下面直接附上opencv的canny边缘检测。
// canny.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
/// 全局变量
Mat src, src_gray;
Mat dst, detected_edges;
int edgeThresh = 1;
int lowThreshold;
int const max_lowThreshold = 100; //将低阈值的上限设定为 :math:`100`.
int ratio = 3; //我们首先设定高:低阈值比为 3:1 (通过变量 *ratio* )
int kernel_size = 3; //设定内核尺寸为 :math:`3` (Canny函数内部调用Sobel操作)
char* window_name = "Edge Map";
/**
* @函数 CannyThreshold
* @简介: trackbar 交互回调 - Canny阈值输入比例1:3
*/
void CannyThreshold(int, void*)
{
/// 使用 3x3内核降噪(平滑图像)
blur( src_gray, detected_edges, Size(3,3) );
/// 运行Canny算子,寻找边缘,输出为:detected_edges
//lowThreshold: lowThreshold; highThreshold: lowThreshold*ratio
//kernel_size: 设定为 3 (Sobel内核大小,内部使用)
Canny( detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size );
/// 使用 Canny算子输出边缘作为掩码显示原图像
//填充 dst 图像,填充值为0 (图像全黑)
dst = Scalar::all(0);
//copyTo将detected_edges拷贝到dst,但是,仅仅拷贝掩码不为0的像素
//Canny边缘检测的输出是镶嵌在黑色背景中的边缘像素,
//因此其结果 dst 图像除了被检测的边缘像素,其余部分都为黑色。
//imshow("aa",detected_edges);
src.copyTo( dst, detected_edges);
imshow( window_name, dst );
}
/** @函数 main */
int main( int argc, char** argv )
{
/// 装载图像
src = imread( "../hand.jpg" );
if( !src.data )
{ return -1; }
/// 创建与src同类型和大小的矩阵(dst)
dst.create( src.size(), src.type() );
/// 原图像转换为灰度图像
cvtColor( src, src_gray, CV_BGR2GRAY );
/// 创建显示窗口
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
/// 创建trackbar,来获取用户交互输入的低阈值,
//1.注意通过trackbar控制的变量为lowThreshold ;2.每次用户通过trackbar产生变动,回调函数 CannyThreshold 被调用.
createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold );
/// 显示图像
CannyThreshold(0, 0);
/// 等待用户反应
waitKey(0);
return 0;
}
参考