zoukankan      html  css  js  c++  java
  • PHP实现 序列帧拆分

    示例图片

    思路:读取图片,二值化(阈值,这里用的是alpha),获取边界,分块,过滤小块(环形)

    代码实现

      1 <?php
      2 ini_set ( 'memory_limit', '5999M' );
      3 include('./picconfig.php');
      4 $time1 = time();
      5 $ImagePath = './test.png';
      6 $res = imageCreateFromAny($ImagePath);
      7 $size = getimagesize($ImagePath);
      8 
      9 $pictype = substr($ImagePath, strrpos($ImagePath, '.'));
     10 
     11 //获取图片像素点,并alpha二值化生成数组,原始数据
     12 $data = array();
     13 for($i=0; $i < $size[1]; ++$i)
     14 {
     15     for($j=0; $j < $size[0]; ++$j)
     16     {
     17         $rgb = imagecolorat($res,$j,$i);
     18         $rgbarray = imagecolorsforindex($res, $rgb);
     19         if($rgbarray['alpha'] < 125)
     20         {
     21             $data[$i.'_'.$j]=1;
     22         }else{
     23             $data[$i.'_'.$j]=0;
     24         }
     25     }
     26 }
     27 //消融掉内部点生成边界数组
     28 $theborderlist = (object)[];
     29 $bordersArr = [];
     30 foreach ($data as $now => $ttt) {
     31     if ($ttt == 1) {
     32         $tmpnow = explode('_', $now);
     33         $s = $tmpnow[0];
     34         $t = $tmpnow[1];
     35         $nowlist = getlist($s, $t, 1);
     36         $tmpbor = getborder($nowlist, $data);
     37         if ($tmpbor) {
     38             if (!in_array($now, $bordersArr)) {
     39                 $bordersArr[] = $now;
     40                 $theborderlist->$now = $nowlist;
     41             }
     42         }
     43     }
     44 }
     45 
     46 //路径数组,记录所有走过的点
     47 $allarr = [];
     48 
     49 //临时块数组,记录一个块内的所有数据
     50 $tmparr = [];
     51 
     52 //结果数组
     53 $resdata = [];
     54 
     55 
     56 //分块,获取结果
     57 saolei($bordersArr);
     58 
     59 $fenkuaiArr = [];
     60 foreach ($resdata as $pickey => $resinfo) {
     61     $x_arr = [];
     62     $y_arr = [];
     63     foreach ($resinfo as $tmpval) {
     64         $tmpvalArr = explode('_', $tmpval);
     65         $y_arr[] = $tmpvalArr[0];
     66         $x_arr[] = $tmpvalArr[1];
     67     }
     68     $min_x = min($x_arr);
     69     $min_y = min($y_arr);
     70     $max_x = max($x_arr);
     71     $max_y = max($y_arr);
     72     if ($max_x > $min_x && $max_y > $min_y ) {
     73         $fenkuaiArr[] = [$min_x,$min_y,$max_x,$max_y];
     74     }
     75 }
     76 
     77 //过滤掉小块
     78 $bigkuai = [];
     79 foreach ($fenkuaiArr as $kuailist) {
     80     $bigflag = getbigkuai($kuailist, $fenkuaiArr);
     81     if ($bigflag) {
     82         $bigkuai[] = $kuailist;
     83     }
     84 }
     85 
     86 //分块截图
     87 if ($bigkuai) {
     88     foreach ($bigkuai as $bigk => $bigli) {
     89         $new_width = $bigli[2]-$bigli[0];
     90         $new_height = $bigli[3]-$bigli[1];
     91         if ($new_width > 0 && $new_height > 0 ) {
     92             $tmpimg = imageCreateFromAny($ImagePath);
     93             $image_p = imagecreatetruecolor($new_width, $new_height);
     94             imagecopyresampled($image_p, $tmpimg, 0, 0, $bigli[0], $bigli[1], $new_width, $new_height, $new_width, $new_height);
     95             $savename = './testpic/tmp'.$bigk.$pictype;
     96             // 输出
     97             imagejpeg($image_p, $savename);
     98             imagedestroy($image_p);
     99             imagedestroy($tmpimg);
    100         }
    101     }
    102 }
    103 
    104 $time2 = time();
    105 echo $time2-$time1;
    106 
    107 
    108 //核心方法,图片分块
    109 function saolei($bordersArr, $thefirst = [], $num = 0)
    110 {
    111     global $allarr;
    112     global $tmparr;
    113     global $resdata;
    114     global $theborderlist;
    115     if (!$thefirst) {
    116         if (!$tmparr) {
    117             $tttarr = array_diff($bordersArr, $allarr);
    118             if (!$tttarr) {
    119                 return;
    120             }
    121             $thefirst = [$tttarr[array_keys($tttarr)[0]]];
    122             $tmparr[] = $thefirst[0];
    123         }
    124     }
    125     $tttdata = [];
    126     foreach ($thefirst as $thepoint) {
    127         if (!in_array($thepoint, $allarr)) {
    128             $alllist = ($theborderlist->$thepoint)?$theborderlist->$thepoint:[];
    129             $choselist = getnext($alllist, $bordersArr);
    130             $allarr[] = $thepoint;
    131             $tmparr = array_merge($tmparr, array_diff($choselist, $tmparr));
    132             $tttdata = array_merge($tttdata, array_diff($choselist, $tttdata));
    133         }
    134     }
    135 
    136     if (!$tttdata) {
    137         $resdata[] = $tmparr;
    138         $tmparr = [];
    139         //调到下一个块
    140         saolei($bordersArr);
    141     } else {
    142         var_dump(count($resdata).'_'.$num);
    143         saolei($bordersArr, $tttdata, $num+1);
    144     }
    145 }
    146 
    147 //获取临点数组(9宫格)
    148 function getlist($a, $b, $num=1)
    149 {
    150     $widarr = range($a-$num, $a+$num);
    151     $hiharr = range($b-$num, $b+$num);
    152     $resArr = [];
    153     foreach ($widarr as $wid) {
    154         if ($wid >= 0) {
    155             foreach ($hiharr as $hih) {
    156                 if ($hih >= 0) {
    157                     $resArr[] = $wid."_".$hih;
    158                 }
    159             }
    160         }
    161     }
    162     return $resArr;
    163 }
    164 
    165 //读取图片
    166 function imageCreateFromAny($filepath) 
    167 { 
    168     $type = exif_imagetype($filepath);
    169     $allowedTypes = array( 
    170         1,  // [] gif 
    171         2,  // [] jpg 
    172         3,  // [] png 
    173         6   // [] bmp 
    174     ); 
    175     if (!in_array($type, $allowedTypes)) { 
    176         return false; 
    177     } 
    178     switch ($type) { 
    179         case 1 : 
    180             $im = imageCreateFromGif($filepath); 
    181         break; 
    182         case 2 : 
    183             $im = imageCreateFromJpeg($filepath); 
    184         break; 
    185         case 3 : 
    186             $im = imageCreateFromPng($filepath); 
    187         break; 
    188         case 6 : 
    189             $im = imageCreateFromBmp($filepath); 
    190         break; 
    191     }    
    192     return $im;  
    193 }
    194 
    195 //边界判断
    196 function getborder($list, $data)
    197 {
    198     $tmpborders = [];
    199     foreach ($list as $thev) {
    200         if ($data[$thev] == 1) {
    201             $tmpborders[] = $thev;
    202         }
    203     }
    204     if (count($tmpborders) < 9) {
    205         return true;
    206     } else {
    207         return false;
    208     }
    209 }
    210 
    211 //获取相邻的边界点
    212 function getnext($list, $data)
    213 {
    214     global $allarr;
    215     $tmpborders = [];
    216     foreach ($list as $thev) {
    217         if (in_array($thev, $data) && !in_array($thev, $allarr)) {
    218             $tmpborders[] = $thev;
    219         }
    220     }
    221     if (count($tmpborders) > 1) {
    222         return $tmpborders;
    223     } else {
    224         return [];
    225     }
    226 }
    227 
    228 //判断是否是大块(如果是小块,会有在大块内部)
    229 function getbigkuai($thelist, $alllist)
    230 {
    231     $flag = true;
    232     foreach ($alllist as $nextlist) {
    233         if ($thelist!=$nextlist) {
    234             if ($thelist[0]>=$nextlist[0] && $thelist[1]>=$nextlist[1] && $thelist[2]<=$nextlist[2] && $thelist[3]<=$nextlist[3]) {
    235                 $flag = false;
    236             }
    237         }
    238     }
    239     return $flag;
    240 }

    这个实现目前只能处理一些简单的序列帧,复杂的耗时太长,效率不高

  • 相关阅读:
    支付宝及时到帐接口使用详解
    Linux 天翼3G上网
    VBS常用函数及功能
    mencoder和ffmpeg参数详解
    C# 将数据导出到Excel汇总
    C# WinForm开发系列 Excel
    C#中的String.Format方法
    Google Maps API 代码
    ffmpeg的使用
    C# WinForm开发系列 Crystal Report
  • 原文地址:https://www.cnblogs.com/jwcrxs/p/10446001.html
Copyright © 2011-2022 走看看