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

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;
}

猜你喜欢

转载自blog.csdn.net/qq_39396954/article/details/80524726