基于opencv的边缘检测

一;

边缘检测的一般步骤:(1)滤波,经常使用高斯滤波

    (2)增强

                                            (3)检测,常使用阈值方法检测


1,canny算子:

步骤:【1】消除噪声

                                           【2】计算梯度幅值和方向

   【3】非极大值抑制

           【4】滞后阈值

示例:

#include"stdafx.h"
#include 
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include"opencv2/core/core.hpp"
#include 

using namespace cv;
using namespace std;

//		描述:全局变量声明
//定义原始图,目标图,灰度图,掩码图
Mat image, g_srcImage, g_srcImage2, g_dstImage, g_dstImage2, g_grayImage, g_edgeImage, tempImage;


//-----------------------------------【main( )函数】--------------------------------------------
//		描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改变console字体颜色
	system("color 4F");

	//载入原图
	image = imread("E:\\pictures\\For_Project\\New_opencv\\Fruits.jpg",1);
	if (!image.data) { printf("Oh,no,读取srcImage错误~! \n"); return false; }

	//显示原始图
	namedWindow("【原始图】");
	imshow("【原始图】", image);
	//定义操作后保存结果图

	g_srcImage = image.clone();
	g_srcImage2 = image.clone();
	g_dstImage = image.clone();
	//复制原图到临时变量
	
	
	Canny(g_srcImage, g_dstImage, 150, 100, 3);
    imshow("【效果图】灰度图", g_dstImage);
	
	tempImage.create(g_srcImage.size(), g_srcImage.type());
	cvtColor(g_srcImage2, g_grayImage, COLOR_BGR2GRAY);
	blur(g_grayImage, g_edgeImage, Size(3, 3));

	Canny(g_edgeImage, g_edgeImage, 3, 9, 3);

	tempImage = Scalar::all(0);

	g_srcImage.copyTo(tempImage, g_edgeImage);

	imshow("【效果图】Canny边缘检测彩色图图", tempImage);

	//等待键盘按键‘q’退出  
	while (char(waitKey(1)) != 'q') {}
	return 0;
}

效果:

基于opencv的边缘检测_第1张图片



2.Sobel算子

(1)分别在x和y方向上求导卷积所得

使用函数void Sobel(input,poutput,int depth,int dx,int dy,int ksize=3,double scale=1,double delta=0,int                         borderType=BORDER_DEFAULT);

示例:

#include"stdafx.h"
#include 
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include"opencv2/core/core.hpp"
#include 

using namespace cv;
using namespace std;

//		描述:全局变量声明
//定义原始图,目标图,灰度图,掩码图
Mat image, g_srcImage, g_srcImage2, g_dstImage, g_dstImage2, g_grayImage, g_edgeImage, tempImage;


//-----------------------------------【main( )函数】--------------------------------------------
//		描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改变console字体颜色
	system("color 4F");

	//载入原图
	Mat grad_x, grad_y, abs_grad_x, abs_grad_y, dst;
	Mat src = imread("E:\\pictures\\For_Project\\New_opencv\\pigdog.jpg",1);
	imshow("【原图】", src);

	Sobel(src, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
	convertScaleAbs(grad_x, abs_grad_x);
	imshow("【效果图】Sobel边缘检测X方向",abs_grad_x);

	Sobel(src, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
	convertScaleAbs(grad_y, abs_grad_y);
	imshow("【效果图】Sobel边缘检测Y方向", abs_grad_y);

	addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
	imshow("【效果图】Sobel边缘检测整体方向", dst);

	//等待键盘按键‘q’退出  
	while (char(waitKey(1)) != 'q') {}
	return 0;
}


基于opencv的边缘检测_第2张图片基于opencv的边缘检测_第3张图片











基于opencv的边缘检测_第4张图片基于opencv的边缘检测_第5张图片





















3:Laplacian算子

使用Laplacian函数

示例:

#include"stdafx.h"
#include 
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include"opencv2/core/core.hpp"
#include 

using namespace cv;
using namespace std;

//		描述:全局变量声明
//定义原始图,目标图,灰度图,掩码图
Mat image, g_srcImage, g_srcImage2, g_dstImage, g_dstImage2, g_grayImage, g_edgeImage, tempImage;


//-----------------------------------【main( )函数】--------------------------------------------
//		描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改变console字体颜色
	system("color 4F");

	//载入原图
	Mat src, src_gray, dst, abs_dst;
	src = imread("E:\\pictures\\For_Project\\New_opencv\\pigdog.jpg",1);
	imshow("【原图】", src);
	//使用高斯滤波消除噪声
	GaussianBlur(src, src, Size(3, 3), 0, 0, BORDER_DEFAULT);
	//转换为灰度图
	cvtColor(src,src_gray,COLOR_RGB2GRAY);
	//使用Laplacian函数
	Laplacian(src_gray, dst, CV_16S, 3, 1, 0, BORDER_DEFAULT);
	//计算绝对值,并将结果转换为8位
	convertScaleAbs(dst, abs_dst);
	imshow("【效果图】Laplace变换", abs_dst);

	//等待键盘按键‘q’退出  
	while (char(waitKey(1)) != 'q') {}
	return 0;
}
效果:

基于opencv的边缘检测_第6张图片


4.scharr滤波器

使用函数Scharr来计算图像差分,其计算图像x或者y方向的图像积分,除了没有ksize核的大小,其他                         的参数几本和Sobel算子一样。

示例:

#include"stdafx.h"
#include 
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include"opencv2/core/core.hpp"
#include 

using namespace cv;
using namespace std;

//		描述:全局变量声明
//定义原始图,目标图,灰度图,掩码图
Mat image, g_srcImage, g_srcImage2, g_dstImage, g_dstImage2, g_grayImage, g_edgeImage, tempImage;


//-----------------------------------【main( )函数】--------------------------------------------
//		描述:控制台应用程序的入口函数,我们的程序从这里开始
//-----------------------------------------------------------------------------------------------
int main()
{
	//改变console字体颜色
	system("color 4F");

	//载入原图
	Mat src, grad_x, grad_y, abs_grad_x, abs_grad_y, dst;
	src = imread("E:\\pictures\\For_Project\\New_opencv\\f7.jpg", 1);
	imshow("【原图】", src);

	Scharr(src, grad_x, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
	convertScaleAbs(grad_x, abs_grad_x);
	imshow("【效果图】X方向Scharr", abs_grad_x);

	Scharr(src, grad_y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT);
	convertScaleAbs(grad_y, abs_grad_y);
	imshow("【效果图】Y方向Scharr", abs_grad_y);

	addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
	imshow("【效果图】整合后Scharr", dst);


	//等待键盘按键‘q’退出  
	while (char(waitKey(1)) != 'q') {}
	return 0;
}
效果;

基于opencv的边缘检测_第7张图片基于opencv的边缘检测_第8张图片

基于opencv的边缘检测_第9张图片基于opencv的边缘检测_第10张图片






































综合示例:

#include"stdafx.h"
#include 
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include"opencv2/core/core.hpp"
#include 

//-----------------------------------【命名空间声明部分】--------------------------------------  
//      描述:包含程序所使用的命名空间  
//-----------------------------------------------------------------------------------------------   
using namespace cv;


//-----------------------------------【全局变量声明部分】--------------------------------------  
//      描述:全局变量声明  
//-----------------------------------------------------------------------------------------------  
//原图,原图的灰度版,目标图  
Mat g_srcImage, g_srcGrayImage, g_dstImage;

//Canny边缘检测相关变量  
Mat g_cannyDetectedEdges;
int g_cannyLowThreshold = 1;//TrackBar位置参数    

							//Sobel边缘检测相关变量  
Mat g_sobelGradient_X, g_sobelGradient_Y;
Mat g_sobelAbsGradient_X, g_sobelAbsGradient_Y;
int g_sobelKernelSize = 1;//TrackBar位置参数    

						  //Scharr滤波器相关变量  
Mat g_scharrGradient_X, g_scharrGradient_Y;
Mat g_scharrAbsGradient_X, g_scharrAbsGradient_Y;


//-----------------------------------【全局函数声明部分】--------------------------------------  
//      描述:全局函数声明  
//-----------------------------------------------------------------------------------------------  
static void ShowHelpText();
static void on_Canny(int, void*);//Canny边缘检测窗口滚动条的回调函数  
static void on_Sobel(int, void*);//Sobel边缘检测窗口滚动条的回调函数  
void Scharr();//封装了Scharr边缘检测相关代码的函数  


			  //-----------------------------------【main( )函数】--------------------------------------------  
			  //      描述:控制台应用程序的入口函数,我们的程序从这里开始  
			  //-----------------------------------------------------------------------------------------------  
int main(int argc, char** argv)
{
	//改变console字体颜色  
	system("color 2F");

	//显示欢迎语  
	ShowHelpText();

	//载入原图  
	g_srcImage = imread("E:\\pictures\\For_Project\\New_opencv\\girl.jpg",1);
	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, CV_BGR2GRAY);

	// 创建显示窗口  
	namedWindow("【效果图】Canny边缘检测", CV_WINDOW_AUTOSIZE);
	namedWindow("【效果图】Sobel边缘检测", CV_WINDOW_AUTOSIZE);

	// 创建trackbar  
	createTrackbar("参数值:", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny);
	createTrackbar("参数值:", "【效果图】Sobel边缘检测", &g_sobelKernelSize, 3, on_Sobel);

	// 调用回调函数  
	on_Canny(0, 0);
	on_Sobel(0, 0);

	//调用封装了Scharr边缘检测代码的函数  
	Scharr();

	//轮询获取按键信息,若按下Q,程序退出  
	while ((char(waitKey(1)) != 'q')) {}

	return 0;
}


//-----------------------------------【ShowHelpText( )函数】----------------------------------  
//      描述:输出一些帮助信息  
//----------------------------------------------------------------------------------------------  
static void ShowHelpText()
{
	//输出一些帮助信息  
	printf("\n\n\t嗯。运行成功,请调整滚动条观察图像效果~\n\n"
		"\t按下“q”键时,程序退出~!\n"
		"\n\n\t\t\t\t by浅墨");
}


//-----------------------------------【on_Canny( )函数】----------------------------------  
//      描述:Canny边缘检测窗口滚动条的回调函数  
//-----------------------------------------------------------------------------------------------  
void on_Canny(int, void*)
{
	// 先使用 3x3内核来降噪  
	blur(g_srcGrayImage, g_cannyDetectedEdges, Size(3, 3));

	// 运行我们的Canny算子  
	Canny(g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold * 3, 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);
}



//-----------------------------------【on_Sobel( )函数】----------------------------------  
//      描述:Sobel边缘检测窗口滚动条的回调函数  
//-----------------------------------------------------------------------------------------  
void on_Sobel(int, void*)
{
	// 求 X方向梯度  
	Sobel(g_srcImage, g_sobelGradient_X, CV_16S, 1, 0, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);
	convertScaleAbs(g_sobelGradient_X, g_sobelAbsGradient_X);//计算绝对值,并将结果转换成8位  

															 // 求Y方向梯度  
	Sobel(g_srcImage, g_sobelGradient_Y, CV_16S, 0, 1, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);
	convertScaleAbs(g_sobelGradient_Y, g_sobelAbsGradient_Y);//计算绝对值,并将结果转换成8位  

															 // 合并梯度  
	addWeighted(g_sobelAbsGradient_X, 0.5, g_sobelAbsGradient_Y, 0.5, 0, g_dstImage);

	//显示效果图  
	imshow("【效果图】Sobel边缘检测", g_dstImage);

}


//-----------------------------------【Scharr( )函数】----------------------------------  
//      描述:封装了Scharr边缘检测相关代码的函数  
//-----------------------------------------------------------------------------------------  
void Scharr()
{
	// 求 X方向梯度  
	Scharr(g_srcImage, g_scharrGradient_X, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
	convertScaleAbs(g_scharrGradient_X, g_scharrAbsGradient_X);//计算绝对值,并将结果转换成8位  

															   // 求Y方向梯度  
	Scharr(g_srcImage, g_scharrGradient_Y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT);
	convertScaleAbs(g_scharrGradient_Y, g_scharrAbsGradient_Y);//计算绝对值,并将结果转换成8位  

															   // 合并梯度  
	addWeighted(g_scharrAbsGradient_X, 0.5, g_scharrAbsGradient_Y, 0.5, 0, g_dstImage);

	//显示效果图  
	imshow("【效果图】Scharr滤波器", g_dstImage);
}
效果图

基于opencv的边缘检测_第11张图片基于opencv的边缘检测_第12张图片基于opencv的边缘检测_第13张图片基于opencv的边缘检测_第14张图片基于opencv的边缘检测_第15张图片基于opencv的边缘检测_第16张图片

你可能感兴趣的:(基于opencv的边缘检测)