某些场景如目标区域是在一个环形的柱面,那么我们就需要将柱面图像进行拉伸,使目标区域在一个平面中显示
预处理:
极坐标显示 - 转换为笛卡尔坐标显示
原理是:得到一个环形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 - 输入图像需要转换的原来图像 ,Row,Colum 圆环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是角点。
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')