电压表检测说明
关于仪表检测,最好用彩色相机进行检测,考虑表盘的复杂性,且表盘指针一般为彩色指针,用黑白相机直接拍摄的时候指针不容易与表盘区分,如果为彩色相机,通过彩色通道,很容易将指针和刻度更好更容易的识别出来。
关于仪表的识别还要注意打光的角度,有些玻璃表盘打上光以后会有反光的现象。根据不同的表对反光的适应性,选择合适的光源。
1、计算刻度的位置,先筛选出刻度的位置,然后再进一步精确计算。因为刻度有一定的宽度,筛选出刻度所在的矩形,计算矩形的中心线。
2、然后绘制直线,通过交点算子,再经过排序,计算出刻度的起始点和终点,计算出两点间的距离,即刻度的测量范围,计算像素与电压的比例值。
3、计算指针所在中线位置与长线交点的位置,计算此位置与第一个点的距离,然后距离值乘上比例值,即为得到的电压值。
检测结果如下图所示,计算的结果还是比较准确的。
上代码和原始图
dev_update_off ()
dev_close_window ()
* 读取图像
read_image (Image, '2')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
gen_rectangle1 (ROI_0, 310.84, 854.863, 1028.37, 1209.44)
reduce_domain (Image, ROI_0, ImageReduced1)
gen_rectangle1 (ROI_2, 367.028, 939.479, 957.554, 961.657)
reduce_domain (ImageReduced1, ROI_2, ImageReduced2)
dev_display(ImageReduced1)
*筛选出刻度值
threshold (ImageReduced2, Regions, 159, 255)
connection (Regions, ConnectedRegions)
smallest_rectangle2 (ConnectedRegions, Row, Column, Phi, Length1, Length2)
gen_rectangle2_contour_xld (Rectangle1, Row, Column, Phi, Length1, Length2)
dev_display(Rectangle1)
stop()
dev_display(ImageReduced1)
*gen_rectangle2 (Rectangle, Row, Column, Phi, Length1, Length2)
sort_contours_xld (Rectangle1, SortedContours, 'lower_left', 'true', 'row')
count_obj(SortedContours,num)
row11:=[]
col11:=[]
row22:=[]
col22:=[]
stop()
ContourS:=[]
* ****************************************
*求rectangle2的中心线
* ****************************************
for i:=1 to num by 1
select_obj (SortedContours, ObjectSelected,i)
*row1:=Row[1]-(Length1[1])*sin(Phi[1])
*row1:=[row1,Row[i-1]-(Length1[i-1])*sin(Phi[i-1])]
*col1:=[col1,Column[i-1]+(Length1[i-1])*cos(Phi[i-1])]
*row2:=[row2,Row[i-1]+(Length1[i-1])*sin(Phi[i-1])]
*col2:=[col2,Column[i-1]-(Length1[i-1])*cos(Phi[i-1])]
row1:=Row[i-1]-(Length1[i-1])*sin(Phi[i-1])
col1:=Column[i-1]+(Length1[i-1])*cos(Phi[i-1])
row2:=Row[i-1]+(Length1[i-1])*sin(Phi[i-1])
col2:=Column[i-1]-(Length1[i-1])*cos(Phi[i-1])
gen_contour_polygon_xld (Contour, [row1,row2], [col1,col2])
dev_display(Contour)
row11:=[row11,row1]
col11:=[col11,col1]
row22:=[row22,row2]
col22:=[col22,col2]
endfor
stop()
gen_region_line(ROI_lines, row11, col11,row22,col22)
gen_region_line (ROI_long, 363.1, 951.1, 960.7, 948.7)
*计算这两个区域的交集
intersection (ROI_lines, ROI_long, Reg_p_obj)
*交集的位置
area_center (Reg_p_obj, Area, Row2, Column2)
*计算第一个点和最后一个点之间的距离
distance_pp (Row2[0], Column2[0], Row2[15], Column2[15], Distance)
*第一个点的位置
gen_cross_contour_xld (Cross, Row2[15], Column2[15], 16, 0.79)
*计算指针的位置
dev_display(ImageReduced1)
*gen_rectangle1 (ROI_xiao, 847.9, 881.5, 891.1, 970.3)
*tu1
*gen_rectangle1 (ROI_xiao, 574.3, 883.9, 600.7, 975.1)
*tu2
gen_rectangle1 (ROI_xiao, 492.7, 888.7, 516.7, 970.3)
reduce_domain (ImageReduced1, ROI_xiao, ImageReduced3)
threshold (ImageReduced3, RegionsZhen, 147, 188)
connection (RegionsZhen, ConnectedRegions1)
select_shape (ConnectedRegions1, SelectedRegionsZhen, 'area', 'and', 150, 99999)
dev_display(ImageReduced1)
dev_display(SelectedRegionsZhen)
smallest_rectangle2 (SelectedRegionsZhen, Row13, Column13, Phi13, Length113, Length213)
gen_rectangle2 (RectangleZhen,Row13, Column13, Phi13, Length113*3, 0.5)
*计算指针与线的交集位置
intersection (RectangleZhen, ROI_long, Reg_p_objZhen)
area_center (Reg_p_objZhen, Area, Row2d, Column2d)
gen_cross_contour_xld (Crossd, Row2d, Column2d, 16, 0.79)
*计算此点与第一个点的距离
distance_pp (Row2d, Column2d, Row2[15], Column2[15], Distance2)
a:=Distance2*150/Distance
* 表示
dev_clear_window ()
dev_display (Image)
dev_set_line_width (2)
dev_set_color ('red')
dev_display (RectangleZhen)
dev_set_color ('yellow')
dev_display (Crossd)
tuple_string (a, '.2f', str)
set_tposition (WindowHandle, Row2d-40, Column2d-150)
write_string (WindowHandle, str)
stop ()
disp_message (WindowHandle, '当前电压:'+str, 'window', 12, 12, 'red', 'false')
图1指针在70多
图2指针在110多
图3指针在20多
于2023年8月18日更新,提供一种新的思路
由于受弧度的影响,在检测的时候并不是完全准的,所拍摄的表盘上边缘和下边缘是呈收敛状态的,所以直接检测并不够准确。
在想有没有一种可以将曲面展开成平面后再计算的
后来找到了一个将柱面展开成平面的算法,但是效果并不理想,还需有待改进,可尝试增加角度的迭代
https://blog.csdn.net/sunnyrainflower/article/details/132353931
上面的链接提供了柱面展成平面的算法及效果图
代码见资源链接
https://download.csdn.net/download/sunnyrainflower/88228306
曲面(弧面、柱面)展平(拉直)需要自己做一个遮罩层
此代码主要是为了方便嫁接使用
自己用视觉算法识别遮罩即可进行嫁接
里面代码去掉了原始程序对gpu的依赖(即自动检测遮罩层位置,所以需要自己做遮罩层)
如果就想用深度学习识别,不想去掉的话,可以访问原始代码地址
https://github.com/AntoninLeroy/wine_label_reader_toolkit
原始代码包含自动识别、展开、字符识别整个流程
如果只想要柱面展开代码,请自行下载
本里面包含两个版本,一个版本包含字符识别,一个版本不包含字符识别
------------------------------------------------------------
声明 | 未经允许,禁止转载,谢谢合作!
作者 | 大胡子大叔
出品 | CSDN
-------------------------------------------------------------