对应示例程序:
measure_tft_cells.hdev
目标:测量TFT液晶显示器中红,绿,蓝三个部分的边缘厚度值
思路为:
1.读取图像,并分成R,G,B三个通道
2.首先根据G通道提取出绿色部分,再将其与R通道做差异,得到包含红色和蓝色部分
3.对包含红色和蓝色的区域进行提取,得到红色部分,再通过区域间的差异性,最终得到蓝色部分
4.利用仿射变换,将图像纠正到垂直方向,方便后续的距离计算,提高测量精度
5.利用measure_pairs提取垂直于测量矩形的直边对,并得到cell厚度
图像:
代码:
dev_close_window ()
dev_update_off ()
Path := 'lcd/tft_cells'
read_image (Image, Path + '_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_size (0, 0, Width, Height, 640, 480, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_color ('green')
dev_set_draw ('margin')
for I := 1 to 7 by 1
read_image (Image, Path + '_' + I$'.2i')
decompose3 (Image, R, G, B)
* First, the cell columns corresponding to each of the three colors (RGB)
* are segmented.
*首先,对三种颜色(RGB)中每种颜色对应的单元格列进行分段。
segment_color_column (G, GreenColumn, GInnerRegions, 200) //分离出绿色 G区域
difference (R, GreenColumn, RegionDifference) //与红色图像做差异
reduce_domain (R, RegionDifference, ImageReduced) //裁剪出R, B 区域
segment_color_column (ImageReduced, RedColumn, RInnerRegions, 200) //分离出红色 R区域
difference (RegionDifference, RedColumn, RegionDifference) //与包含R,B的区域 做差异
reduce_domain (B, RegionDifference, ImageReduced) //裁剪去B区域
segment_color_column (ImageReduced, BlueColumn, BInnerRegions, 50) //分离出蓝色 B区域
*
* In order to achieve more accurate edge positions, the image is aligned
* so that the cell columns are vertically oriented. This way our edges
* lie parallel to the x-axis of the image.
*为了获得更精确的边缘位置,
*需要将图像校正,使单元格的列呈现垂直方向。
*这样我们提取出的边缘将平行于图像的X轴。
smallest_rectangle2 (GreenColumn, Row, Column, Phi, Length1, Length2)
* Normalize Phi so that all negative values are turned by 180 degrees
*图像校正到垂直方向
PhiNorm := Phi - ((sgn(Phi) / 2.0 - .5) * rad(180))
hom_mat2d_identity (HomMat2DIdentity)
hom_mat2d_rotate (HomMat2DIdentity, -(mean(PhiNorm) - rad(90)), Width / 2, Height / 2, HomMat2DRotate)
affine_trans_image (Image, ImageTrans, HomMat2DRotate, 'constant', 'false') //校正原始图像
*
*
* Perform the actual measurements ...
* ... for the green cells
affine_trans_image (G, ImageAffinTrans, HomMat2DRotate, 'constant', 'false') //校正红色G图像
affine_trans_region (GreenColumn, GreenAffineTrans, HomMat2DRotate, 'nearest_neighbor') //校正绿色列
affine_trans_region (GInnerRegions, GInnerTrans, HomMat2DRotate, 'nearest_neighbor') //校正绿色 内部区域
*进行绿色通道测量
measure_cell_frame_width (ImageAffinTrans, GreenAffineTrans, GInnerTrans, FrameWidth, REdgeFirst, CEdgeFirst, REdgeSecond, CEdgeSecond)
dev_display (ImageTrans)
dev_set_line_width (3)
dev_set_color ('green')
gen_cross_contour_xld (GreenCross, [REdgeFirst,REdgeSecond], [CEdgeFirst,CEdgeSecond], 12, rad(0))
dev_display (GreenCross)
*打印绿色通道的测量结果
Message := 'Mean frame width / deviation [px]'
Message[1] := mean(FrameWidth)$'12.2f' + deviation(FrameWidth)$'15.1f'
disp_message (WindowHandle, Message, 'window', 12, 12, ['black','forest green'], 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* ... the red cells 红色通道 类似于绿色通道
affine_trans_image (R, ImageAffinTrans, HomMat2DRotate, 'constant', 'false')
affine_trans_region (RedColumn, RedAffineTrans, HomMat2DRotate, 'nearest_neighbor')
affine_trans_region (RInnerRegions, RInnerTrans, HomMat2DRotate, 'nearest_neighbor')
measure_cell_frame_width (ImageAffinTrans, RedAffineTrans, RInnerTrans, FrameWidth1, REdgeFirst1, CEdgeFirst1, REdgeSecond1, CEdgeSecond1)
dev_set_color ('red')
gen_cross_contour_xld (RedCross, [REdgeFirst1,REdgeSecond1], [CEdgeFirst1,CEdgeSecond1], 12, rad(0))
dev_display (RedCross)
Message[2] := mean(FrameWidth1)$'12.2f' + deviation(FrameWidth1)$'15.1f'
disp_message (WindowHandle, Message, 'window', 12, 12, ['black','forest green','red'], 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* ... and finally the blue cells 蓝色通道
affine_trans_image (B, ImageAffinTrans, HomMat2DRotate, 'constant', 'false')
affine_trans_region (BlueColumn, BlueAffineTrans, HomMat2DRotate, 'nearest_neighbor')
affine_trans_region (BInnerRegions, BInnerTrans, HomMat2DRotate, 'nearest_neighbor')
measure_cell_frame_width (ImageAffinTrans, BlueAffineTrans, BInnerTrans, FrameWidth2, REdgeFirst2, CEdgeFirst2, REdgeSecond2, CEdgeSecond2)
dev_set_color ('blue')
gen_cross_contour_xld (BlueCross, [REdgeFirst2,REdgeSecond2], [CEdgeFirst2,CEdgeSecond2], 12, rad(0))
dev_display (BlueCross)
Message[3] := mean(FrameWidth2)$'12.2f' + deviation(FrameWidth2)$'15.1f'
disp_message (WindowHandle, Message, 'window', 12, 12, ['black','forest green','red','blue'], 'true')
* Display a detail of the image with the result
*显示包含结果的图像的详细信息 小窗口显示
gen_rectangle1 (Rectangle, 250, 500, 550, 800)
dev_set_line_width (1)
dev_set_color ('white')
dev_display (Rectangle)
get_window_extents (WindowHandle, Row1, Column1, WindowWidth, WindowHeight) //有关窗口大小和位置的信息。
dev_open_window (0, WindowWidth, 300, 300, 'black', WindowHandle1)
dev_set_part (250, 500, 550, 800)
dev_display (ImageTrans)
dev_set_line_width (3)
dev_set_color ('red')
dev_display (RedCross)
dev_set_color ('blue')
dev_display (BlueCross)
dev_set_color ('green')
dev_display (GreenCross)
if (I < 7)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
dev_close_window ()
else
disp_end_of_program_message (WindowHandle, 'black', 'true')
endif
endfor
用到的几个算子:
decompose3–分离三通道图像
hom_mat2d_identity–生成二维齐次变换矩阵
hom_mat2d_rotate-- 向二维齐次变换矩阵中添加旋转向量。
affine_trans_image–对图像进行仿射变换
affine_trans_region–对图像区域进行仿射变换
gen_measure_rectangle2–获得一个测量句柄
measure_pairs–提取垂直于矩形或环形弧的直边对
close_measure–删除一个measure对象