ホームページ  >  記事  >  Java  >  Java画像の二値化と大津閾値法

Java画像の二値化と大津閾値法

黄舟
黄舟オリジナル
2016-12-30 11:53:542755ブラウズ

この記事では主に画像の二値化、つまりグレースケールに基づく閾値分割に焦点を当てます。実際、二値化にはさまざまな方法があり、画像処理中にターゲット領域を完全に分割できれば、成功の半分以上が得られることから、二値化の重要性がわかります。この記事では主に3つの二値化方法を紹介します。

1. しきい値を固定する方法。しきい値を設定し、しきい値より大きいピクセルを 255 に設定します。それ以外の場合は 0 です。これが最も単純ですが、効果は最も不安定です。

<span style="font-size:14px;"><span style="font-size:10px;">public void SimBinary(){
		toGray();//灰度化
		int Threshold = 128;
		for (int y = 0; y < h; y++) {
                   for (int x = 0; x < w; x++) {
            	      if(data[x + y * w] < Threshold){
            		 data[x + y * w] = 0;

            	      }else{
            		data[x + y * w] = 255;
            	      }
                  }
	       }
					
	}</span></span>

その動作効果は次のとおりです:

Java画像の二値化と大津閾値法

Java画像の二値化と大津閾値法

2. ループ方法 (参考: 画像処理の一般的な 2 値化方法の概要)

1. 初期化しきい値 T。ランダムな方法で生成されます。

2. 閾値マップに従って、各ピクセルデータ P(n,m) がオブジェクトピクセルデータ G1 と背景ピクセルデータ G2 に分割されます。 (n は

行、m は列)

3。G1 の平均値は m1、G2 の平均値は m2

4 です。新しいしきい値 T' = (m1 + m2)/2。

5. 2 番目のステップに戻り、新しいしきい値を使用してピクセル データをオブジェクトと北京ピクセル データに分割し続けます。計算された新しいしきい値が最後のしきい値と等しくなるまで、ステップ 2 ~ 4 を続けます。

コードは次のとおりです:

<span style="font-size:14px;">	public void IterBinary(){
		toGray();
		
		int Threshold = 128;
		int preThreshold = 256;
		
		while (Math.abs(Threshold-preThreshold) > 4){
			int s1 = 0;
			int s2 = 0;
			int f1 = 0;
			int f2 = 0;
			
			for (int y = 0; y < h; y++) {
	                  for (int x = 0; x < w; x++) {
	            	    if(data[x + y * w] < Threshold){
	            		s1 += data[x + y * w];
	            		f1++;
	            	      }else{
	            		s2 += data[x + y * w];
	            		f2++;
	            	      }
	                 }
		       }
			
			preThreshold = Threshold;
			Threshold = (int)((s1/f1+s2/f2)/2);
		 }
		
		for (int y = 0; y < h; y++) {
                   for (int x = 0; x < w; x++) {
            	     if(data[x + y * w] < Threshold){
            		data[x + y * w] = 0;

            	     }else{
            		data[x + y * w] = 255;
            	     }
                  }
	       }
					
	}</span>

効果は次のとおりです:

Java画像の二値化と大津閾値法3. Otsu 閾値法 (参考: 適応閾値アルゴリズム (Otsu 閾値法))

最大クラス間分散法が提案されました。 1979 年に日本の学者、大津氏によって作成されました。これは適応閾値決定方法であり、大津法または略して OTSU とも呼ばれます。画像のグレースケール特性に従って、画像を背景とターゲットの 2 つの部分に分割します。背景とターゲットの間のクラス間の分散が大きいほど、ターゲットの一部が誤って背景として分類された場合、または背景の一部が誤ってターゲットとして分類された場合、画像を構成する 2 つの部分間の差異が大きくなります。 2つの部分の差は小さくなります。したがって、クラス間の分散を最大化するセグメンテーションは、誤分類の確率が最小になることを意味します。画像 I (x, y) の場合、前景 (つまり、ターゲット) と背景のセグメンテーションしきい値は T で示され、画像全体に対する前景に属するピクセル点の割合は ω0 で示され、その平均グレー レベルは次のようになります。 μ0; 画像全体の背景ピクセル ポイントの数を示します。画像のスケールは ω1、その平均グレー レベルは μ1 です。画像全体の平均

グレー レベルは μ で示され、クラス間の分散は g で示されます。画像の背景が暗く、画像のサイズが M×N であると仮定します。画像内のグレー値がしきい値 T 未満のピクセルの数は N0 として記録され、グレー値が閾値 T 未満のピクセルの数は N0 として記録されます。閾値Tより大きい値をN1として記録すると、

ω0=N0/ M×N (1)

ω1=N1/ M×N (2)

N0+N1=M×N (3)

ω0+ω1=1 (4)

μ =ω0*μ0+ω1*μ1 (5)

g=ω0(μ0-μ)^2+ω1(μ1-μ)^2 (6)

式 (5) を式 (6) に代入すると、価数式と等しくなります:

g=ω0ω1(μ0-μ1)^2 (7)

トラバーサル法を使用して、クラス間の分散を最大化するしきい値 T を取得します。 、これが必要なものです。

コードは次のとおりです:

<span style="font-size:14px;">public void Otsu(){
		toGray();
		int num = h*w;
		int[] hist = hist();
		int sum = math.sum(hist);
		double[] res = new double[256];
		double m1=0,m2=0,w1=0,w2=0;
		
		for(int k=0;k<256;k++){
			for(int i=0;i<k;i++){
				m1 +=hist[i];
			}
			w1 = m1/num;
			w2 = 1-w1;
			m2 = (sum-m1)/(255-k);
			m1 = m1/(k+1);
			res[k] = w1*w2*Math.abs(m1 - m2)*Math.abs(m1 - m2);
		}
		
		int Threshold = math.maxIndex(res); //获得最大值的下标
		
		for (int y = 0; y < h; y++) {
                  for (int x = 0; x < w; x++) {
            	    if(data[x + y * w] < Threshold){
            		data[x + y * w] = 0;

            	    }else{
            		data[x + y * w] = 255;
            	    }
                }
		}
	}</span>

実行時の効果は次のとおりです:

Java画像の二値化と大津閾値法 上記は、Java イメージの 2 値化と Otsu 閾値メソッドの内容です。さらに関連する内容については、 に注目してください。 PHP 中国語 Web サイト (www.php.cn)!


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