opencv矩形识别

2023-05-16

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>

using namespace cv;
using namespace std;

double angle(Point pt1, Point pt2, Point pt0)
{
	double dx1 = pt1.x - pt0.x;
	double dy1 = pt1.y - pt0.y;
	double dx2 = pt2.x - pt0.x;
	double dy2 = pt2.y - pt0.y;
	return (dx1*dx2 + dy1*dy2) / sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
}//勾股定理验证是否满足直角的关系

void findRectInfo(std::vector<cv::Point> rect, int *rectInfo)
{
	int x[4] = { 0 }, y[4] = { 0 };
	int maxX = 0, maxY = 0, minX = 2000, minY = 2000;
	//get the rect points
	for (int i = 0; i<4; i++)
	{
		x[i] = rect[i].x;
		y[i] = rect[i].y;

		if (maxX<x[i])
			maxX = x[i];
		if (maxY<y[i])
			maxY = y[i];
		if (minX>x[i])
			minX = x[i];
		if (minY>y[i])
			minY = y[i];
	}
	rectInfo[0] = minY;
	rectInfo[1] = minX;
	rectInfo[2] = maxY - minY;
	rectInfo[3] = maxX - minX;
	//cout << "minY=" << minY << endl;
	//cout << "minX=" << minX << endl;
	//cout << "maxY - minY=" << maxY - minY << endl;
	//cout << "maxX - minX=" << maxX - minX << endl;
	return;
}

int main()
{
	Mat src = imread("755.jpg");

	Mat binaryzation, gray, pengzhang, deaden, edge;

	Mat dst = Mat::zeros(src.size(), CV_8UC3);

	cvtColor(src, gray, CV_BGR2GRAY);

	imshow("灰度", gray);
	
	//erzhi.create(src.size(), src.type());

	threshold(gray, binaryzation, 50, 255, THRESH_BINARY);

	imshow("二值化", binaryzation);

	Mat element = getStructuringElement(0, Size(2 + 1, 2 + 1), Point(1, 1));		// 构建内核

	dilate(binaryzation, pengzhang, element, Point(-1, -1), 2);			// 膨胀2次

	imshow("膨胀", pengzhang);

	blur(pengzhang, deaden, Size(3, 3));

	imshow("降噪", deaden);

	Canny(deaden, edge, 3, 9, 3);

	imshow("轮廓", edge);

	std::vector<std::vector<Point>> contours;
	std::vector<Vec4i> hierarchy;
	findContours(edge, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
	
	RNG rng(0);

	std::vector<Point> approx;
	std::vector<std::vector<Point>> squares;

	for (int i = 0; i < contours.size(); i++)
	{
		//if (contours[i].size() < 10 || contours[i].size() > 100)
		//{
		//	continue;
		//}

		approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.02, true);


		if (approx.size() >= 4 && 
			fabs(contourArea(Mat(approx))) > 1000 &&
			isContourConvex(Mat(approx)))
		{

			printf("i = %d   %d \n", i, approx.size());

		//	double maxCosine = 0;		// 多边形逼近
		//	for (int j = 2; j < 5; j++)
		//	{
		//		double cosine = fabs(angle(approx[j % 4], approx[j - 2], approx[j - 1]));
		//		maxCosine = MAX(maxCosine, cosine);
		//	}
		//	if (maxCosine < 0.1)
		//		squares.push_back(approx);

			int tmp[4] = { 0 };
			findRectInfo(approx, tmp);

			if (tmp[2] < 15				// 过滤出自己需要的轮廓
				|| tmp[2] > 35
				|| tmp[3] < 50
				|| *tmp < 500)
			{
				continue;
			}

			printf("%d  %d  %d  %d\n", *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3));

			Scalar color = Scalar(255, 255, 255);
			drawContours(dst, contours, i, color, 2, 8, hierarchy, 0, Point(0, 0));

		}
	}

	imshow("结果", dst);

	imwrite("ab.jpg", dst);

	waitKey();

	return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

opencv矩形识别 的相关文章

随机推荐

  • C语言实现冒泡排序

    冒泡排序作为学习排序最基本的算法 xff0c 具有稳定性与实用性 下面是C语言冒泡排序的源代码 include lt stdio h gt int main void int a 10 61 6 4 3 2 7 8 9 10 1 5 int
  • ESP32(ESP-IDF)+CNC Shield+A4988控制步进电机

    陈拓 2023 04 15 2023 04 15 1 简介 在 Arduino Uno开发板 43 电机驱动扩展版CNC Shield V3 0硬件说明 https blog csdn net chentuo2000 article det
  • C语言实现快速排序算法

    快排作为公认最优秀的排序方法 xff0c 是每一个程序员都应该掌握的 xff0c 那么 xff0c 今天就由我来为大家简单讲解一下快速排序算法的代码 源代码如下 xff1a include lt stdio h gt void quicks
  • C语言实现二分查找

    相较于线性查找 xff0c 二分查找在面对大量数据时的效率更高 xff0c 但它的缺点是只能对有序数组进行查找 源代码如下 xff1a include lt stdio h gt void binarysearch int a int su
  • 约瑟夫环详解

    package newjosephu public class myfinaljosephu 你可能会说crazy 我只想说ez xff01 public static void main String args circlelinkedl
  • 01背包问题(滚动数组实现的逻辑)

    package tttest public class mybetterbag public static void main String args int weight 61 1 3 4 int bagsize 61 4 int val
  • java递归实现辗转相除法

    public static int getres int a int b if b 61 0 return getres b a b return a
  • java 线索二叉树的构建

    public class test public static void main String args Node root 61 new Node 1 Node node2 61 new Node 2 Node node3 61 new
  • VINS-Mono

    非极大值抑制 NMS算法 xff0c 思想是搜索局部最大值 xff0c 抑制非极大值 输入 xff1a 目标边界框及其对应的置信度的分列表 xff0c 设定阈值 xff0c 阈值用来删除重叠较大的边界框 IoU xff1a 两个边界框的交集
  • vtk世界坐标系与屏幕坐标系的转换

    世界坐标系 gt 屏幕坐标系 double worldCoord 3 61 100 100 20 vtkSmartPointer lt vtkCoordinate gt pCoorPress 61 vtkSmartPointer lt vt
  • VTK读取DCM保存成png

    VTK读取DCM保存成png include lt vtkSmartPointer h gt include lt vtkImageViewer2 h gt include lt vtkDICOMImageReader h gt inclu
  • 姿态矩阵与姿态向量的相互转化

    罗德里格斯公式 转轴 n 是矩阵 R 特征值 1 对应的特征向量 求解此方程 再归一化 就得到了旋转轴 CV EXPORTS W void Rodrigues InputArray src OutputArray dst OutputArr
  • 电脑连接树莓派Zero W

    电脑连接树莓派ZeroW 陈拓 2018 05 16 2018 06 09 0 概述 本位介绍两种电脑连接树莓派PiZero W的方法 xff1a l 电脑通过USB以太网连接树莓派ZeroW l 电脑通过WiFi连接树莓派ZeroW 1
  • 读取 ttf 字体文件并提取汉字轮廓

    读取 ttf 字体文件并提取汉字轮廓 ttf 免费下载 ttf 下载链接 编译安装 freetype freetype下载链接 实现效果 demo下载地址
  • CRC-16/MODBUS 校验位计算

    实验指令 xff1a 前23位表示 信息头 43 信息内容 24 xff0c 25位是待计算的校验位 26位是结束码 7E 01 00 00 01 10 02 00 27 00 0C 00 02 00 00 00 00 00 50 00 3
  • QSS之QPushButton 详细介绍

    官方参考资料 span class hljs tag QPushButton span span class hljs rules span class hljs comment 前景色 span span class hljs rule
  • bochs 详细介绍

    BOCHS 简介及配置 Bochs 简介 Bochs xff08 读音同 Box xff09 是用C 43 43 开发的以 LGPL 许可证发放的开放源代码的x86 xff0c x86 64模拟器 xff0c 模拟整个PC 它被设计成可以运
  • QT信号槽传递复杂参数

    原理 1 先将想要传递的多个数据封装成一个结构体 2 然后再用QVariant打包 3 通过信号槽机制传送 4 传到目标类后再解开QVariant的到自己想要的数据 实验目标 按下按钮后 xff0c 将界面上3个控件的值传递到Product
  • Opencv 轮廓提取

    边缘检测的一般步骤 滤波 消除噪声增强 使边界轮廓更加明显检测 选出边缘点 方法一 Canny算法 特点 xff1a 轮廓细腻 include lt opencv2 opencv hpp gt include lt opencv2 high
  • opencv矩形识别

    include lt opencv2 highgui highgui hpp gt include lt opencv2 imgproc imgproc hpp gt include lt opencv2 core core hpp gt