OpenCV 指针仪表盘参数读取(四) 指针定位

这一节是此方案设计的最核心部分,指针能否准确的定位出来是最关键的问题,在学习过程中,初步采用几种方案来尽可能的提高指针定位的精度:

1.指针定位的方案: Hough直线检测 环向模板匹配法 径向灰度求和法

2.指针细化的方法(算法将放在文章最后提供测试与使用)

对于指针定位,初步的设计思路是采用Hough直线检测的方法,而后通过直线上的点与圆的关系来将错误检测的直线进行过滤,此方案的难点在于Hough直线检测的方法经常与Canny边缘检测算子进行联合使用,而Canny算子的阈值选择以及Hough直线的长度选择都是比较动态的过程,在调节过程非常困难,本文采用可以连续调节Canny算子和Hough检测阈值的方法,来选择适合于方案的值,初步测试有较好的效果。

函数使用如下:

// HoughLine
midd_line_img = HoughLine(midd_img, midd_line_img);

OpenCV中的函数封装为:

// CannyDetect
Canny(gray_img, midd_line_img, 23, 55, 3);
// HoughLine
HoughLinesP(midd_line_img, mylines, 1, CV_PI / 180, g_nthreshold + 1, 20, 5);

采用的可以调节的Canny算子的程序及效果图如下:

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

using namespace std;
using namespace cv;

// Define the Mat parameters
Mat g_srcImage, g_dstImage, g_midImage;
// Define a vector to collect all detected lines
vector<Vec4i> g_lines;
int g_nthreshold = 100;

static void showImage1(int, void*);
static void showImage2(int, void*);
int thred1 = 23;
int thred2 = 55;
// 23 55
int main()
{
	// Load origin image   
	g_srcImage = imread("12.jpg", 0);
	// Show origin image
	namedWindow("Dst Image", 1);
	imshow("Origin Image", g_srcImage);
	// Create a Tracebar
	createTrackbar("threshold1", "Dst Image", &thred1, 200, showImage1);
	createTrackbar("threshold2", "Dst Image", &thred2, 200, showImage2);
	// Canny Detect and Gray am image  
	Canny(g_srcImage, g_midImage, thred1, thred2, 3);
	cvtColor(g_midImage, g_dstImage, CV_GRAY2BGR);
	showImage1(thred1, 0);
	showImage2(thred2, 0);
	// Show the dst image
	imshow("Dst Image", g_dstImage);
	waitKey(0);
	return 0;
}

static void showImage1(int thred1, void*) {
	// Canny Detection
	Canny(g_srcImage, g_midImage, thred1, thred2, 3);
	imshow("Dst Image", g_midImage);
}

static void showImage2(int thred2, void*) {
	// Canny Detection
	Canny(g_srcImage, g_midImage, thred1, thred2, 3); 
	imshow("Dst Image", g_midImage);
}

效果图:

原图:

适宜的阈值选择:

不适宜的阈值选择:已经将指针直线湮没

同理,HoughLine方法的总体方案如下:

Mat HoughLine(Mat midd_img, Mat midd_line_img) {
	
	Mat dst_img, gray_img;

	cvtColor(midd_img, gray_img, COLOR_BGR2GRAY);

	// CannyDetect
	Canny(gray_img, midd_line_img, 23, 55, 3);

	// convert cannied image to a gray one  
	cvtColor(midd_line_img, dst_img, CV_GRAY2BGR);

	// define a vector to collect all possible lines 
	vector<Vec4i> mylines;
	int g_nthreshold = 39;
	HoughLinesP(midd_line_img, mylines, 1, CV_PI / 180, g_nthreshold + 1, 20, 5);

	// draw every line by using for
	for (size_t i = 0; i < mylines.size(); i++)
	{
		l = mylines[i];
		if (((circle_center.x - 10) <= l[0]) && (l[0] <= (circle_center.x + 10)))
			if (((circle_center.y - 10) <= l[1]) && (l[1] <= (circle_center.y + 10)))
				if (((circle_center.x - circle_radius) <= l[2]) && (l[2] <= (circle_center.x + circle_radius)))
					if (((circle_center.y - circle_radius) <= l[3]) && (l[3] <= (circle_center.y + circle_radius)))
					{
						//cout << Point(l[0], l[1]) << " " << Point(l[2], l[3]) << " " << l[0] << " " << circle_center.x - circle_radius << " " << circle_center.x + circle_radius << endl;
						// line(midd_img, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(23, 180, 55), 2, CV_AA);
						cho_l = l;
						line(midd_img, Point(circle_center.x, circle_center.y), Point(cho_l[2], cho_l[3]), Scalar(23, 180, 55), 2, CV_AA);
					}
	}

	return midd_img;
}

效果图如下:

欢迎评论文章,给予宝贵建议,工程提供在github下载学习,请关注作者,共同学习交流。

OpenCV是一个强大的计算机视觉库,可以用于图像处理和分析。要使用指针仪表盘读取功能,需要以下步骤: 1. 加载图像:使用OpenCV函数读取仪表盘图像并将其存储为Mat对象。 2. 预处理图像:使用图像处理技术,如灰度转换、平滑和二值化,以便更好地识别仪表盘指针。 3. 检测指针:使用霍夫变换检测仪表盘指针。这将返回指针的位置和角度。 4. 计算度数:根据指针的位置和角度计算出指针所指示的度数。 下面是一个使用OpenCV进行指针仪表盘读取的示例代码: ```python import cv2 import math # 读取图像 img = cv2.imread('dashboard.jpg') # 灰度转换 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 平滑处理 blur = cv2.GaussianBlur(gray, (5, 5), 0) # 二值化 ret, thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU) # 检测圆形轮廓 circles = cv2.HoughCircles(thresh, cv2.HOUGH_GRADIENT, 1, 20, param1=50, param2=30, minRadius=0, maxRadius=0) # 获取圆形轮廓 if circles is not None: circles = np.round(circles[0, :]).astype('int') for (x, y, r) in circles: # 绘制圆形轮廓 cv2.circle(img, (x, y), r, (0, 255, 0), 2) # 获取指针位置 pointer_x = int(x + r * math.cos(math.radians(-90))) pointer_y = int(y - r * math.sin(math.radians(-90))) # 绘制指针 cv2.line(img, (x, y), (pointer_x, pointer_y), (0, 0, 255), 2) # 计算度数 degree = int((math.atan2(y - pointer_y, pointer_x - x) * 180 / math.pi) + 180) print('degree:', degree) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个示例中,我们首先读取指针仪表盘的图像,然后使用OpenCV函数对其进行了预处理和检测。最后,我们计算了指针所指示的度数,并将其打印出来。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值