热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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
#include
#include
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 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 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 {
l = mylines[i];
if (((circle_center.x - 10) <&#61; l[0]) && (l[0] <&#61; (circle_center.x &#43; 10)))
if (((circle_center.y - 10) <&#61; l[1]) && (l[1] <&#61; (circle_center.y &#43; 10)))
if (((circle_center.x - circle_radius) <&#61; l[2]) && (l[2] <&#61; (circle_center.x &#43; circle_radius)))
if (((circle_center.y - circle_radius) <&#61; l[3]) && (l[3] <&#61; (circle_center.y &#43; circle_radius)))
{
//cout < // line(midd_img, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(23, 180, 55), 2, CV_AA);
cho_l &#61; 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;
}

效果图如下&#xff1a;

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


推荐阅读
  • 来自FallDream的博客,未经允许,请勿转载,谢谢。一天一套noi简直了.昨天勉强做完了noi2011今天教练又丢出来一套noi ... [详细]
  • 本文介绍了使用Python和C语言编写程序来计算一个给定数值的平方根的方法。通过迭代算法,我们能够精确地得到所需的结果。 ... [详细]
  • HDU 2537 键盘输入处理
    题目描述了一个名叫Pirates的男孩想要开发一款键盘输入软件,遇到了大小写字母判断的问题。本文提供了该问题的解决方案及实现方法。 ... [详细]
  • 个人博客:打开链接依赖倒置原则定义依赖倒置原则(DependenceInversionPrinciple,DIP)定义如下:Highlevelmo ... [详细]
  • UVa 11683: 激光雕刻技术解析
    自1958年发明以来,激光技术已在众多领域得到广泛应用,包括电子设备、医疗手术工具、武器等。本文将探讨如何使用激光技术进行材料雕刻,并通过编程解决一个具体的激光雕刻问题。 ... [详细]
  • 本文探讨了如何选择一个合适的序列化版本ID(serialVersionUID),包括使用生成器还是简单的整数,以及在不同情况下应如何处理序列化版本ID。 ... [详细]
  • 如何使用Maven将依赖插件一并打包进JAR文件
    本文详细介绍了在使用Maven构建项目时,如何将所需的依赖插件一同打包进最终的JAR文件中,以避免手动部署依赖库的麻烦。 ... [详细]
  • 题目描述:Balala Power! 时间限制:4000/2000 MS (Java/Other) 内存限制:131072/131072 K (Java/Other)。题目背景及问题描述详见正文。 ... [详细]
  • Gradle 是 Android Studio 中默认的构建工具,了解其基本配置对于开发效率的提升至关重要。本文将详细介绍如何在 Gradle 中定义和使用共享变量,以确保项目的一致性和可维护性。 ... [详细]
  • Day4今天继续复习搞基础课,加油!树形DP每一个节点都分为选和不选两种状态,选为f[i,1],不选为f[i,0]&# ... [详细]
  • 本文介绍了一种使用链剖分(Link-Cut Tree, LCT)来维护动态树结构的方法,特别是如何通过 LCT 来高效地管理子树的信息,如子树大小等。 ... [详细]
  • 本题旨在通过实现矩阵加法,加深对多维数组的理解。题目要求读取两个 n×m 的矩阵 A 和 B,并计算它们的和。 ... [详细]
  • 在学习了Splay树的基本查找功能后,可能会觉得它与普通的二叉查找树没有太大的区别,仅仅是通过splay操作减少了时间开销。然而,Splay树之所以被誉为“序列之王”,主要在于其强大的区间操作能力。 ... [详细]
  • 题目概述:Sereja 拥有一个由 n 个整数组成的数组 a1, a2, ..., an。他计划执行 m 项操作,这些操作包括更新数组中的特定元素、增加数组中所有元素的值,以及查询数组中的特定元素。 ... [详细]
  • 本文探讨了Linux环境下线程私有数据(Thread-Specific Data, TSD)的概念及其重要性,介绍了如何通过TSD技术避免多线程间全局变量冲突的问题,并提供了具体的实现方法和示例代码。 ... [详细]
author-avatar
宋羽翔-ben
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有