opencv_c++学习(二十二)

这篇具有很好参考价值的文章主要介绍了opencv_c++学习(二十二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、凸包检测

opencv_c++学习(二十二)
图中左侧为边缘检测的效果,中间为图像经过二值化的效果,右图为凸包检测效果。

convexHull(lnputArraypoints, OutputArray hull,bool clockwise = false, bool returnPoints = true)

points:输入的2D点集。
hull:输出凸包的顶点。
clockwise:方向标志,当参数为true时,凸包顺序为顺时针方向,否则为逆时针方向。
returnPoints:输出数据的类型标志,当参数为true时第二个参数输出的结果是凸包顶点的坐标,否则第二个参数输出的结果是凸包顶点的索引。
这里的计算实例如下:

int main() {

	//读取图片
	Mat src = imread("图片1.png");
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	Mat gray, binary;
	//转化为灰度图
	cvtColor(src, gray, COLOR_BGR2GRAY);
	//二值化
	threshold(gray, binary, 105, 255, THRESH_BINARY);

	//开运算去除细小区域
	Mat k = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));
	morphologyEx(binary, binary, MORPH_RECT, k);

	//轮廓检测
	vector<vector<Point>>contours;
	//存放轮廓结构变量
	vector<Vec4i>hierarchy;

	findContours(binary, contours, hierarchy, 0, 2, Point());

	for (int i = 0; i < contours.size(); i++)
	{
		//计算凸包
		vector<Point>hull;
		convexHull(contours[i], hull);

		//绘制凸包
		for (int j = 0; j < hull.size(); j++)
		{
			//绘制凸包顶点
			circle(src, hull[j], 4, Scalar(255, 0, 0), 2, 8, 0);
			//连接凸包
			//将起始点与终点相连
			if (j == hull.size()-1)
			{
				line(src, hull[j], hull[0], Scalar(0, 0, 255), 2, 8, 0);
				break;
			}
			line(src, hull[j], hull[j+1], Scalar(0, 0, 255), 2, 8, 0);
		}
	}

	imshow("q", src);

	waitKey(0);
	return 0;
}

二、直线检测

检测直线的霍夫变换原理:
opencv_c++学习(二十二)
先看左上角的图像,图中我们可以看出三条直线都经过了一个点。这里我们可以将y=kx+b一个函数描述这三条直线。由于都经过一个点,所以(x,y)的参数是固定的,右上角的图像为k、b的参数空间。也就是说参数空间中的每一个点都可以描述原空间的每一条直线。
opencv_c++学习(二十二)
上图中左上方图片可以看出,这三个点绘制成的直线没有斜率k,因此不能在参数空间上表示该直线。这时我们可以采用上图中的下部分的方法:可以用直线到坐标原点的距离,以及垂线与x轴的夹角来表示这一直线。
检测直线过程:
opencv_c++学习(二十二)
标准霍夫变换函数:

HoughLines(IlnputArray image, OutputArray lines,double rho, double theta, int threshold, double srn = 0, double stn = 0, double min_theta = 0, double max_theta = cv_PI)

image:目标图像。
lines: 检测直线的输出量。
rho:离散化后的单位长度。
theta:离散化后的单位角度。
threshold:步骤三中的阈值。
srn、stn:当两参数为0时,则为标准的霍夫变换,不为零则为多尺度霍夫变换。
min_theta、max_theta:角度最大最小值。
渐进概率式霍夫变换:

HoughllLinesP(InputArrayimage, OutputArray lines, double rho, double theta, int threshold, minLineLength =, void cv=HoughllLinesP( InputArrayimage, OutputArray lines.double 0, double maxLineGap = 0)

image:待检测直线的原图像,必须是CV_8C的单通道二值图像。
lines:霍夫变换检测到的直线输出量,每一条直线都由4个参数进行描述,分别是直线两个端点的坐标rho:以像素为单位的距离分辨率。
theta:以弧度为单位的角度分辨率。
threshold:累加器的阈值。
minLineLength:直线的最小长度,当检测直线的长度小于该数值时将会被剔除。
maxLineGap:允许将同一行两个点连接起来的最大距离。
标准霍夫变换应用案例:

void drawLine(Mat &img,  //原图像
	vector<Vec2f> lines, //检测的直线数据
	double rows, //原图的行数
	double cols,//原图的列数
	Scalar scalar, //绘制直线的颜色
	int n //绘制直线的线宽
	)
{
	Point pt1, pt2;
	for (size_t i = 0; i < lines.size(); i++)
	{
		float rho = lines[i][0]; //直线距离坐标原点的距离
		float theta = lines[i][1]; //直线过坐标原点垂线与x轴的夹角
		double a = cos(theta); //夹角的余弦值
		double b = sin(theta);//夹角的正弦值
		double x0 = a * rho, y0 = b * rho;//直角与过坐标原点的垂线交点
		double length = max(rows, cols); //  图像高度的最大值、计算直线上的一点

		pt1.x = cvRound(x0 + length * (-b));
		pt1.y = cvRound(y0 + length * (a));

		//计算直线上另一点
		pt2.x = cvRound(x0 - length * (-b));
		pt2.y = cvRound(y0 - length * (a));
		//两点绘制一条直线
		line(img, pt1, pt2, scalar, n);
	}


}

int main() {

	//以灰度图形式读取图片
	Mat src = imread("2.jpg", IMREAD_GRAYSCALE);
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//检测边缘图像,并二值化
	Mat edge;
	Canny(src, edge, 80, 180, 3, false);
	//进行二值化操作
	threshold(edge, edge, 170, 255, THRESH_BINARY);

	//使用累加器检测直线
	vector<Vec2f> line1, line2;
	HoughLines(edge, line1, 1, CV_PI / 180, 50, 0, 0);
	HoughLines(edge, line2, 1, CV_PI / 180, 150, 0, 0);

	//在原图中绘制直线
	Mat img1, img2;
	//深拷贝出两个原图像,对比两个变换的结果
	src.copyTo(img1);
	src.copyTo(img2);

	//绘制图像
	drawLine(img1, line1, edge.rows, edge.cols, Scalar(255), 2);
	drawLine(img2, line2, edge.rows, edge.cols, Scalar(255), 2);

	imshow("a", img1);
	imshow("b", img2);
	imshow("c", edge);
	waitKey(0);
	return 0;
}

运行上述的代码可以显示出如下三个图片:
边缘检测效果:
opencv_c++学习(二十二)
阈值较大的显示效果:
opencv_c++学习(二十二)
阈值较小的显示效果:
opencv_c++学习(二十二)
渐进概率霍夫变换应用案例:文章来源地址https://www.toymoban.com/news/detail-459719.html

int main() {

	//以灰度图形式读取图片
	Mat src = imread("2.jpg", IMREAD_GRAYSCALE);
	if (src.empty())
	{
		printf("不能打开空图片");
		return -1;
	}

	//检测边缘图像,并二值化
	Mat edge;
	Canny(src, edge, 80, 180, 3, false);

	//使用渐进式霍夫变换提取直线
	vector<Vec4i> linesP1, linesP2;
	//两个点连接最大距离10
	HoughLinesP(edge, linesP1, 1, CV_PI / 180, 150, 30, 10);
	//两个点连接最大距离30
	HoughLinesP(edge, linesP2, 1, CV_PI / 180, 150, 30, 30);

	//分别绘制两个不同阈值的直线
	Mat img1;
	src.copyTo(img1);
	for (size_t i = 0; i < linesP1.size(); i++)
	{
		line(img1, Point(linesP1[i][0], linesP1[i][1]), Point(linesP1[i][2], linesP1[i][3]), Scalar(255), 3);
	}

	imshow("q", img1);

	Mat img2;
	src.copyTo(img2);
	for (size_t i = 0; i < linesP2.size(); i++)
	{
		line(img2, Point(linesP2[i][0], linesP2[i][1]), Point(linesP2[i][2], linesP2[i][3]), Scalar(255), 3);
	}

	imshow("q", img1);
	imshow("w", img2);

	waitKey(0);
	return 0;
}

到了这里,关于opencv_c++学习(二十二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • opencv_c++学习(二十七)

    上图为针孔相机成像原理,蓝色坐标中的O即为镜头光心。成像原理与小孔成像相同。 单目相机映射关系如下: 将上式进行变换,就可以从三位空间映射到2维平面的公式。 相机的畸变公式如下: objectPoints:世界坐标系中3D点的三维坐标。 rvec:世界坐标系变换到相机坐标系的旋

    2024年02月06日
    浏览(53)
  • 数字图像处理(实践篇)二十二 使用opencv进行人脸、眼睛、嘴的检测

    目录 1 xml文件 2 涉及的函数 3 实践 使用opencv进行人脸、眼睛、嘴的检测。 1 xml文件 方法① 下载  地址:https://github.com/opencv/opencv/tree/master/data/haarcascades 点击haarcascade_frontalface_default.xml文件 对着Raw右键,选择“链接另存为”,选择代码所在的路径即可,就可以下载这个文件啦

    2024年02月03日
    浏览(48)
  • opencv 凸包检测 convexHull

    2024年02月12日
    浏览(38)
  • OpenCV(三十五):凸包检测

    1.凸包检测介绍       凸包检测是计算凸包的一种技术,凸包就是:给定二维平面上的点集,将最外层的点连接起来构成的凸边形,它是包含点集中所有的点。 2.凸包检测函数convexHull() void cv::convexHull ( InputArray  points, OutputArray hull, boolclockwise = false, bool   returnPoints = true ) p

    2024年02月09日
    浏览(40)
  • Python Opencv实践 - 凸包检测(ConvexHull)

       

    2024年02月10日
    浏览(45)
  • 【AI】《动手学-深度学习-PyTorch版》笔记(二十二):单发多框检测(SSD)

    SSD(Single Shot MultiBox Detector)单发多框检测。“Single shot”说明SSD算法属于one-stage(一段式)方法,“MultiBox”说明SSD是多框预测(多尺度锚框/特征图)。 SSD和YOLO一样都是采用CNN网络执行one-stage(一段式)检测,区别是: YOLO速度快,适用于实时物体检测;但是精度略低,尤

    2024年02月09日
    浏览(42)
  • opencv_c++学习(三)

    CV Assert(mylmage.depth() == CV 8U); CV_Assert()函数判断图像数据的类型是否为uchar类型,不满足则抛出异常。 Mat.ptr(int i=0)获取像素矩阵的指针,索引i表示第几行,从0开始计行数。 Mat.ptr(int i=0)获取像素矩阵的指针,索引i表示第几行,从0开始计行数。 获取当前像素点P(row, col)的像素值

    2024年02月03日
    浏览(33)
  • opencv_c++学习(六)

    对以上实例解释如下: 若读取的为本地视频,则filename为视频名称,若读取的是摄像头数据,则为int类型的摄像头id。 视频属性可以通过get()函数获取。 见文末案例 对以上实例进行解释: filename:保存视频的地址和文件名,包含视频格式; fourcc:压缩帧的4字符编解码器代码,

    2024年02月03日
    浏览(37)
  • opencv_c++学习(十三)

    trackbarname:滑动条的名称。 winname:创建滑动条窗口的名称。 value:指向整数变量的指针,该指针指向的值反映滑块的位置,创建后,滑块位置由此变量定义。 count:滑动条的最大取值。 onChange:每次滑块更改位置时要调用的函数的指针。该函数应该原型为void Foo (int,void *) ;,其中

    2024年02月05日
    浏览(87)
  • opencv_c++学习(三十)

    model:模型文件名称 config:配置文件名称 framework:框架种类 Net类中的函数名称以及作用: 向网络层中添加数据: blob:新的输入数据,数据类型为CV_32F或CV_8U。 name:输入网络层的名称。 scalefactor:可选的标准化比例(尺寸缩放)。 mean:可选的减数数值(平移)。 opencv调用深度学习模

    2024年02月06日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包