画像の二値化
C
#include <cv.h> #include <highgui.h> int main(int argc, char **argv) { IplImage *src_img=0, *gray_img; IplImage *bin_img, *bininv_img, *trunc_img, *tozero_img, *tozeroinv_img; IplImage *adaptive_img; char *imagename; // (1)load a specified file and convert it into grayscale image. // allocate destination images. imagename = argc > 1 ? argv[1] : "../image/trains.png"; src_img = cvLoadImage(imagename, CV_LOAD_IMAGE_COLOR); if(src_img == 0) return -1; gray_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); cvCvtColor(src_img, gray_img, CV_BGR2GRAY); bin_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); bininv_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); trunc_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); tozero_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); tozeroinv_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); adaptive_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); // (2)apply a fixed-level threshold to each pixel cvThreshold(gray_img, bin_img, 0, 255, CV_THRESH_BINARY|CV_THRESH_OTSU); cvThreshold(gray_img, bininv_img, 0, 255, CV_THRESH_BINARY_INV|CV_THRESH_OTSU); cvThreshold(gray_img, trunc_img, 0, 255, CV_THRESH_TRUNC|CV_THRESH_OTSU); cvThreshold(gray_img, tozero_img, 0, 255, CV_THRESH_TOZERO|CV_THRESH_OTSU); cvThreshold(gray_img, tozeroinv_img, 0, 255, CV_THRESH_TOZERO_INV|CV_THRESH_OTSU); // (3)apply an adaptive threshold to a grayscale image cvAdaptiveThreshold(gray_img, adaptive_img, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, 8); // (4)show source and destination images cvNamedWindow("Source", CV_WINDOW_AUTOSIZE); cvNamedWindow("Binary", CV_WINDOW_AUTOSIZE); cvNamedWindow("Binary Inv", CV_WINDOW_AUTOSIZE); cvNamedWindow("Trunc", CV_WINDOW_AUTOSIZE); cvNamedWindow("ToZero", CV_WINDOW_AUTOSIZE); cvNamedWindow("ToZero Inv", CV_WINDOW_AUTOSIZE); cvNamedWindow("Adaptive", CV_WINDOW_AUTOSIZE); cvShowImage("Source", src_img); cvShowImage("Binary", bin_img); cvShowImage("Binary Inv", bininv_img); cvShowImage("Trunc", trunc_img); cvShowImage("ToZero", tozero_img); cvShowImage("ToZero Inv", tozeroinv_img); cvShowImage("Adaptive", adaptive_img); cvWaitKey (0); cvDestroyWindow("Source"); cvDestroyWindow("Binary"); cvDestroyWindow("Binary Inv"); cvDestroyWindow("Trunc"); cvDestroyWindow("ToZero"); cvDestroyWindow("ToZero Inv"); cvDestroyWindow("Adaptive"); cvReleaseImage(&src_img); cvReleaseImage(&gray_img); cvReleaseImage(&bin_img); cvReleaseImage(&bininv_img); cvReleaseImage(&trunc_img); cvReleaseImage(&tozero_img); cvReleaseImage(&tozeroinv_img); cvReleaseImage(&adaptive_img); return 0; }
// (1)指定ファイルをカラー画像として読み込み,それをグレースケールに変換します.
指定されたファイルを3チャンネルのカラー画像として読み込み,関数 cvCvtColor を用いてグレースケールに変換します.また,さまざまな閾値処理後の画像を格納する領域を確保します.これらは,入力画像と同じサイズで,ビット深度8,チャンネル1の画像領域になります.
// (2)画像に対し,さまざまな固定閾値処理を行います.
関数 cvThreshold を用いて,入力画像から作成されたグレースケール画像に対して,以下のような固定閾値処理を行います.
- CV_THRESH_BINARY : 閾値を超えるピクセルは maxVal に,それ以外のピクセルは 0 になります.
- CV_THRESH_BINARY_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは maxVal になります.
- CV_THRESH_TRUNC : 閾値を超えるピクセルは threshold に,それ以外のピクセルは変更されません.
- CV_THRESH_TOZERO : 閾値を超えるピクセルは変更されず,それ以外のピクセルは 0 になります.
- CV_THRESH_TOZERO_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは変更されません.
また,このサンプルでは,全ての手法に対して CV_THRESH_OTSU を指定することで,大津の手法を用いて自動的に閾値を決定します.もちろん,これを行わずに自分で閾値を決定することも可能です.
// (3)画像に対し,適応的な閾値処理を行います.
関数 cvAdaptiveThreshold
を用いて,入力画像から作成されたグレースケール画像に対して,適応的な閾値処理を行います.閾値が適応的に決定されるので,対象ピクセルは,画像全体ではなく,その近傍領域に対して明暗を決定されます.
ここでは第4引数で CV_ADAPTIVE_THRESH_GAUSSIAN_C を指定しているので,blockSize(第6引数)x blockSize
の近傍領域に対してガウシアンを重みとして総和をとり,そこから param1(第7引数)の値を引いた値を閾値として利用します.
このように求められた閾値を超えるピクセルは maxVal (第3引数)に,それ以外は 0 になります.
// (4)入力画像と処理結果画像を表示します.
入力画像と,処理されたそれぞれの二値化画像を表示します.また,何かキーが押されるとプログラムを終了します.
C++
#include <cv.h> #include <highgui.h> using namespace cv; int main(int argc, char **argv) { // (1)load a specified file and convert it into grayscale image const char *imagename = argc > 1 ? argv[1] : "../image/trains.png"; Mat src_img = imread(imagename); if(!src_img.data) return -1; Mat gray_img; cvtColor(src_img, gray_img, CV_BGR2GRAY); // (2)apply a fixed-level threshold to each pixel Mat bin_img, bininv_img, trunc_img, tozero_img, tozeroinv_img; threshold(gray_img, bin_img, 0, 255, THRESH_BINARY|THRESH_OTSU); threshold(gray_img, bininv_img, 0, 255, THRESH_BINARY_INV|THRESH_OTSU); threshold(gray_img, trunc_img, 0, 255, THRESH_TRUNC|THRESH_OTSU); threshold(gray_img, tozero_img, 0, 255, THRESH_TOZERO|THRESH_OTSU); threshold(gray_img, tozeroinv_img, 0, 255, THRESH_TOZERO_INV|THRESH_OTSU); // (3)apply an adaptive threshold to a grayscale image Mat adaptive_img; adaptiveThreshold(gray_img, adaptive_img, 255, ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 7, 8); // (4)show source and destination images namedWindow("Source", CV_WINDOW_AUTOSIZE); namedWindow("Binary", CV_WINDOW_AUTOSIZE); namedWindow("Binary Inv", CV_WINDOW_AUTOSIZE); namedWindow("Trunc", CV_WINDOW_AUTOSIZE); namedWindow("ToZero", CV_WINDOW_AUTOSIZE); namedWindow("ToZero Inv", CV_WINDOW_AUTOSIZE); namedWindow("Adaptive", CV_WINDOW_AUTOSIZE); imshow("Source", src_img); imshow("Binary", bin_img); imshow("Binary Inv", bininv_img); imshow("Trunc", trunc_img); imshow("ToZero", tozero_img); imshow("ToZero Inv", tozeroinv_img); imshow("Adaptive", adaptive_img); waitKey(0); return 0; }
// (1)指定ファイルをカラー画像として読み込み,それをグレースケールに変換します.
指定されたファイルを3チャンネルのカラー画像として読み込み,関数 cvtColor を用いてグレースケールに変換します.
// (2)画像に対し,さまざまな固定閾値処理を行います.
関数 threshold を用いて,入力画像から作成されたグレースケール画像に対して,以下のような固定閾値処理を行います(C インタフェースとは,定数の名前が異なることに注意してください).
- THRESH_BINARY : 閾値を超えるピクセルは maxVal に,それ以外のピクセルは 0 になります.
- THRESH_BINARY_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは maxVal になります.
- THRESH_TRUNC : 閾値を超えるピクセルは threshold に,それ以外のピクセルは変更されません.
- THRESH_TOZERO : 閾値を超えるピクセルは変更されず,それ以外のピクセルは 0 になります.
- THRESH_TOZERO_INV : 閾値を超えるピクセルは 0 に,それ以外のピクセルは変更されません.
また,このサンプルでは,全ての手法に対して THRESH_OTSU を指定することで,大津の手法を用いて自動的に閾値を決定します.もちろん,これを行わずに自分で閾値を決定することも可能です.
// (3)画像に対し,適応的な閾値処理を行います.
関数 adaptiveThreshold
を用いて,入力画像から作成されたグレースケール画像に対して,適応的な閾値処理を行います.閾値が適応的に決定されるので,対象ピクセルは,画像全体ではなく,その近傍領域に対して明暗を決定されます.
ここでは第4引数で ADAPTIVE_THRESH_GAUSSIAN_C を指定しているので,blockSize(第6引数)x blockSize
の近傍領域に対してガウシアンを重みとして総和をとり,そこから C(第7引数)の値を引いた値を閾値として利用します.
このように求められた閾値を超えるピクセルは maxVal (第3引数)に,それ以外は 0 になります.
// (4)入力画像と処理結果画像を表示します.
入力画像と,処理されたそれぞれの二値化画像を表示します.また,何かキーが押されるとプログラムを終了します.