エッジ検出(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)






