论文复现_显示屏装配尺寸测量
读到一篇关于显示屏装配尺寸测量的文献,感谢肖敏同学的思路,若侵权请联系作者删除。
该文献利用霍夫变换对边缘直线进行粗定位, 并依次找到直线边缘附近的所有点集, 利用最小二乘法进行拟合, 精确地检测出图像中的直线边缘,由此计算出液晶显示区域和外壳之间的距离。
步骤:
- 图像预处理;
- canny算子提取显示区域和外壳的边缘;
- 霍夫直线检测粗定位,获取直线极坐标参数,由此筛选实际边缘线,计算直线点坐标;
- 最小二乘法拟合直线点。
- 通过点到直线的距离求平均,提高测量准确度和精度。
重点记录:
1、霍夫直线检测
OpenCV提供了两个函数用于直线提取,HoughLines()函数输出直线极坐标参数,HoughLinesP()函数输出直线端点坐标。
C++: void HoughLines(InputArray image, OutputArray lines,
double rho, double theta, int threshold, double srn=0,
double stn=0, double min_theta = 0, double max_theta = CV_PI )
第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
第二个参数,OutputArray 类型的lines,经过调用HoughLines函数后储存了霍夫线变换检测到线条的输出矢量。每一条线由具有两个元素的矢量表示,其中,是离坐标原点((0,0)(也就是图像的左上角)的距离。 是弧度线条旋转角度(0垂直线,π/2水平线)。
第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。PS:Latex中/rho就表示 。
第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。
第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数,double类型的srn,有默认值0。对于多尺度的霍夫变换,这是第三个参数进步尺寸rho的除数距离。粗略的累加器进步尺寸直接是第三个参数rho,而精确的累加器进步尺寸为rho/srn。
第七个参数,double类型的stn,有默认值0,对于多尺度霍夫变换,srn表示第四个参数进步尺寸的单位角度theta的除数距离。且如果srn和stn同时为0,就表示使用经典的霍夫变换。否则,这两个参数应该都为正数。
第八个参数,double类型的 min_theta,对于标准和多尺度Hough变换,检查线条的最小角度。必须介于0和max_theta之间。
第九个参数,double类型的 max_theta, 对于标准和多尺度Hough变换,检查线条的最大角度。必须介于min_theta和CV_PI之间.
C++: void HoughLinesP(InputArray image, OutputArray lines,
double rho, double theta, int threshold,
double minLineLength=0, double maxLineGap=0 )
第一个参数,InputArray类型的image,输入图像,即源图像,需为8位的单通道二进制图像,可以将任意的源图载入进来后由函数修改成此格式后,再填在这里。
第二个参数,OutputArray 类型的lines,经过调用HoughLinesP函数后后存储了检测到的线条的输出矢量,每一条线由具有四个元素的矢量(x_1,y_1, x_2, y_2) 表示,其中,(x_1, y_1)和(x_2, y_2) 是是每个检测到的线段的结束点。
第三个参数,double类型的rho,以像素为单位的距离精度。另一种形容方式是直线搜索时的进步尺寸的单位半径。
第四个参数,double类型的theta,以弧度为单位的角度精度。另一种形容方式是直线搜索时的进步尺寸的单位角度。
第五个参数,int类型的threshold,累加平面的阈值参数,即识别某部分为图中的一条直线时它在累加平面中必须达到的值。大于阈值threshold的线段才可以被检测通过并返回到结果中。
第六个参数,double类型的minLineLength,有默认值0,表示最低线段的长度,比这个设定参数短的线段就不能被显现出来。
第七个参数,double类型的maxLineGap,有默认值0,允许将同一行点与点之间连接起来的最大的距离。
2、无序数组找出差值最大的两个数
在筛选直线时需要用到,先将前两个数按大小设定为左右两个端点值,计算差值,遍历剩余数与当前最小值作差与当前差值比较,若大于则执行取代操作,具体见代码;若小于则跳过。
如果先将数据进行排序,再抽取最大最小值,复杂度会更高。
void find(vector<Vec2f>&lines_xy,int &m, int &n) {
float leftNum;
float rightNum;
float dis = lines_xy[0][0] - lines_xy[1][0];//当前两个数差值
if (dis < 0)
{
leftNum = lines_xy[0][0];
m = 0;
rightNum = lines_xy[1][0];
n = 1;
}
else
{
leftNum = lines_xy[1][0];
m = 1;
rightNum = lines_xy[0][0];
n = 0;
}
float minNum = leftNum;
for (int i = 2; i < lines_xy.size(); i++) {
// 将当前元素和它之前的最小元素进行相减,当差值更大,更新记录的元素
if (abs(lines_xy[i][0] - minNum) > abs(dis)) {
if (lines_xy[i][0] > minNum) {
rightNum = lines_xy[i][0];
n = i;
}
else {
leftNum = lines_xy[i][0];
minNum = lines_xy[i][0];
m = i;
}
dis = lines_xy[i][0] - minNum;
cout << "m:" << m << " n:" << n << endl;
}
}
}
复现结果:
x方向的直线距离采用的是平均距离,精度高,y方向采用的点距离,精度低。
上一篇: 面试试题001-截取字符串
下一篇: 给计算机学生的几点建议
推荐阅读