opencv3编程入门(第七章7.1-7.2)

7.1.2opencv中调用Canny函数边缘检测:

#include <opencv2\opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main()
{
	Mat img = imread("sg.jpg");//名为sg.jpg的图片一定要与.cpp文件同路径。
	Mat src1 = img.clone();
	imshow("原始图Canny边缘检测", img);
	Mat dst, edge, gray;
	dst.create(src1.size(), src1.type());
	cvtColor(src1, gray, COLOR_BGR2GRAY);
	blur(gray, edge, Size(3, 3));
	Canny(edge, edge, 3, 9, 3);
	dst = Scalar::all(0);//将g_dstImage内所有元素置0
	src1.copyTo(dst, edge);//将原图g_srcImage拷贝到目标图g_dstImage中
	imshow("效果图Canny边缘检测", dst);
	imwrite("轮廓图.jpg", dst);
	waitKey(0);
	return 0;
	
}

原图如下:
在这里插入图片描述

程序执行结果如图:
在这里插入图片描述
7.1.3Sobel算子的使用

#include <opencv2\opencv.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
int main()
{
	Mat grad_x, grad_y;
	Mat abs_grad_x, abs_grad_y, dst;
	Mat img = imread("sg.jpg");//名为sg.jpg的图片一定要与.cpp文件同路径。
	imshow("原始图Sobel边缘检测", img);
	//求x方向梯度
	Sobel(img, grad_x, CV_16S, 1, 0, 3, 1, 1, BORDER_DEFAULT);
	//CV_16S是输出的图像深度
	convertScaleAbs(grad_x, abs_grad_x);
	imshow("效果图X方向Sobel", abs_grad_x);
	//求y方向梯度
	Sobel(img, grad_y, CV_16S, 0, 1, 3, 1, 1, BORDER_DEFAULT);
	convertScaleAbs(grad_y, abs_grad_y);/*该函数对整个图像数组中的每一个元素,进行操作,可实现图像增强等相关先行操作的快速运算,也常用于将CV_16S、CV_32F等
	其他类型的输出图像转变成CV_8U型的图像。*/
	imshow("效果图Y方向Sobel", abs_grad_y);
	//合并梯度
	addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, dst);
	imshow("效果图整体方向Spbel", dst);
	imwrite("轮廓图01.jpg", abs_grad_x);
	imwrite("轮廓图02.jpg", abs_grad_y);
	imwrite("轮廓图03.jpg", dst);
	waitKey(0);
	return 0;
	
}

程序执行效果如图;Sobel整体方向图:
在这里插入图片描述
7.1.6边缘检测综合实例:

#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位置参数
							//Sobel边缘检测相关变量
Mat g_sobelGradient_X, g_sobelGradient_Y;
Mat g_sobelAbsgradient_X, g_sobelAbsgradient_Y;
int g_sobelKernelSize = 1;
//Scharr滤波器相关变量
Mat g_scharrGradient_X, g_scharrGradient_Y;
Mat g_scharrAbsGradient_X, g_scharrAbsGradient_Y;
static void on_Canny(int, void*);
static void on_Sobel(int, void*);
void Scharr();
int main(int argc, char** argv)
{
	system("color 2F");
	g_srcImage = imread("sg.jpg");
	if (!g_srcImage.data) {
		printf("读取错误\n");return false;
	}
	namedWindow("原始图");
	imshow("原始图", g_srcImage);
	g_dstImage.create(g_srcImage.size(), g_srcImage.type());
	cvtColor(g_srcImage, g_srcGrayImage, COLOR_BGR2GRAY);
	namedWindow("效果图Canny边缘检测", WINDOW_AUTOSIZE);
	namedWindow("效果图Sobel边缘检测", WINDOW_AUTOSIZE);
	createTrackbar("参数值", "效果图Canny边缘检测", &g_cannyLowThreshold,
		120, on_Canny);
	createTrackbar("参数值", "效果图Sobel边缘检测", &g_sobelKernelSize,
		3, on_Sobel);
	on_Canny(0, 0);//调用回调函数
	on_Sobel(0, 0);
	Scharr();
	while ((char(waitKey(1)) != 'q')) {}
	return 0;

}

//Canny边缘检测窗口滚动条的回调函数
void on_Canny(int, void*)
{
	blur(g_srcGrayImage, g_cannyDetectedEdges, Size(3, 3));
	Canny(g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold,
		g_cannyLowThreshold * 3, 3);
	g_dstImage = Scalar::all(0);
	g_srcImage.copyTo(g_dstImage, g_cannyDetectedEdges);
	imshow("效果图Canny边缘检测", g_dstImage);
}
//Sobel边缘检测窗口滚动条的回调函数
void on_Sobel(int, void*)
{
	Sobel(g_srcImage, g_sobelGradient_X, CV_16S, 1, 0, (2 * g_sobelKernelSize + 1),
		1, 1, BORDER_DEFAULT);//CV_16S是输出的图像深度
	convertScaleAbs(g_sobelGradient_X, g_sobelAbsgradient_X);
	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);
	addWeighted(g_sobelAbsgradient_X, 0.5, g_sobelAbsgradient_Y, 0.5, 0, g_dstImage);
	imshow("效果图Sobel边缘检测", g_dstImage);

}
//Scharr边缘检测,
void Scharr()
{
	Scharr(g_srcImage, g_scharrGradient_X, CV_16S, 1, 0, 1,
		0, BORDER_DEFAULT);//CV_16S是输出的图像深度
	convertScaleAbs(g_scharrGradient_X, g_scharrAbsGradient_X);
	Scharr(g_srcImage, g_scharrGradient_Y, CV_16S, 0, 1,
		1, 0, BORDER_DEFAULT);
	convertScaleAbs(g_scharrGradient_Y, g_scharrAbsGradient_Y);
	addWeighted(g_scharrAbsGradient_X, 0.5, g_scharrAbsGradient_Y, 0.5, 0, g_dstImage);
	imshow("效果图Scharr滤波器", g_dstImage);
}

程序执行效果如图;
1.Canny边缘检测:在这里插入图片描述
2.Sobel边缘检测:
在这里插入图片描述
3.Scharr滤波器:
在这里插入图片描述
7.2.4标准霍夫变换:HoughLines()函数

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat srcImage = imread("tsg.jpg");
	Mat midImage, dstImage;
	Canny(srcImage, midImage, 50, 200, 3);
	cvtColor(midImage, dstImage, COLOR_GRAY2BGR);//为什么是转化边缘检测后的图为灰度图?
	vector<Vec2f>lines;
	HoughLines(midImage, lines, 1, CV_PI / 180, 150, 0, 0);
	for (size_t i = 0;i < lines.size();i++)
	{
		float rho = lines[i][0], theta = lines[i][1];
		Point pt1, pt2;
		double a = cos(theta), b = sin(theta);
		double x0 = a*rho, y0 = b*rho;
		pt1.x = cvRound(x0 + 1000 * (-b));
		pt1.y = cvRound(y0 + 1000 * (a));
		pt2.x = cvRound(x0 + 1000 * (-b));
		pt2.y = cvRound(y0 + 1000 * (a));
		line(dstImage, pt1, pt2, Scalar(55, 100, 195), 1, LINE_AA);
		//以上参数含义:输入图像,线段起点、终点、线条颜色、线宽、线段类型。
	}
	imshow("原始图", srcImage);
	imshow("Canny边缘检测图", midImage);
	imshow("效果图", dstImage);
	waitKey(0);
	return 0;
}

程序执行结果如图:
在这里插入图片描述
7.2.5累计概率霍夫变换:HoughLinesP()

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat srcImage = imread("tsg.jpg");
	Mat midImage, dstImage;
	Canny(srcImage, midImage, 50, 200, 3);
	cvtColor(midImage, dstImage, COLOR_GRAY2BGR);//为什么是转化边缘检测后的图为灰度图?
	vector<Vec4i>lines;
	HoughLinesP(midImage, lines, 1, CV_PI / 180, 80,50, 10);
	/*以上参数含义:第三个是单位的距离精度,依次是:单位的角度精度、累加平面的阈值参数、
	50表示最低线段的长度、10允许同一行点与点之间连起来的最大距离*/
	for (size_t i = 0;i < lines.size();i++)
	{
		Vec4i l = lines[i];
		line(dstImage,Point(l[0],l[1]),Point(l[2],l[3]), Scalar(186, 88, 255), 1, LINE_AA);
		//以上参数含义:输入图像,线段起点、终点、线条颜色、线宽、线段类型。
	}
	imshow("原始图", srcImage);
	imshow("Canny边缘检测图", midImage);
	imshow("效果图", dstImage);
	waitKey(0);
	return 0;
}

程序执行结果如图:
在这里插入图片描述
7.2.9霍夫圆变换:HoughCircles():

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;

int main()
{
	Mat srcImage = imread("qiu.jpg");
	Mat midImage, dstImage;
	imshow("原始图", srcImage);
	cvtColor(srcImage,midImage, COLOR_BGR2GRAY);//彩色图转化为灰度图
	GaussianBlur(midImage, midImage, Size(9, 9), 2, 2);
	vector<Vec3f>circles;
	HoughCircles(midImage,circles, HOUGH_GRADIENT, 1.5,10,200,100,0,0);
	/*以上参数含义:第三个是检测算法,依次是:检测圆心的累加器图像的分辨率与输入图像之比的倒数、
	10表示圆心与圆心之间的最小距离、200、100分别是累加器阈值的上下限,0、0分别是圆半径的最小和最大值*/
	for (size_t i = 0;i < circles.size();i++)
	{
		Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
		int radius = cvRound(circles[i][2]);
		circle(srcImage, center,3, Scalar(0,255, 0), -1, 8, 0);//绘制圆心
		//-1表示一个实心的圆心
		circle(srcImage, center, radius, Scalar(155,50, 255), 3, 8, 0);//绘制圆的轮廓
		//3表示元的线条粗细,若是负数表示填充圆。8表示线条类型
	}
	imwrite("2.jpg",srcImage);
	imshow("效果图", srcImage);
	waitKey(0);
	return 0;
}

在这里插入图片描述
7.2.10综合示例:

#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
Mat g_srcImage, g_dstImage, g_midImage;
vector <Vec4i> g_lines;
int g_nthreshold = 100;
static void on_HoughLines(int, void*);
int main()
{
	system("color 3F");
	Mat g_srcImage = imread("tsg.jpg");
	imshow("原始图", g_srcImage);
	namedWindow("效果图", 1);
	createTrackbar("值", "效果图", &g_nthreshold, 200, on_HoughLines);
	Canny(g_srcImage, g_midImage, 50, 200, 3);
	cvtColor(g_midImage, g_dstImage, COLOR_GRAY2BGR);//为什么是转化边缘检测后的图为灰度图?
	on_HoughLines(g_nthreshold, 0);
	HoughLinesP(g_midImage, g_lines, 1, CV_PI / 180, 80, 50, 10);
	imshow("效果图", g_dstImage);
	waitKey(0);
	return 0;
}
static void on_HoughLines(int, void*)
{
	Mat dstImage = g_dstImage.clone();
	Mat midImage = g_midImage.clone();
	vector <Vec4i>mylines;
	HoughLinesP(midImage, mylines,1, CV_PI / 180, g_nthreshold + 1, 50, 10);
	for (size_t i = 0;i < mylines.size();i++)
	{
		Vec4i l = mylines[i];
		line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(23, 180, 55), 1, LINE_AA);
	}
	imshow("效果图", dstImage);
}

程序执行结果如图:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值