Halcon图像处理-环形显示拉伸

时间:2024-05-22 19:02:41

某些场景如目标区域是在一个环形的柱面,那么我们就需要将柱面图像进行拉伸,使目标区域在一个平面中显示

预处理:

极坐标显示 - 转换为笛卡尔坐标显示

原理是:得到一个环形Ring 然后得到最小外接圆半径,再得到ring的内圆半径,然后再将环形ring 区域内的内容进行拉伸处理,将环形的图像转换为水平平面显示,主要的算子解释如下:

柱面拉伸图像预处理,这里给出一般的预处理,根据实际情况选择。

方法

预处理和一般图像预处理相同

*填充圆环得到最小的外接圆半径的圆心坐标

shape_trans (Ring, OuterCircle, 'outer_circle')

*求一个区域的补集

complement (Ring, RegionComplement)  求一个区域的补集

connection (RegionComplement, ConnectedRegions)

select_shape (ConnectedRegions, InnerCircle, ['width','height'], 'and', [450,450], [650,650])

* Determine the parameters of the ring that contains the bar code.

*求内外圆形的半径圆心坐标  求一个区域的最小外接圆

smallest_circle (Ring, Row, Column, OuterRadius) 得到外圆最小的圆形半径和圆形坐标信息  求取外圆的信息

smallest_circle (InnerCircle, InnerRow, InnerColumn, InnerRadius) 到最小的圆形半径和圆心坐标信息 求取内圆的信息

* Now read the bar code. This is done by computing the polar transformation

* of the ring in the image that contains the bar code.

WidthPolar := 1440 

HeightPolar := round(OuterRadius - InnerRadius - 10)  四舍五入算子

这是极坐标转换的主要算子:

polar_trans_image_ext (Image, PolarTransImage, Row, Column, rad(360), 0, OuterRadius - 5, InnerRadius + 5, WidthPolar, HeightPolar, 'bilinear')

主要参数设置:Image - 输入图像需要转换的原来图像 RowColum 圆环Ring的圆心坐标,接下来的两个参数表示需要拉伸的其实角度和终止角度。接下两个参数需要的是起始半径和终止半径,也就是说需要的到被识别文字的所在圆环区域。Bilinear 双线性插值法,精度大于邻近插值法

参考案例

案例:grid_rectification.hdev

当一个显示在柱面的一维码、二维码、字符,我们需要将它转成平面才能准且的识别,一般由两个步骤将图像拉伸为平面图。

Step1:Determination of the image map  求出一个投影变换矩阵 Map

       算子gen_grid_rectification_map (ImageReduced, ConnectingLines, Map, Meshes, GridSpacing, 0, Row, Col, 'bilinear')

       如何求出Map 具体步骤如下代码

Step2: Application of the image map 计算Map和原图 得出投影变换之后的平面图像

      算子:map_image (Image, Map, ImageMapped)

 

* This example illustrates how to use the operators for the grid-rectification.

*

* The following command creates a postscript file

* that contains the rectification grid. This grid must be

* printed. Then it must be mounted on the object surface.

 

生成一个网格文件,也可以自己手动画出一个网格图像即可。这是求出Map的必要步骤。

WidthOfGrid := 0.17

NumSquares := 17

create_rectification_grid (WidthOfGrid, NumSquares, 'rectification_grid.ps')

*

* Read the image of the object wrapped by the rectification grid

* and reopen the window with an appropriate size.

read_image (Image, 'can_with_grid')

get_image_size (Image, ImageWidth, ImageHeight)

dev_close_window ()

dev_open_window (0, 0, ImageWidth * 0.75, ImageHeight * 0.75, 'black', WindowID1)

dev_display (Image)

dev_update_off ()

set_display_font (WindowID1, 14, 'mono', 'true', 'false')

* *

* Part 1: Determination of the image map  求出一个投影变换矩阵Map

* The surface to be rectified is wrapped by a checkered pattern, which

* is used to determine the mapping between the distorted image and

* the rectified image. Note the orientation of the two circular marks. When

* in gen_grid_rectification_map() the parameter Rotation is 'auto', the rectified

* image is rotated such that the black mark is left of the white mark.

*

* Determine region of interest

MinContrast := 25  最小对比度

Radius := 10  半径

find_rectification_grid (Image, GridRegion, MinContrast, Radius) 

寻找网格的算子,根据最小对比度和最小半径,得出网格所在的区域

*

dev_display (GridRegion)

disp_message (WindowID1, 'Grid region', 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowID1, 'black', 'true')

stop ()

reduce_domain (Image, GridRegion, ImageReduced)  将原图所在上述代码得出的区域抠出

*

* Determine grid points

SigmaSaddlePoints := 1.5

Threshold := 5  这个值越大则对角点的要求越大

saddle_points_sub_pix (ImageReduced, 'facet', SigmaSaddlePoints, Threshold, Row, Col)  寻找角点坐标的算子

Note:角点:就是在图像中有一个像素区域向四面八方扩散其灰度值都在变化,则认为这个点为角点。

如下图中:

位置2 只有在垂直的方向灰度值由变化,则位置2不是角点。

位置1灰度值变化方向很多,则认为位置1是角点。

Halcon图像处理-环形显示拉伸

 

dev_set_color ('blue')

gen_cross_contour_xld (SaddlePoints, Row, Col, 6, 0.785398) 

这个一个构造点的算子,会得到一个小小的十字叉。

在算子前缀带有gen_的算子都是有一种得到一种形状的算子

例如:gen_rectangle1()  得到一个不带方向的矩形 gen_circle (Circle, Row, Col, 100.5)得到一个圆形等等。

dev_display (Image)

dev_display (SaddlePoints) 显示一下上面得到的小十字叉形状

disp_message (WindowID1, 'Grid points', 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowID1, 'black', 'true')

stop ()

*

* Connect points to grid

SigmaConnectGridPoints := 0.9

MaxDist := 5.0

GridSpacing := 20

dev_set_color ('red')

connect_grid_points (ImageReduced, ConnectingLines, Row, Col, SigmaConnectGridPoints, MaxDist)

这个算子是将上面的小十字叉连接起来,形成一个网格。

*

dev_display (ConnectingLines)

disp_message (WindowID1, 'Connected grid points', 'window', 12, 12, 'black', 'true')

disp_continue_message (WindowID1, 'black', 'true')

stop ()

*

* Determine image map

gen_grid_rectification_map (ImageReduced, ConnectingLines, Map, Meshes, GridSpacing, 0, Row, Col, 'bilinear')

Map得到一个投影变换矩阵

ImageReduced 需要投影变换的图像

ConnectingLines 刚刚求出来的网格

Row, Col小交叉点的坐标

 

map_image (ImageReduced, Map, ImageMapped)

最终矩阵计算算子,用来得出投影变换后的图像 mageMapped

*

get_image_size (Map, MapWidth, MapHeight)

dev_open_window (0, (ImageWidth * 0.75) + 12, MapWidth, MapHeight, 'black', WindowID2)

set_display_font (WindowID2, 14, 'mono', 'true', 'false')

dev_display (ImageMapped)

disp_message (WindowID2, 'Rectified grid', 'window', 12, 12, 'black', 'true')

stop ()

*

* Part 2: Application of the image map

* The original surface (without the checkered pattern) is rectified

* using the previously calculated image map.

*

* Read in the image to be rectified

read_image (Image, 'can')  读取原来的图像

*

* Rectify image using the previously calculated image map

dev_set_window (WindowID2)

map_image (Image, Map, ImageMapped) 利用刚刚的出来的Map矩阵计算得出最终转换为平面的图像

*

dev_set_window (WindowID1)

dev_display (Image)

disp_message (WindowID1, 'Original image', 'window', 12, 12, 'black', 'true')

dev_set_window (WindowID2)

dev_display (ImageMapped)

disp_message (WindowID2, 'Rectified image', 'window', 12, 12, 'black', 'true')

 

Halcon图像处理-环形显示拉伸