ホームページ  >  記事  >  バックエンド開発  >  PHPによる画像データ読み込みの原理と実装

PHPによる画像データ読み込みの原理と実装

WBOY
WBOYオリジナル
2016-06-23 14:19:001547ブラウズ

この投稿は hudie631489527 が 2012-07-21 23:34:34 に最終編集しました

長い間記事を書いていなかったので、手がかゆみ始めています

今回は、についての内容をお届けしますPHP で画像データを抽出します

ここに新しい技術はありません。PHP も画像と処理の原理と方法を処理できることを皆さんに知っていただくためです

データ「特定の文字 + 数字」を読み取るための簡単なデモがここに実装されています画像内の指定された位置に配置します (この例 この画像はサボテンの交通監視画像からのものです)


次の 2 つのステップは別々に実行されます

I 最初に金型操作を実行し、次の手順を実行しましょう:
1.画像の位置を特定するには、領域を特定し、画像からその部分を抽出する必要があります
2.フォントのこの部分を抽出し、将来のマッチングのためにフォント ファイルに記録します (完全なフォントを取得するには、テストに複数の画像が必要です)


II は画像テキストの抽出を実行します。実装手順は次のとおりです:

1.画像を見つけるには、領域を特定し、画像からこの部分を削除する必要があります

2.フォントのこの部分を抽出し、保存されたフォント ファイル内のデータと比較し、このフォントに対応するデータを見つけます


この 2 つのステップは類似点が多いですが、分離する必要があると思います。それらは 2 つの異なるプロセスです

ちょうどシャワーを浴びて考えましたが、最初に 2 番目の部分を紹介し、次に最初の部分を紹介するつもりです。そうすれば、誰もが興味を持って最初に結果を確認できるでしょう。欲望、ははは...


正式にトピックに入ります:

まず、操作する必要があるクラスをリリースし、右下の矢印をクリックしてクラス ファイルを表示します
<?php/*** * @author: Buty(孟婆) *  */class picWords {	private $width;	private $height;	private $zimo_file = 'piczimo.php'; //需要生成的字模文件	private $zimo_info = '';	private $continued; //高峰流量持续的时间	private $warnning_data; //流量报警峰值	private $hourstep; //一小时在时间轴上的长度	function __construct() {		if(!extension_loaded('gd')) { //需要gd扩展的支持			exit('GD extension is supported,please load GD extension and go on.');		}		if(file_exists('config.php')) {			require 'config.php';			$this->continued = $continued;			$this->warnning_data = $warnning_data;			$this->hourstep = $hourstep;		}			}/*****************************************自行创建字模图片与字模数组文件********************************/		function readPicDot($picfile) {		$res = imagecreatefrompng($picfile);		$size = getimagesize($picfile);		$this->width = $size[0];		$this->height = $size[1];		$data = array();				for($j = 0; $j < $this->height; ++$j) {			/*			 * 取需要的数据段 			 * 262,273 day.png			 */						if($j > 262 && $j < 273) {   				for($i=0; $i < $this->width; ++$i) {					if($i > 420) {						$rgb = imagecolorat($res,$i,$j);						$rgbarray = imagecolorsforindex($res, $rgb);						if($rgbarray['red'] < 145 && $rgbarray['green'] < 145 & $rgbarray['blue'] < 145) {							$data[$i][$j]=1;						} else {							$data[$i][$j]=0;						}					}				}							}		}				return $data;	}	function readMaxOutDot($picfile) {		$res = imagecreatefrompng($picfile);		$size = getimagesize($picfile);		$this->width = $size[0];		$this->height = $size[1];		$data = array();				for($j = 0; $j < $this->height; ++$j) {			/*			 * 取需要的数据段 			 * 262,273 day.png			 */						if($j > 262 && $j < 273) {   				for($i=0; $i < $this->width; ++$i) {					if($i < 180 && $i > 90) {						$rgb = imagecolorat($res,$i,$j);						$rgbarray = imagecolorsforindex($res, $rgb);						if($rgbarray['red'] < 145 && $rgbarray['green'] < 145 & $rgbarray['blue'] < 145) {							$data[$i][$j]=1;						} else {							$data[$i][$j]=0;						}					}				}							}		}				return $data;	}				function readHourDot($picfile) {		$res = imagecreatefrompng($picfile);		$size = getimagesize($picfile);		$this->width = $size[0];		$this->height = $size[1];		$data = array();				for($j = 0; $j < $this->height; ++$j) {			/*			 * 取需要的数据段 			 * popup_module_view_hour.png			 * 25, 245 # 35, 480			 * 			 */						if($j > 30 && $j < 242) {   				for($i=0; $i < $this->width; ++$i) {					if($i >66 && $i < 486) {						$rgb = imagecolorat($res,$i,$j);						$rgbarray = imagecolorsforindex($res, $rgb);						if(($rgbarray['red'] < 50 && $rgbarray['green'] > 180 && $rgbarray['blue'] < 50) || ($rgbarray['red'] < 145 && $rgbarray['green'] < 145 & $rgbarray['blue'] < 145)) {							$data[$i][$j]=1;						} else {							$data[$i][$j]=0;						}					}				}							}		}				return $data;	}		function cutData($data) {		$zimo = $tmp = array();		$num = $len = 0;		$count_start = false;		foreach($data as $k => $v) {			if(in_array(1, $v)) {								$zimo[$num][] = $v;				$count_start = true;				$len++;				if($len >= 6) {  //解决字体连在一起					$len = 0;					$num++; //字数加1				}							} else {				$len = 0;				$count_start = false;			}			if(!$count_start) {				$num++;			}		}		//var_dump(array_keys($zimo));				//对于字母T的修复		$res = $this->createZimoArray($zimo);		//$this->debugPic($zimo[35]);		//die();		//打印完整字模点阵		/*		foreach($zimo as $k => $v) {			if($k == 35) {				echo '<hr />';				$this->debugPic($v);			}		}		*/				//var_dump($res);		end($res);//移动数据指针		$last_two_data = prev($res);				if(!strcmp($last_two_data, '0100000000')) { //说明切割T时存在问题			$last_three_data = prev($res);			$last_three_data_real = $last_three_data . $last_two_data; //补充到T字母中			foreach($res as $k => $v) {				if(!strcmp($v, $last_three_data)) {					$res[$k] = $last_three_data_real;				}			}					}		return $res;	}		//构造字模数组	function createZimoArray($data) {		$str = array();		foreach($data as $k => $v) {			$str[$k] = '';			foreach($v as $ks => $vs) {				$str[$k] .= implode('', $vs);			}		}		return $str;	}		//将数据字模读入文件中	function storeZimo($data) {		$str = $this->createZimoArray($data);		$picwords = APP_CACHE_PATH.'picwords.php';		swritefile($picwords, "<?php\r\nreturn ".var_export($str, true)."\r\n?>");	}	//匹配字模数据	function matchZimo($str_arr) {		$need_str = '';		$picwords = $this->zimo_file;		if(empty($this->zimo_info)) {			$this->zimo_info = include_once($picwords);		}		foreach($str_arr as $k => $v) {			foreach($this->zimo_info as $ks => $vs) {				similar_text($v, $vs, $tmp);				if($tmp > 99)					$need_str .= $ks;			}		}		return $need_str;	}		function debugPic($data) {			echo '<div style="width:5850px">';			foreach($data as $k => $v) {				echo '<div style="float:left">';				foreach($v as $ks => $vs) {					echo $vs."<br />";				}				echo '</div>';			}			echo '</div>';	}	function handleHourData($data) {		$data_info = array();		foreach($data as $k => $v) {			$get = true;			$data_info[$k] = 0;			foreach($v as $ks => $vs) {				if($vs == 1 && $get) {					$get = false;				}				if(!$get) {					$data_info[$k]++;									} else {					unset($data[$k][$ks]);				}			}		}		return $data_info;	}/************************************取数据的方法*******************************/	//总流量	function getPicWords($file) {		$need_str = '';		//读取图片点阵信息		$data = $this->readPicDot($file);				//处理切割到的数据,并写入数组		$data = $this->cutData($data);		//匹配字模数据		$need_str = $this->matchZimo($data);		return $need_str;	}	//得到最大流量速度	function getMaxSpeed($file) {		$need_str = '';				//读取图片点阵信息		$data = $this->readMaxOutDot($file);		//处理切割到的数据,并写入数组		$data = $this->cutData($data);		//匹配字模数据		$need_str = $this->matchZimo($data);		return $need_str;	}	//分析小时图中的流量峰值	function parseFlow($file, $info) {		//得到最大流量速度		$maxflow = floatval($this->getMaxSpeed($file));		//读取图片点阵信息		$data = $this->readHourDot($file);		//数据抽象形变		$data_info = $this->handleHourData($data);				$max = max($data_info);				$radio = (float) ($maxflow / $max); //流量计算比列				$timeradio = ceil($this->hourstep / 60);//每分钟格数				$continued_time = $this->continued * $timeradio;//持续时间用点阵长度量化				$count = 0;		foreach($data_info as $v) {			if($v * $radio > $this->warnning_data) {				$count++;				if($count >= $continued_time) {					echo "ServerID: $info[sid] IP: $info[ip] flow over: ".$this->warnning_data.'<br />'; //发邮件					break;				}			} else {				$count = 0;			}		}	}	}?>


1.テキスト抽出関数の紹介

操作が必要な画像、下の赤い部分が抽出する必要があるテキストです

コード処理後、次の画像が得られます
<?php$picWord = new picWords();$picfile = 'popup_module_view.png';//图片路径$data = $picWord->readPicDot($picfile);//读取图片点阵信息?>



この画像は集合で表されますこの図の文字列は誰でもわかると思います


この時点で操作対象の範囲が狭まりましたが、すぐに問題となるのは、文字の数と文字をどうやって取得するかということです。写真にある

この問題も最も難しいです。ここでカットを開始します

コード処理後、次の図が得られます:
<?php$data = $picWord->cutData($data);//处理切割到的数据,并写入数组?>



各ブロックは文字に対応します (現時点では実際の文字ではありません) 、これは単なる未知のデータであり、私たちが変換するのを待っています)

注意深い友人なら、データの 2 番目と 3 番目のブロックが実際には T で表されていることに気づいたはずです。後続のコードにはこれに対する別の処理があります

教えてくださいここで説明します。なぜなら、1 文字あたり 6 ピクセル、高さ 10 ピクセルずつ画像を拡大したからです。なぜこれら 2 つの数値を使用して計算する必要があるのか​​と疑問に思った人もいるでしょう。これらは、この図のテキストの観察に基づいていると言いたいので、5 と 7 は適切ではないので、幅として 6 を選択しました。高さは 10
rree

次に、配列を保存します。これらの文字列を「10101010...」という文字列に変換し、フォント ファイルと照合して (ここでは最初に使用します。後で紹介します)、必要なデータを取得します



2.フォントの生成

フォントを生成するプロセスは、最後に文字を保存する配列内の文字列と対応する文字を手動で識別して記録する必要があることを除いて、上記と同じです。このステップは上記のステップより前に完了する必要があります。上記 一致するフォント ファイルがありません。

おそらく学生は、これは依然として知的ではなく手動で識別する必要があると言いたいでしょう。ただし、既製のフォント ファイルはないため、手動で生成する必要があります。そのクラスメイトがフォントやフォントを勉強していて、画像内のテキストにどのフォントが使用されているかが一目でわかり、このフォントファイルも持っている場合、手動で生成する必要はなく、それを借りて使用するだけです


さて、今日の記事はここまでです。ファイル内の固定テキストを取得します。
興味のある学生は、クリックしてデモをダウンロードしてください。画像ファイルを解凍して、pick_pic_data.php を実行します。もこのファイル内で任意に指定可能です

次回は波形からある一定値を超えた状況を検出し、対応する方法を紹介します


ディスカッションへの返信(解決策)

ありがとうございました共有するため。 。 。 。 。 。

共有してくれてありがとう。

共有してくれてありがとう、たくさんのことを学びました。 。 。 。

こんにちは、質問があります。 piczimo.php ファイル内の 0 ~ 9 はどのようにして次のパターンに変換されます。

'0' => '0011111100011000011001000000100100100010011000011111100'、

'1' => '010000001001000000100111111 1 000000000100000000010'、

a-z A-Z はどうでしょうか?アドバイスありがとうございます。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。