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