OpenCV tutorial 解析2 〜ヒストグラム計算〜

イントロダクション

前回は、チュートリアルにあるコード(Git)を起動して、そのプログラムの内容について解析しました。

実際にはチュートリアルの「Calculate a Histogramのところにたどり着いた状態です。

ヒストグラムとは

ヒストグラムは、事前に定義されたビンのセットにまとめられたデータの収集数です。私たちの場合、データはピクセルの強度を表しているので、(0、256)のような範囲になります

チュートリアルには記載があるのですが、理解したのは色のデータ(0-256)を持っていることくらいです。

やっぱりコードから。。。

いつも通りコードから理解していきます。「なんやらわからんが、ヒストグラムを表示している(下のように)

この赤、緑、青のグラフ?が表示されているのはどうやらRGBの度合いが表示されているくさい(チュートリアルの文言から推測)

じゃ、コードで見て見ましょう。

ヒストグラムの表示領域

ImageView fx:id="histogram"

VideoControllerにある、ImageViewクラスの変数名が「histogram」を探す。。。

/** FXML ヒストグラム -> fx:id="histogram" */
@FXML
private ImageView histogram;

ありました、そしてこいつは、「showHistogram()」で処理しているようなのでこのメソッドを追いかけます。

// set the number of bins at 256
MatOfInt histSize = new MatOfInt(256);
// only one channel
MatOfInt channels = new MatOfInt(0);
// set the ranges
MatOfFloat histRange = new MatOfFloat(0, 256);

この部分で3つに分けているようです。

Imgproc.calcHist(images.subList(0, 1), channels, new Mat(), hist_b, histSize, histRange, false);

Core.calcHist()メソッドで細かい計算をしてくれるようです。

	// effectively draw the histogram(s)
	for (int i = 1; i < histSize.get(0, 0)[0]; i++)
	{
		// B component or gray image
		Imgproc.line(histImage, new Point(bin_w * (i - 1), hist_h - Math.round(hist_b.get(i - 1, 0)[0])),
				new Point(bin_w * (i), hist_h - Math.round(hist_b.get(i, 0)[0])), new Scalar(255, 0, 0), 2, 8, 0);
		// G and R components (if the image is not in gray scale)
		if (!gray)
		{
			Imgproc.line(histImage, new Point(bin_w * (i - 1), hist_h - Math.round(hist_g.get(i - 1, 0)[0])),
					new Point(bin_w * (i), hist_h - Math.round(hist_g.get(i, 0)[0])), new Scalar(0, 255, 0), 2, 8,
					0);
			Imgproc.line(histImage, new Point(bin_w * (i - 1), hist_h - Math.round(hist_r.get(i - 1, 0)[0])),
					new Point(bin_w * (i), hist_h - Math.round(hist_r.get(i, 0)[0])), new Scalar(0, 0, 255), 2, 8,
					0);
		}
	}
	
	// display the histogram...
	Image histImg = Utils.mat2Image(histImage);
	updateImageView(histogram, histImg);
	
}

こんな風にプログラムを起動しているようです。

わかったこと

  1. ROI(Rectクラス)でイメージの中に領域を作る
  2. Coreクラスの「calcHist()」「normalize()」「addWeighted()」などで色データの扱いができる

感想

単純にカメラからのデータをいじったり、成分解析したりできるのは魅力的だ!

ここで作成したアプリをラズパイなどに乗っけても面白そうだ。

続きは次回

でわでわ。。。