凸包检测、直线检测、点集拟合、二维码检测

news2024/12/26 8:38:25

目录

1、凸包检测

2、直线检测

3、点集拟合

4、二维码检测


1、凸包检测

//凸包检测
int test1()
{
	Mat img = imread("F:/testMap/hand.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	// 二值化
	Mat gray, binary;
	cvtColor(img, 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_OPEN, k);
	imshow("binary", binary);

	//轮廓发现
	vector<vector<Point>> contours;
	vector<Vec4i> hierarchy;
	findContours(binary, contours, hierarchy, 0, 2, Point());
	for (int n = 0; n < contours.size(); n++)
	{
		//计算凸包
		vector<Point> hull;
		convexHull(contours[n], hull);//绘制凸包
		for (int i = 0; i < hull.size(); i++)
		{
			//绘制凸包顶点
			circle(img, hull[i], 4, Scalar(255, 0, 0), 2, 8, 0);//连接凸包
			if (i == hull.size() - 1)
			{
				line(img, hull[i], hull[0], Scalar(0, 0, 255), 2, 8, 0);
				break;
			}
			line(img, hull[i], hull[i + 1], Scalar(0, 0, 255), 2, 8, 0);
		}
	}
	imshow("hull", img);
	waitKey(0);
	return 0;
}

2、直线检测

 

//直线检测
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;
		double 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 test2()
{
	Mat img = imread("F:/testMap/qier.png", IMREAD_GRAYSCALE);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat edge;
	//检测边缘图像,并二值化
	Canny(img, edge, 80, 180, 3, false);

	//用不同的累加器进行检测直线
	vector<Vec2f> lines1, lines2;
	HoughLines(edge, lines1, 1, CV_PI / 180, 50, 0, 0);
	HoughLines(edge, lines2, 1, CV_PI / 180, 150, 0, 0);

	//在原图像中绘制直线
	Mat img1, img2;
	img.copyTo(img1);
	img.copyTo(img2);
	drawLine(img1, lines1, edge.rows, edge.cols, Scalar(255), 2);
	drawLine(img2, lines2, edge.rows, edge.cols, Scalar(255), 2);
	
	//显示图像
	imshow("img ", img);
	waitKey(0);
	imshow("edge", edge);
	waitKey(0);
	imshow("img1", img1);
	waitKey(0);
	imshow("img2", img2);
	waitKey(0);
	return 0;
}
//渐进概率式霍夫变换
int test5()
{
	Mat img = imread("F:/testMap/qier.png", IMREAD_GRAYSCALE);
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}

	Mat edge;
	//检测边缘图像,并二值化
	Canny(img, edge, 80, 180, 3, true);
	threshold(edge, edge, 170, 255, THRESH_BINARY);

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

	//绘制两个点连接最大距离10直线检测结果
	Mat img1;
	img.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);
	}
	//绘制两个点连接最大距离30直线检测结果
	Mat img2;
	img.copyTo(img);
	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("img1", img1);
	imshow("img2", img2);
	waitKey(0);
	return 0;
}

3、点集拟合

 

 

 

//点集拟合
int test3()
{
	system("color 02");//更改输出界面颜色
	Vec4f lines;//存放拟合后的直线
	vector<Point2f> point;//待检测是否存在直线的所有点
	const static float Points[20][2] = {
		{ 0.0f, 0.0f }, { 10.0f, 11.0f }, { 21.0f, 20.0f }, { 30.0f, 30.0f },
		{ 40.0f, 42.0f }, { 50.0f, 50.0f }, { 60.0f, 60.0f }, { 70.0f, 70.0f },
		{ 80.0f, 80.0f }, { 90.0f, 92.0f }, { 100.0f, 100.0f }, { 110.0f, 110.0f },
		{ 120.0f, 120.0f }, { 136.0f, 130.0f }, { 138.0f, 140.0f }, { 150.0f, 150.0f },
		{ 160.0f, 163.0f }, { 175.0f, 170.0f }, { 181.0f, 180.0f }, { 200.0f, 190.0f } };

	//将所有点存放在vector中,用于输入函数中
	for (int i = 0; i < 20; i++)
	{
		point.push_back(Point2f(Points[i][0], Points[i][1]));
	}
	//参数设置
	double param = 0;//距离模型中的数值参数C
	double reps = 0.01;//坐标原点与直线之间的距离精度
	double aeps = 0.01;//角度精度

	fitLine(point, lines, DIST_L1, 0, 0.01, 0.01);
	double k = lines[1] / lines[0];//直线斜率
	cout << "直线斜率: " << k << endl;
	cout << "直线上一点坐标x: " << lines[2] << ", y:" << lines[3] << endl;
	cout << "直线解析式: y = " << k << "(x - " << lines[2] << ") + " << lines[3] << endl;

	waitKey(0);


	Mat img(500, 500, CV_8UC3, Scalar::all(0));
	RNG &rng = theRNG();//生成随机点
	while (true)
	{
		int i, count = rng.uniform(1, 101);
		vector<Point> points;
		//生成随机点
		for (i = 0; i < count; i++)
		{
			Point pt;
			pt.x = rng.uniform(img.cols / 4, img.cols * 3 / 4);
			pt.y = rng.uniform(img.rows / 4, img.rows * 3 / 4);
			points.push_back(pt);
		}
		//寻找包围点集的三角形
		vector<Point2f> triangle;
		double area = minEnclosingTriangle(points, triangle);

		//寻找包围点集的圆形
		Point2f center;
		float radius = 0;
		minEnclosingCircle(points, center, radius);

		//创建两个图片用于输出结果img = Scalar: :all(0);
		Mat img2;
		img.copyTo(img2);//在图像中绘制坐标点
		for (i = 0; i < count; i++)
		{
			circle(img, points[i], 3, Scalar(255, 255, 255), FILLED, LINE_AA);
			circle(img2, points[i], 3, Scalar(255, 255, 255), FILLED, LINE_AA);
		}

		//绘制三角形
		for (i = 0; i < 3; i++)
		{
			if (i == 2)
			{
				line(img, triangle[i], triangle[0], Scalar(255, 255, 255), 1, 16);
				break;
			}
			line(img, triangle[i], triangle[i + 1], Scalar(255, 255, 255), 1, 16);
		}

		//绘制圆形
		circle(img2, center, cvRound(radius), Scalar(255, 255, 255), 1, LINE_AA);
		//输出结果
		imshow("triangle", img);
		imshow("circle", img2);

		//按q键或者ESC键退出程序
		char key = (char)waitKey();
		if (key == 27 || key == 'q' || key == 'Q')
		{
			break;
		}
	}
	return 0;
}

4、二维码检测

 

 

//二维码检测
int test4()
{
	Mat img = imread("F:/testMap/erweima.png");
	if (img.empty())
	{
		cout << "请确认图像文件名称是否正确" << endl;
		return -1;
	}
	Mat gray, qrcode_bin;
	cvtColor(img, gray, COLOR_BGR2GRAY);
	QRCodeDetector qrcodedetector;
	vector<Point> points;
	string information;
	bool isQRcode;
	isQRcode = qrcodedetector.detect(gray, points);//识别二维码
	if (isQRcode)
	{
		//解码二维码
		information = qrcodedetector.decode(gray, points, qrcode_bin);
		cout << points << endl;//输出二维码四个顶点的坐标
	}
	else
	{
		cout << "无法识别二维码,请确认图像时候含有二维码" << endl;
		return -1;
	}

	//绘制二维码的边框
	for (int i = 0; i < points.size(); i++)
	{
		if (i == points.size() - 1)
		{
			line(img, points[i], points[0], Scalar(0, 0, 255), 2, 8);
			break;
		}
		line(img, points[i], points[i + 1], Scalar(0, 0, 255), 2, 8);
	}

	//将解码内容输出到图片上
	putText(img, information.c_str(), Point(20, 30), 0, 1.0, Scalar(0, 0, 255), 2, 8);
	
	//利用函数直接定位二维码并解码
	string information2;
	vector<Point> points2;
	information2 = qrcodedetector.detectAndDecode(gray, points2);
	cout << points2 << endl;
	putText(img, information2.c_str(), Point(20, 55), 0, 1.0, Scalar(0, 0, 0), 2, 8);
	
	//输出结果
	namedWindow("result", WINDOW_NORMAL);
	imshow("result", img);
	namedWindow("qrcode_bin", WINDOW_NORMAL);
	imshow("qrcode_bin", qrcode_bin);

	waitKey(0);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/747339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Splashtop 亮相上安会,助力企业安全远程办公

2023年7月5-7日&#xff0c;2023第二届上海网络安全博览会暨高峰论坛在上海新国际博览中心举办。 本届上安会由上海市信息网络安全管理协会等单位主办&#xff0c;上海科学院、上海汽车集团等机构联合协办。大会围绕数字发展主题&#xff0c;多方位展示了网络安全行业的最新发…

SQL性能规范

一、随聊 记录一下吧&#xff0c;2023年7月13日00:11:11&#xff0c;现在的状态真的很&#xff0c;忙&#xff0c;干不完的活&#xff0c;希望巨大的压力&#xff0c;能够让自己快速成长&#xff0c;回想我这一路&#xff0c;21年大专毕业&#xff0c;用一年时间熟悉软件&…

JDK的安装与配置

所有的开发&#xff0c;第一步必然是准备环境&#xff0c;而JDK提供了一套完整的工具和环境&#xff0c;使开发人员能够编写、编译和运行Java应用程序。是Java开发的基础&#xff0c;为开发者提供了丰富的功能和工具&#xff0c;简化了Java应用程序开发的过程。所以这里就记录一…

C++教程——vector容器、deque容器、stack容器、queue容器、list容器、set容器、map容器

vector容器 基本概念 vector赋值操作 vector容量和大小 vector插入与删除 vector数据存取 vector互换容器 vector预留空间&#xff1a;减少开辟内存空间的次数 deque容器 deque构造函数 deque赋值方式 deque大小操作 deque插入和删除 deque数据存取 deque排序 stack容器 stack…

iOS开发 - 系统自带框架实现扫一扫功能

iOS 扫一扫 利用系统自带框架实现扫一扫功能 一 项目配置 扫一扫功能相机和相册权限&#xff0c;在info.plist中设置询问用户是否允许访问的权限。 info.plist加入NSCameraUsageDescription、NSPhotoLibraryUsageDescription、NSPhotoLibraryAddUsageDescription <key&g…

java.lang.UnsatisfiedLinkError: Could not load SWT library.

java.lang.UnsatisfiedLinkError: Could not load SWT library. https://download.eclipse.org/windowbuilder/lastgoodbuild

力扣206. 反转链表

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 链接&#xff1a;206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 题解 方法一&#xff1a;类似头插法 设置3个指针cur、next、newhead&#xff0c;其中cur和next指向当前链表头…

Kubernetes基础知识点

k8s可以看做是一个集群操作系统&#xff0c;能够对容器进行调度和编排。 Kubernetes中的基本对象 pod 是k8s中的最小单位&#xff0c;一个pod封装一个或者多个容器&#xff0c;存储资源。 deployment 是对pod的服务化封装&#xff0c;可以包含一个或多个pod statefulset 为…

ArcGIS处理nc数据步骤

降水温度蒸散发等气象数据通常以NC格式存储&#xff0c;可以用Matlab和ArcGIS读取数据。常为逐年逐月逐日数据。在用GIS进行数据分析时&#xff0c;需要将其转换为栅格数据。 &#xff08;1&#xff09;打开nc数据。打开GIS, ArcToolbox-Multidimension Tools-Make NetCDF Rast…

多线程高频知识点—2023

多线程高频知识点—2023 多线程的基本概念什么是线程/进程为什么在进程中还需要线程呢&#xff1f;同步与异步的区别程序计数器多线程的应用场景多线程的创建方式手写一个异步日志框架多线程线程安全问题 多线程的基本概念 什么是cpu CPU的中文名称是中央处理器&#xff0c;是…

【优选算法】—— 滑动窗口类问题

本期&#xff0c;我给大家带来的是关于滑动窗口类算法的介绍&#xff0c;并通过具体的题目帮助大家思考理解。 目录 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;题目讲解 1、难度&#xff1a;medium 1️⃣长度最小的子数组 2️⃣找到字符串中所有字⺟…

Xcode 更新后 Version 14.3.1报错

File not found: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a Xode版本和pod版本不一致导致&#xff0c;改成一致就可以了 放在podfile文件里,最后一个pod,和最后一个end中间 Showing Recent …

将字符串转换为字典json.loads(字符串)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 将字符串转换为字典 json.loads(字符串) [太阳]选择题 关于以下代码说法错误的是? import json myStr{"name":"xiaobai","age":30} print(【显示】mySt…

【论文阅读】TransCAM: Transformer Attention-based CAM Refinement for WSSS

分享一篇阅读的用于弱监督分割的论文 论文标题&#xff1a; TransCAM: Transformer Attention-based CAM Refinement for Weakly Supervised Semantic Segmentation 作者信息&#xff1a; 代码地址&#xff1a; https://github.com/liruiwen/TransCAM Abstract 大多数现有…

java判断某个字符串是否在字符串数组中的方法(4种)

1.效率最高&#xff08;最原始&#xff09; 代码如下&#xff08;示例&#xff09;&#xff1a; public class Demo { public static boolean useLoop(String[] arr, String targetValue) { for (String s : arr) { if (s.equals(targetValue)) return true; } return false; }…

图像分类——模型微调

目录 微调热狗识别获取数据集模型构建与训练 微调 热狗识别 获取数据集 import tensorflow as tf import pathlibtraindirhotdog/train testdirhotdog/test image_gentf.keras.preprocessing.image.ImageDataGenerator(rescale1/255) train_data_genimage_gen.flow_from_direc…

2023年Q2空调行业品牌数据榜单(京东商品数据)

随着夏季的来临&#xff0c;高温天气也带动部分家电行业的销售&#xff0c;以空调为代表的家电市场正逐步恢复活力。结合鲸参谋电商数据分析平台的相关数据&#xff0c;我们来分析一下2023年Q2空调市场的具体销售表现。 根据鲸参谋平台的数据显示&#xff0c;2023年4-6月份&am…

TypeScript学习(2)- ts基本类型

类型声明式Ts非常重要的一个特点&#xff0c;通过类型声明可以指定TS中变量&#xff08;参数&#xff0c;形参&#xff09;的类型。指定类型后&#xff0c;当为变量赋值时&#xff0c;ts编译器会自动检查值是否符合类型声明&#xff0c;符合则赋值&#xff0c;否则报错。 目录 …

从VAE到Diffusion生成模型详解(1):VAE

文章目录 1. 生成式模型简介2. PixelRNN/CNN3. VAE3.1 自编码器AE3.2 VAE基本原理3.3 VAE公式推导 4. 参考 1. 生成式模型简介 什么是生成式模型 给定训练集&#xff0c;产生与训练集同分布的新样本。如下图所示&#xff0c;希望学习到一个模型 p m o d e l ( x ) p_{model}(…

22 分页控件

文章目录 界面设置初始化主对话框子页面初始化 页面1枚举窗口页面2枚举进程全部代码 界面设置 ui 设置 >创建CTablCtrl > 创建页控件&#xff08;子窗口&#xff09;&#xff0c;style设置成为chlid 添加类 页面中加入listCtrl 控件 添加变量 分别添加初始化函数 初始化…