【OpenCV】用C++实现的直线卡尺工具

前言

在OpenCV中,查找直线是经常需要用到的功能,故此用C++实现了一个寻找直线的卡尺工具。

一、卡尺工具的原理

卡尺工具的原理是基于图像边缘检测的方法,用于测量图像中的线段长度和角度。它通过在图像中选择两个点,然后沿着直线方向上的像素进行采样,通过计算采样点的像素值,可以得到线段的长度和角度等信息

二、卡尺工具的C++实现

#include <opencv2/opencv.hpp>

using namespace cv;
void DetectLines(cv::Mat srcImage, cv::Rect rect, int searchFlag, int maxGrad, int thresholdValue, bool isErode, int kernelSize, cv::Point& p1, cv::Point& p2)  //二值化直线拟合检测
{
	if (srcImage.channels() == 3)
		cv::cvtColor(srcImage, srcImage, cv::COLOR_BGR2GRAY);
	cv::Mat m_resultImg = srcImage(rect).clone();
	threshold(m_resultImg, m_resultImg, thresholdValue, 255, THRESH_BINARY);

	if (isErode)
	{
		Mat element = getStructuringElement(0, Size(kernelSize, kernelSize), Point(-1, -1));
		erode(m_resultImg, m_resultImg, element);  //腐蚀操作	
	}
	std::vector<Point2f> onefitlinepoints;
	switch (searchFlag)
	{
	case 0:
	{
		//从左到右查找
		for (int y = 0; y < m_resultImg.rows; y++)
		{
			for (int x = 0; x < m_resultImg.cols; x++)
			{
				if ((int)m_resultImg.at<uchar>(y, x) == maxGrad)
				{
					onefitlinepoints.push_back(Point(y, x));
					break; 
				}
			}
		}
		break;
	}
	case 1:
	{
		//从右到左查找
		for (int y = m_resultImg.rows - 1; y > 0; y--)
		{
			for (int x = m_resultImg.cols - 1; x > 0; x--)
			{
				if ((int)m_resultImg.at<uchar>(y, x) == maxGrad)
				{
					onefitlinepoints.push_back(Point(y, x));
					break;
				}
			}
		}
		break;
	}
	case 2:
	{
		//从上到下查找
		for (int x = m_resultImg.cols - 1; x > 0; x--)
		{
			for (int y = 0; y < m_resultImg.rows; y++)
			{
				if ((int)m_resultImg.at<uchar>(y, x) == maxGrad)
				{
					onefitlinepoints.push_back(Point(x, y));
					break;
				}
			}
		}
		break;
	}
	case 3:
	{
		//从下到上查找
		for (int x = m_resultImg.cols - 1; x > 0; x--)
		{
			for (int y = m_resultImg.rows - 1; y > 0; y--)
			{
				if ((int)m_resultImg.at<uchar>(y, x) == maxGrad)
				{
					onefitlinepoints.push_back(Point(x, y));
					break;
				}
			}
		}
		break;
	}
	}
	Vec4f oneline;
	cv::fitLine(onefitlinepoints, oneline, cv::DIST_L1, 0, 0.01, 0.01);   //根据给定的点集(比如轮廓)拟合出一条直线	

	Point2f  point1, point2, point3;
	
	point2.x = oneline[2];
	point2.y = oneline[3];

	double k = oneline[1] / oneline[0];

	从左到右或从右到左
	if (searchFlag == 1 || searchFlag == 0)
	{
		point1.y = rect.y;
		point1.x = (k * (0 - point2.x) + point2.y) + rect.x;
		point3.y = rect.y + rect.height;
		point3.x = (k * (m_resultImg.rows - point2.x) + point2.y) + rect.x;
	}
	/从下到上或从上到下
	else if (searchFlag == 3 || searchFlag == 2)
	{
		point1.x = rect.x;
		point1.y = (k * (0 - point2.x) + point2.y) + rect.y;
		point3.x = rect.x + rect.width;
		point3.y = (k * (m_resultImg.cols - point2.x) + point2.y) + rect.y;
	}
	
	p1 = point1;
	p2 = point3;
	cv::cvtColor(srcImage, srcImage, COLOR_GRAY2RGB);
	cv::line(srcImage, point1, point3, cv::Scalar(0, 0, 255), 5, 1, 0);
	rectangle(srcImage, rect, Scalar(0, 255, 0), 5, 8, 0);  //根据初始点和结束点,将矩形画到img上
	cv::imwrite("./Datas/detectedLine.png", srcImage);
}

int main()
{
	cv::Mat src = cv::imread("./Datas/1.png", 0);
	cv::Rect rect(0, 0, src.cols, src.rows);
	cv::Point p1, p2;
	DetectLines(src, rect, 2, 0, 70, true, 3, p1, p2);
	system("pause");
	return 0;
}

三、 测试结果

原图
在这里插入图片描述
结果图片
在这里插入图片描述

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Halcon卡尺工具是机器视觉中常用的工具之一,而OpenCV也是常用的计算机视觉库。下面简单介绍如何在C++中使用OpenCV实现Halcon卡尺工具。 1. 首先,需要导入OpenCV头文件: ``` #include <opencv2/opencv.hpp> ``` 2. 接下来,需要读取图像并将其转换为灰度图像: ``` cv::Mat srcImg = cv::imread("image.jpg"); cv::Mat grayImg; cv::cvtColor(srcImg, grayImg, cv::COLOR_BGR2GRAY); ``` 3. 然后,需要定义卡尺工具的参数。Halcon卡尺工具主要包括起点、方向、长度、宽度等参数。在OpenCV中,可以通过定义两个点来表示起点和终点,并通过一些数值来定义卡尺工具的其他参数: ``` cv::Point2f startPoint(100, 100); cv::Point2f endPoint(300, 300); int length = 200; int width = 10; ``` 4. 接下来,可以利用OpenCV的线段函数画出卡尺工具: ``` cv::line(srcImg, startPoint, endPoint, cv::Scalar(0, 0, 255), width); ``` 5. 最后,可以使用OpenCV的几何变换函数进行卡尺工具的旋转和缩放: ``` cv::Point2f center(startPoint.x + length / 2, startPoint.y + width / 2); double angle = 45; double scale = 0.5; cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, scale); cv::warpAffine(srcImg, srcImg, rotationMatrix, srcImg.size()); ``` 这样,就可以在OpenCV实现Halcon卡尺工具了。完整代码如下: ``` #include <opencv2/opencv.hpp> int main() { cv::Mat srcImg = cv::imread("image.jpg"); cv::Mat grayImg; cv::cvtColor(srcImg, grayImg, cv::COLOR_BGR2GRAY); cv::Point2f startPoint(100, 100); cv::Point2f endPoint(300, 300); int length = 200; int width = 10; cv::line(srcImg, startPoint, endPoint, cv::Scalar(0, 0, 255), width); cv::Point2f center(startPoint.x + length / 2, startPoint.y + width / 2); double angle = 45; double scale = 0.5; cv::Mat rotationMatrix = cv::getRotationMatrix2D(center, angle, scale); cv::warpAffine(srcImg, srcImg, rotationMatrix, srcImg.size()); cv::imshow("result", srcImg); cv::waitKey(); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shanhedian2013

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值