最近在做特征提取,学习巩固一些基础算法在OpenCV编程中的实现。
图片来源:毛星云老师的《OpenCV3编程入门》
该代码的功能是对一张图片进行Canny边缘检测,检测的高阈值、低阈值和高斯模糊核的半径可以拖动滑块进行修改。
//---------------------------------【头文件、命名空间包含部分】---------------------------- // 描述:包含程序所使用的头文件和命名空间 //------------------------------------------------------------------------------------------------ #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp> using namespace cv; //-----------------------------------【全局变量声明部分】-------------------------------------- // 描述:全局变量声明 //----------------------------------------------------------------------------------------------- //原图,原图的灰度版,目标图 Mat g_srcImage, g_srcGrayImage, g_dstImage; //Canny边缘检测相关变量 Mat g_cannyDetectedEdges; int g_cannyLowThreshold = 1;//TrackBar位置参数 int g_cannyHighThreshold = 3; int denoise_kernel_size = 1; //-----------------------------------【全局函数声明部分】-------------------------------------- // 描述:全局函数声明 //----------------------------------------------------------------------------------------------- static void ShowHelpText(); static void on_Canny(int, void*);//Canny边缘检测窗口滚动条的回调函数 //-----------------------------------【main( )函数】-------------------------------------------- // 描述:控制台应用程序的入口函数,我们的程序从这里开始 //----------------------------------------------------------------------------------------------- int main(int argc, char** argv) { //改变console字体颜色 system("color 2F"); //显示欢迎语 ShowHelpText(); //载入原图 g_srcImage = imread("luomu.jpg"); if (!g_srcImage.data) { printf("Oh,no,读取srcImage错误~! \n"); return false; } //显示原始图 namedWindow("【原始图】"); imshow("【原始图】", g_srcImage); // 创建与src同类型和大小的矩阵(dst) g_dstImage.create(g_srcImage.size(), g_srcImage.type()); // 将原图像转换为灰度图像 cvtColor(g_srcImage, g_srcGrayImage, COLOR_BGR2GRAY); // 创建显示窗口 namedWindow("【效果图】Canny边缘检测", WINDOW_AUTOSIZE); // 创建trackbar createTrackbar("低阈值", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny); createTrackbar("高阈值", "【效果图】Canny边缘检测", &g_cannyHighThreshold, 120, on_Canny); createTrackbar("高斯核半径", "【效果图】Canny边缘检测", &denoise_kernel_size, 50, on_Canny); // 调用回调函数 on_Canny(0, 0); //轮询获取按键信息,若按下Q,程序退出 while ((char(waitKey(1)) != 'q')) {} return 0; } //-----------------------------------【ShowHelpText( )函数】---------------------------------- // 描述:输出一些帮助信息 //---------------------------------------------------------------------------------------------- static void ShowHelpText() { //输出欢迎信息和OpenCV版本 printf("\n\n\t\t\t 欢迎使用\n"); printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION); printf("\n\n ----------------------------------------------------------------------------\n"); //输出一些帮助信息 printf("\n\n\t运行成功,请调整滚动条观察图像效果~\n\n" "\t按下“q”键时,程序退出。\n"); } //-----------------------------------【on_Canny( )函数】---------------------------------- // 描述:Canny边缘检测窗口滚动条的回调函数 //----------------------------------------------------------------------------------------------- void on_Canny(int, void*) { // 先使用 3x3内核来降噪 blur(g_srcGrayImage, g_cannyDetectedEdges, Size(denoise_kernel_size * 2 + 1, denoise_kernel_size * 2 + 1)); // 运行我们的Canny算子 Canny(g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyHighThreshold, 3); //先将g_dstImage内的所有元素设置为0 g_dstImage = Scalar::all(0); //使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中 g_srcImage.copyTo(g_dstImage, g_cannyDetectedEdges); //显示效果图 imshow("【效果图】Canny边缘检测", g_dstImage); }原图: 输出结果: 拖动滑块修改阈值:
canny函数参数中有两个关于滞后阈值的参数。正常情况下低阈值应低于高阈值。但是若高阈值低于低阈值时canny函数自动将高阈值识别为低阈值,低阈值识别为高阈值: 低阈值为:5 高阈值为:15 低阈值为:15 高阈值为:5
可以看出,两组参数的边缘检测结果是相同的。