OpenCV 4学習ノート(20)——二値分割


今回の整理記録の内容は画像の二値化に関する知識があり、画像の二値化は非常に重要な前処理手段であり、このステップで得られた二値画像は後続の画像処理過程に非常に大きな影響を及ぼす.高品質の2値画像が得られると、後続の処理もより簡便になる.
-グローバルしきい値分割
画像を二値化するには、まず画像を階調画像に変換し、次に二値分割のための閾値を設定し、階調画像の各画素点を遍歴し、その画素点の階調値が閾値より大きい場合、その画素点を255の階調値に設定し、その画素点の階調値が閾値より小さい場合、その画素点を0の階調値に設定する必要がある.これにより、最も簡単な画像の二値化が実現され、コード実装が以下に示される.
Mat image_gray;
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	Scalar m = mean(image_gray);			//mean(Mat())         Scalar  
	int threshold = m[0];			//                   
	int height = image.rows;
	int width = image.cols;
	Mat binary = Mat::zeros(image.size(), CV_8UC1);
	for (int row = 0; row < height; row++)
	{
     
		for (int col = 0; col < width; col++)
		{
     
			uchar  gray = image_gray.at<uchar>(row, col);
			if (gray > threshold)
			{
     
				binary.at<uchar>(row, col) = 255;
			}
		}
	}
	imshow("binary", binary);

上記コードでは、1枚の階調画像の画素平均値をmean(image_gray)関数で取得し、mean(Mat())関数の戻り値がScalarオブジェクトであることに注意し、その平均値を2値分割の閾値として画素点遍歴して2値画像を求める.実際には、OpenCVに関連するいくつかのAPIを使用することができ、画像の二値化を行うために画素点を苦労する必要はありません.関連コードは次のとおりです.

	Mat image_gray, binary_image, binary_color_image, binary_image_OTSU, binary_image_TRIANGLE;
	cvtColor(image, image_gray, COLOR_BGR2GRAY);
	threshold(image_gray, binary_image, 127, 255, THRESH_BINARY);		//        255,       0
	//threshold(image_gray, binary_image, 127, 255, THRESH_BINARY_INV);		//        0,       255
	//threshold(image_gray, binary_image, 127, 255, THRESH_TOZERO);		//        0,       
	//threshold(image_gray, binary_image, 127, 255, THRESH_TOZERO_INV);	//        0,       
	//threshold(image_gray, binary_image, 127, 255, THRESH_TRUNC);		//           ,       


	double thresh = threshold(image_gray, binary_image_OTSU, 0, 255, THRESH_BINARY | THRESH_OTSU);			//      ,  thresh  ;    8     
	//double thresh = threshold(image_gray, binary_image_TRIANGLE, 0, 255, THRESH_BINARY_INV | THRESH_TRIANGLE);			//      ,  thresh  ;    8     

	imshow("binary_image", binary_image);
	imshow("binary_image_OTSU", binary_image_OTSU);
	//imshow("binary_image_OTSU", binary_image_TRIANGLE);
	//imshow("binary_color_image", binary_color_image);

このうちthreshold()関数は主要なAPIであり、以下、そのパラメータについて紹介する:第1のパラメータsrc:画像の二値化を行う必要がある入力画像は、単一チャネルの階調図でも三チャネルのカラー図でもよいが、一般的に階調画像を用いて二値分割を行う.第2のパラメータdst:出力された2値画像;3番目のパラメータthresh:入力した分割しきい値は、自動的に計算できます.4番目のパラメータmaxvalue:入力画像の最大画素値は、一般的に255です.5番目のパラメータtype:以下の7つの一般的な方法の選択があり、最初の5つは自分でパラメータthreshを設定する必要があります.1、THRESH_BINARY:閾値より大きいものを255、閾値より小さいものを0 2、THRESH_BINARY_INV:閾値より大きいものを0、閾値より小さいものを255、THRESH_とするTOZERO:閾値より小さいものを0とし、閾値より大きいものを保持4、THRESH_TOZERO_INV:閾値より大きいものを0とし、閾値より小さいものを保持5、THRESH_TRUNC:閾値より大きいものを閾値とし、閾値より小さいものを保持6、THRESH_OTSU:しきい値を自動的に計算し、パラメータthreshが無効です.8ビット単一チャネル図にのみ適用される.二重ピークヒストグラムを有する画像の二値分割7、THRESH_に適用TRIANGLE:閾値を自動的に計算し、パラメータthreshが無効である;8ビット単一チャネル図にのみ適用される.単一ピークヒストグラムを有する画像の二値分割に適しており、第6、7種のTHRESH_OTSUとTHRESH_TRIANGLEは,画像ヒストグラムに基づいて自動グローバルしきい値探索を実現し,二値分割を行うことができるが,階調画像にのみ適用できる.
2つの自動グローバルしきい値探索アルゴリズムの大まかな原理は,OTSUアルゴリズム:ヒストグラムの異なる区間を分類し,最大クラス間分散をしきい値として計算することである.ヒストグラムには2つのピークがあり、中間に明らかな谷があるヒストグラムの対応画像の二値化効果は比較的良く、1つの単一ピークしかないヒストグラムには対応する画像分割効果は比較的悪い.TRIANGLEアルゴリズム:ヒストグラムの単一ピークを三角形に近似し、頂点を探して垂線の底部の点を作り、その点を三角形の辺に垂線を作り、垂線と三角形の辺の交点に対応する画素値が閾値となる.ヒストグラムに対して単一ピークのみの対応画像の二値化効果がよい.
自動グローバルしきい値探索アルゴリズムを使用すると、threshold()関数の戻り値によって自動計算のしきい値を取得することができ、もちろん、その戻り値を取得する設定をしなくてもよい.
threshold(image_gray, binary_image_OTSU, 0, 255, THRESH_BINARY | THRESH_OTSU)

また,自動グローバルしきい値探索アルゴリズムを用いる場合,THRESH_BINARY | THRESH_OTSUという書き方が一般的であり,しきい値分割方式を人為的に指定することができ,より理想的な結果を分割するのに便利である.
−局所適応しきい値分割に用いたthreshold()方式は、いずれもグローバルしきい値に基づいて分割されており、1枚の画像に画素分布ムラ、光照射分布ムラ等があると、比較的良い効果が得られにくい.特にOCR認識を行う場合、撮影されたテキスト画像に光のムラが生じることが多く、この場合はグローバルしきい値分割を用いると効果が劣る.したがって、OpenCVは、同様の問題を解決するために適応しきい値分割APIを提供する.局所適応しきい値分割は、実際には、各画素の近傍ブロックの画素値分布に基づいてその画素位置における二値化しきい値を決定するため、多くの局所しきい値が形成され、画像中の異なる領域では異なる局所しきい値に基づいて二値分割が行われる.OpenCVにおける適応しきい値の算出方法は、まず画像の平均値(ガウスぼかし平均値とボックスぼかし平均値の2つに分ける方法)を求め、元の画像から平均値画像を減算して得られた差分値から所定値を減算し、最終結果が0より大きいか否かを判断し、対応するしきい値分割を行う.その中のガウスぼかし平均値は、入力画像をガウスぼかした後にその平均値を求めるものである.一方,ボックスブラー平均値は,入力画像を平均ブラーして平均値を求める.コードのデモは次のとおりです.
	Mat gray_image, adaptive_binary_image_gauss, adaptive_binary_image_mean;
	cvtColor(image, gray_image, COLOR_BGR2GRAY);
	adaptiveThreshold(gray_image, adaptive_binary_image_gauss, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 25, 10);	
	adaptiveThreshold(gray_image, adaptive_binary_image_mean, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 25, 10);
	
	imshow("adaptive_binary_image_gauss", adaptive_binary_image_gauss);
	imshow("adaptive_binary_image_mean", adaptive_binary_image_mean);

ここで、主なAPIはadaptiveThreshold()であり、以下、そのパラメータを紹介する:第1のパラメータsrc:2値分割が必要な入力画像;2番目のパラメータ:出力された2値画像;3番目のパラメータmaxValue:最大階調値、一般的に255;4番目のパラメータadaptiveMethod:ガウスブラー平均かボックスブラー平均かを選択します.それぞれADAPTIVE_THRESH_GAUSSIAN_CADAPTIVE_THRESH_MEAN_Cです.5番目のパラメータthresholdType:使用するしきい値分割方式は、THRESH_しか入力できません.BINARYまたはTHRESH_BINARY_INVは、他のしきい値分割方式を使用するとエラーを報告する.2値分割後、黒い背景、白い前景が必要であり、目標が背景または前景であることに基づいてこのパラメータを選択する.THRESH_BINARY:二値画像=原図-平均画像-C>0?255 : 0 THRESH_BINARY_INV:二値画像=原図–平均画像-C>0?0:255 6番目のパラメータblockSize:ぼかし時のウィンドウサイズは、奇数パラメータC:原図と平均画像との差から減算された所定値でなければならず、負の値とすることができる.経験値は10~25.適応しきい値分割効果は,グローバルしきい値に比べて局所適応しきい値の二値化効果が相対的に良好であることがわかる.
二値分割は多くの画像処理操作の基礎であり、例えば二値分析は欠陥検出に用いる:入力画像を二値化し、形態学的操作によって干渉を除去し、輪郭発見と輪郭分析を行い、さらに輪郭を並べ替え、微細な欠陥を拡大し、テンプレートと比較することができる(例えば、減算、減算後ゼロでない領域は欠陥である).最後に検出結果を出力します.これは、画像処理における二値分割の重要な地位を示す特定の応用にすぎない.
実は画像の二値化の操作、いくつかの主要な方式があって、以下に1つの総括をします:(1)グローバルしきい値の二値化:threshold()というAPIを通じてグローバルにしきい値化を実現して、自動的にしきい値を設定することができて、画像が単一のピークのヒストグラムあるいは2つのピークのヒストグラムであることによって自動的にしきい値を計算することができます;(2)モルフォロジー勾配二値化に基づく:morphologyEx()によるMORPH_GRADIENTは画像に対して基本勾配を求め、階調図に変換してグローバルしきい値分割を行う.(3)inRange二値化:異なる色のH(色調)とS(飽和度)の異なる範囲で異なる色を選択し、画像中のある領域が選択されているかどうかによって画像の二値化を行う.(4)Cannyエッジ二値化に基づく:画像を直接canny演算子エッジ検出操作を行い、一部のノイズ(内部にガウスブラーを施した)を除去し、エッジを強化するとともに、エッジの二値画像を出力し、エッジ操作が必要な画像、例えば輪郭発見などに適用する.(5)適応二値化:adaptiveThreshold()というAPIにより画像の局所適応二値分割が実現され、光照射が不均一な画像、特にOCR認識が必要なテキスト画像に適しており、通常のグローバルしきい値分割よりも比較的良好な分割効果がある.
今回は主にグローバルしきい値の二値化と局所適応の二値化を記録し、その後、他の二値化操作を一つ一つ整理する機会があれば、これで終わりです.ありがとうございます.
PS:私のコメントは雑で、自分の心得もあれば、ネット上で资料を调べる时に抜粋した知识の内容もあります.だから、同じように、私が先辈に勉强した敬意です.もし先辈が私のノートの内容があなたの知的财产権を侵害していると思ったら、私に连络してください.私は関连する博文の内容を削除します.ありがとうございます.