openCV学习8-两个算子+Canny边缘检测

本文介绍了Sobel算子用于检测图像中像素变化快的区域,即边缘;接着讲解了拉普拉斯算子作为二阶导数在边缘检测中的应用;最后阐述了Canny边缘检测算法,包括模糊降噪、灰度转换、梯度计算和非边缘抑制等步骤,以获取高质量的二值边缘图像。
摘要由CSDN通过智能技术生成

1.Sobel算子

·瞧一瞧关于图像像素的函数,在变化快的地方(求导大的地方)边缘信号强!







#include <opencv2\core\core.hpp>  
#include <opencv2\highgui\highgui.hpp>  
#include <opencv2\imgproc\imgproc.hpp>  
#include <opencv2\objdetect\objdetect.hpp>  
#include <opencv2\imgproc\types_c.h>  
#include <opencv2\objdetect\objdetect_c.h>
#include<opencv2/opencv.hpp>
#include<iostream>
#include<cmath>
#include<cstdio>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst;
	src=imread("cat.jpg");
	if(src.empty())
	{
		cout<<"!!???"<<endl;
		return -1;
	}
	namedWindow("cat!",1);
	namedWindow("out",1);
	imshow("cat!",src);

	//先高斯模糊
	GaussianBlur(src,dst,Size(3,3),0,0);
	//转灰度图
	Mat src_gray;
	cvtColor(dst,src_gray,CV_BGR2GRAY);
	imshow("gray!",src_gray);
	//Sobel
	Mat x,y;
	Scharr(src_gray,x,CV_16S,1,0);//比Sobel方法更明显的边缘!
	Scharr(src_gray,y,CV_16S,0,1);
	//Sobel(src_gray,x,CV_16S,1,0,3);
	//Sobel(src_gray,y,CV_16S,0,1,3);
	convertScaleAbs(x,x);//显示正的
	convertScaleAbs(y,y);
	imshow("x!",x);
	imshow("y!",y);
	//混合
	Mat xy=Mat(x.size(),x.type());
	int width=x.cols;
	int height=y.rows;
	for(int i=0;i<height;i++)
	{
		for(int j=0;j<width;j++)
		{
			int xg=x.at<uchar>(i,j);
			int yg=y.at<uchar>(i,j);
			int xxyy=xg+yg;
			xy.at<char>(i,j)=saturate_cast<uchar>(xxyy);
		}
	}
	//addWeighted(x,0.5,y,0.5,0,xy);
	imshow("out",xy);

	waitKey(0);
	return 0;
}

2.拉普拉斯算子


这是二阶导的玩法♂



#include <opencv2\core\core.hpp>  
#include <opencv2\highgui\highgui.hpp>  
#include <opencv2\imgproc\imgproc.hpp>  
#include <opencv2\objdetect\objdetect.hpp>  
#include <opencv2\imgproc\types_c.h>  
#include <opencv2\objdetect\objdetect_c.h>
#include<opencv2/opencv.hpp>
#include<iostream>
#include<cmath>
#include<cstdio>

using namespace std;
using namespace cv;

int main()
{
	Mat src,dst;
	src=imread("cat.jpg");
	if(src.empty())
	{
		cout<<"!!???"<<endl;
		return -1;
	}
	namedWindow("cat!",1);
	imshow("cat!",src);
	namedWindow("out",1);

	Mat src_gray,edge;
	GaussianBlur(src,dst,Size(3,3),0,0);
	cvtColor(dst,src_gray,CV_BGR2GRAY);
	Laplacian(src_gray,edge,CV_16S,3);
	convertScaleAbs(edge,edge);
	threshold(edge,edge,0,255,THRESH_OTSU|THRESH_BINARY);
	imshow("out",edge);
	waitKey(0);
	return 0;
}

3.Canny边缘检测


↑先模糊降噪,再转灰度,获取梯度,再压制非边缘的点(只留最大点),通过阈值->二值图像





#include <opencv2\core\core.hpp>  
#include <opencv2\highgui\highgui.hpp>  
#include <opencv2\imgproc\imgproc.hpp>  
#include <opencv2\objdetect\objdetect.hpp>  
#include <opencv2\imgproc\types_c.h>  
#include <opencv2\objdetect\objdetect_c.h>
#include<opencv2/opencv.hpp>
#include<iostream>
#include<cmath>
#include<cstdio>

using namespace std;
using namespace cv;

Mat src,dst1,dst,src_gray;
int t1=50,maxx=255;

void canny_demo(int,void*)
{
	blur(src_gray,src_gray,Size(3,3),Point(-1,-1),BORDER_DEFAULT);
	Canny(src_gray,dst1,t1,t1*2,3,false);
	//dst.create(src.size(),src.type());//彩色的!
	//src.copyTo(dst,dst1);
	imshow("out",dst1);
}

int main()
{
	src=imread("cat.jpg");
	if(src.empty())
	{
		cout<<"!!???"<<endl;
		return -1;
	}
	namedWindow("cat!",1);
	imshow("cat!",src);
	namedWindow("out",1);

	cvtColor(src,src_gray,CV_BGR2GRAY);
	createTrackbar("Threshold Value:","out",&t1,maxx,canny_demo);
	canny_demo(0,0);

	waitKey(0);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值