首页 > Web开发 > 详细

PHP实现 序列帧拆分

时间:2019-02-27 19:37:01      阅读:162      评论:0      收藏:0      [点我收藏+]

示例图片

技术分享图片

 

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

 

代码实现

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

 

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

 

PHP实现 序列帧拆分

原文:https://www.cnblogs.com/jwcrxs/p/10446001.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!