エッジ検出(Sobel,Laplacian,Canny)
C
#include <cv.h> #include <highgui.h> int main (int argc, char **argv) { IplImage *src_img, *sobel_img, *laplaian_img, *canny_img; IplImage *tmp_img; char *imagename; // (1)load a specified file as a grayscale image // and allocate destination images imagename = argc > 1 ? argv[1] : "../image/bike_sign.png"; src_img = cvLoadImage(imagename, CV_LOAD_IMAGE_GRAYSCALE); if(src_img == 0) return -1; tmp_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_32F, 1); sobel_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); laplaian_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); canny_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); // (2)calculate the first image derivatives using an Sobel operator cvSobel(src_img, tmp_img, 1, 1, 3); cvConvertScaleAbs(tmp_img, sobel_img, 1, 0); // (3)calculate the Laplacian of an image cvLaplace(src_img, tmp_img, 3); cvConvertScaleAbs(tmp_img, laplaian_img, 1, 0); // (4)implement the Canny algorithm for edge detection cvCanny(src_img, canny_img, 50.0, 200.0, 3); // (5)show original gray and their edge images respectively, // and quit when any key pressed cvNamedWindow("Original(GrayScale)", CV_WINDOW_AUTOSIZE); cvNamedWindow("Sobel", CV_WINDOW_AUTOSIZE); cvNamedWindow("Laplacian", CV_WINDOW_AUTOSIZE); cvNamedWindow("Canny", CV_WINDOW_AUTOSIZE); cvShowImage("Original(GrayScale)", src_img); cvShowImage("Sobel", sobel_img); cvShowImage("Laplacian", laplaian_img); cvShowImage("Canny", canny_img); cvWaitKey(0); cvDestroyWindow("Original"); cvDestroyWindow("Sobel"); cvDestroyWindow("Laplace"); cvDestroyWindow("Canny"); cvReleaseImage(&src_img); cvReleaseImage(&sobel_img); cvReleaseImage(&laplaian_img); cvReleaseImage(&canny_img); cvReleaseImage(&tmp_img); return 0; }
// (1)指定ファイルをグレースケール画像として読み込みます.また,それと同サイズの出力画像領域を確保します.
このサンプルでは,エッジの検出を目的としているので(色情報は不要なので),グレースケール画像として読み込みを行います.また,それと同サイズの出力画像領域,テンポラリ画像領域を確保します.テンポラリ画像領域は,もとの8Uよりも大きいビット深度(ここでは32F,64Fでも可)でなければならないことに注意してください.
// (2)Sobelオペレータを用いて,1次微分画像を求めます.
関数 cvSobel を用いて,1次微分画像を計算します.第3,第4引数共に1を指定して,x-方向,y-方向の微分を求めます.また,オペレータのアパーチャサイズは 3 を指定しています.この計算結果を,グレースケール画像(ビット深度 8U)に変換します.
// (3)画像のラプラシアン(2次微分)を求めます.
関数 cvLaplace を用いて,2時微分画像を計算します.アパーチャサイズは 3 を指定します.この計算結果を,グレースケール画像(ビット深度 8U)に変換します.
// (4)Cannyアルゴリズムを用いて,エッジを検出します.
関数 cvCanny を用いて,エッジを検出します.第3,第4引数はそれぞれ,エッジの初期検出と,そこから続くエッジの接続に用いられる閾値を表します.この2つの引数は,数値の大小でその意味を判断されるので,順序は (50, 200) でも (200, 50) でも等価です.アパーチャサイズは,3を指定します.
// (5)元のグレースケール画像,それぞれのエッジ画像を表示します.
元画像(グレースケール),および3種の処理画像を表示します.また,何かキーが押された場合プログラムを終了します.
C++
#include <cv.h> #include <highgui.h> using namespace cv; int main (int argc, char **argv) { // (1)load a specified file as a grayscale image const char *imagename = argc > 1 ? argv[1] : "../image/bike_sign.png"; Mat src_img = imread(imagename, 0); if(!src_img.data) return -1; // (2)calculate the first image derivatives using an Sobel operator Mat tmp_img; Mat sobel_img; Sobel(src_img, tmp_img, CV_32F, 1, 1); convertScaleAbs(tmp_img, sobel_img, 1, 0); // (3)calculate the Laplacian of an image Mat laplacian_img; Laplacian(src_img, tmp_img, CV_32F, 3); convertScaleAbs(tmp_img, laplacian_img, 1, 0); // (4)implement the Canny algorithm for edge detection Mat canny_img; Canny(src_img, canny_img, 50, 200); // (5)show original gray and their edge images respectively, // and quit when any key pressed namedWindow("Original(Grayscale)", CV_WINDOW_AUTOSIZE); namedWindow("Sobel", CV_WINDOW_AUTOSIZE); namedWindow("Laplacian", CV_WINDOW_AUTOSIZE); namedWindow("Canny", CV_WINDOW_AUTOSIZE); imshow("Original(Grayscale)", src_img); imshow("Sobel", sobel_img); imshow("Laplacian", laplacian_img); imshow("Canny", canny_img); waitKey(0); return 0; }
// (1)指定ファイルをグレースケール画像として読み込みます.
このサンプルでは,エッジの検出を目的としているので(色情報は不要なので),グレースケール画像として読み込みを行います.
// (2)Sobelオペレータを用いて,1次微分画像を求めます.
関数 Sobel を用いて,1次微分画像を計算します.第4,第5引数共に1を指定して,x-方向,y-方向の微分を求めます.また,オペレータのアパーチャは 3 を指定しています.この計算結果を,グレースケール画像(ビット深度 8U)に変換します.
// (3)画像のラプラシアン(2次微分)を求めます.
関数 Laplacian を用いて,2時微分画像を計算します.アパーチャサイズは 3 を指定します.この計算結果を,グレースケール画像(ビット深度 8U)に変換します.
// (4)Cannyアルゴリズムを用いて,エッジを検出します.
関数 Canny を用いて,エッジを検出します.第3,第4引数はそれぞれ,エッジの初期検出と,そこから続くエッジの接続に用いられる閾値を表します.この2つの引数は,数値の大小でその意味を判断されるので,順序は (50, 200) でも (200, 50) でも等価です.アパーチャサイズは指定せず,デフォルト値の3を利用します.
// (5)元のグレースケール画像,それぞれのエッジ画像を表示します.
元画像(グレースケール),および3種の処理画像を表示します.また,何かキーが押された場合プログラムを終了します.
実行結果例
元画像(カラー)
(左から)入力画像(グレースケール),処理結果(Sobel,Laplacian,Canny)