一、定义:投影变换也叫透射变换、投影映射。透射变换是将图像投影到一个新的视平面,是一种二维坐标到三维坐标的变换。
透射变换是仿射变换的延续,也可以说仿射变换是透射变换的一种特殊形式。其特殊性在于变换后图像的形状仍然维持原状。投影变换包括的情况很多,有可能变换前后图像的形状发生了很大的改变,如对边不再平行,或者发生了透视畸变,这时可以使用投影变换使其恢复原状。其步骤与仿射变换类似,首先计算投影变换矩阵,然后计算投影变换参数,最后将投影变换矩阵映射到对象上。
二、算子
2.1根据给定点的投影计算一个同质变换矩阵
hom_vector_to_proj_hom_mat2d( : : Px, Py, Pw, Qx, Qy, Qw, Method : HomMat2D)
Px:输入参数,图像变换前图像的顶点x坐标。
Py:输入参数,图像变换前图像的顶点y坐标。
Pw:输入参数,图像变换前图像的顶点w坐标。
Qx:输入参数,图像变换后图像的顶点x坐标。
Qy:输入参数,图像变换后图像的顶点y坐标。
Qw:输入参数,图像变换后图像的顶点w坐标。
Method:输入参数,变换方式选择。默认'normalized_dlt',
列表
【
'dlt’算法最快速简单,但是有相对的不准确的误差
'normalized_dlt’速度与精度较好
】。
HomMat2D:输出参数,输出齐次投影变换矩阵。
2.2根据给定点的投影计算一个投影变换矩阵
vector_to_proj_hom_mat2d( : : Px, Py, Qx, Qy, Method, CovXX1, CovYY1, CovXY1, CovXX2, CovYY2, CovXY2 : HomMat2D, Covariance)
Px:输入参数,图像变换前图像的顶点x坐标。
Py:输入参数,图像变换前图像的顶点y坐标。
Qx:输入参数,图像变换后图像的顶点x坐标。
Qy:输入参数,图像变换后图像的顶点y坐标。
Method:输入参数,变换方式选择。默认 'normalized_dlt',
列表
【
'dlt’算法最快速简单,但是有相对的不准确的误差
'gold_standard’优化较好但速度较慢
'normalized_dlt’速度与精度较好
】
CovXX1:输入参数,图像变换前图像对应x值坐标的row方向的变动。默认[]。
CovYY1:输入参数,图像变换前图像对应y值坐标的col方向的变动。默认[]。
CovXY1:输入参数,图像变换前图像对应点的协方差。默认[]。
CovXX2:输入参数,图像变换后图像对应x值坐标的row方向的变动。默认[]。
CovYY2:输入参数,图像变换后图像对应y值坐标的col方向的变动。默认[]。
CovXY2:输入参数,图像变换后图像对应点的协方差。默认[]。
HomMat2D:输出参数,输出映射变换矩阵。
Covariance:输出参数,输出9×9协方差矩阵的投影变换矩阵。
Filters / Geometric Transformations
2.3对图像应用投影变换
projective_trans_image(Image : TransImage : HomMat2D, Interpolation, AdaptImageSize, TransformDomain : )
Image:输入参数,输入需要变换的多通道图像。
TransImage:输出参数,输出变换后的图像。
HomMat2D:输入参数,输入变换矩阵。
Interpolation:输入参数,插值的方式。默认 'bilinear',列表【 'bilinear', 'nearest_neighbor'】。
AdaptImageSize:输入参数,是否自动调整输出图像的大小。默认'false',列表【'false', 'true'】。
TransformDomain:输入参数,输入图像的域也应该进行变换吗?。默认'false',列表【'false', 'true'】。
Regions / Geometric Transformations
2.4对区域应用投影变换
projective_trans_region(Regions : TransRegions : HomMat2D, Interpolation : )
Regions:输入参数,输入区域。
TransRegions:输出参数,输出变换后的区域。
HomMat2D:输入参数,输入映射变换矩阵。
Interpolation:输入参数,插值的方式。默认 'bilinear',列表【 'bilinear', 'nearest_neighbor'】。
三、代码应用
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
* Image Acquisition 01: Code generated by Image Acquisition 01
list_files ('C:/Users/Dell/Desktop/投影变换', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
threshold (Image, Regions, 95, 255)
fill_up (Regions, RegionFillUp)
opening_rectangle1 (RegionFillUp, RegionOpening, 5, 5)
connection (RegionOpening, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 80225.1, 220096)
closing_circle (SelectedRegions, RegionClosing, 15)
*提取矩形XLD轮廓
gen_contour_region_xld (RegionClosing, Contours, 'border')
*分割XLD轮廓,并排序。(第一次排序按照行,第二次排序按照列。这样可以有顺序的提取矩形的四条边。)
segment_contours_xld (Contours, ContoursSplit, 'lines', 5, 10, 2)
sort_contours_xld (ContoursSplit, SortedContours, 'upper_left', 'true', 'row')
sort_contours_xld (ContoursSplit, SortedContours1, 'upper_left', 'true', 'column')
*分别把行列的的XLD拟合成直线
gen_empty_obj (Hline)
select_obj (SortedContours, ObjectSelected, 1)
select_obj (SortedContours, ObjectSelected1, 4)
concat_obj (Hline, ObjectSelected, Hline)
concat_obj (Hline, ObjectSelected1, Hline)
gen_empty_obj (Vline)
select_obj (SortedContours1, ObjectSelected2, 1)
select_obj (SortedContours1, ObjectSelected3, 4)
concat_obj (Vline, ObjectSelected2, Vline)
concat_obj (Vline, ObjectSelected3, Vline)
fit_line_contour_xld (Hline, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
gen_region_line (RegionLines, RowBegin, ColBegin, RowEnd, ColEnd)
fit_line_contour_xld (Vline, 'tukey', -1, 0, 5, 2, RowBegin1, ColBegin1, RowEnd1, ColEnd1, Nr1, Nc1, Dist1)
gen_region_line (RegionLines1, RowBegin1, ColBegin1, RowEnd1, ColEnd1)
*计算矩形四个角点坐标(左上,右上,右下,左下)
intersection_lines (RowBegin[0], ColBegin[0], RowEnd[0], ColEnd[0], RowBegin1[0], ColBegin1[0], RowEnd1[0], ColEnd1[0], Row, Column, IsOverlapping)
intersection_lines (RowBegin[0], ColBegin[0], RowEnd[0], ColEnd[0], RowBegin1[1], ColBegin1[1], RowEnd1[1], ColEnd1[1], Row1, Column1, IsOverlapping1)
intersection_lines (RowBegin[1], ColBegin[1], RowEnd[1], ColEnd[1], RowBegin1[1], ColBegin1[1], RowEnd1[1], ColEnd1[1], Row2, Column2, IsOverlapping2)
intersection_lines (RowBegin[1], ColBegin[1], RowEnd[1], ColEnd[1], RowBegin1[0], ColBegin1[0], RowEnd1[0], ColEnd1[0], Row3, Column3, IsOverlapping3)
gen_cross_contour_xld (Cross, Row, Column, 22, 0.785398)
gen_cross_contour_xld (Cross1, Row1, Column1, 22, 0.785398)
gen_cross_contour_xld (Cross2, Row2, Column2, 22, 0.785398)
gen_cross_contour_xld (Cross3, Row3, Column3, 22, 0.785398)
*投影变换前的坐标
originalRow:=[Row,Row1,Row2,Row3]
originalColumn:=[Column,Column1,Column2,Column3]
*计算原图矩形区域最宽和最高参数
distance_pp (Row, Column, Row1, Column1, Width1)
distance_pp (Row2, Column2, Row3, Column3, Width2)
tuple_max2 (Width1, Width2, WidthMax)
distance_pp (Row, Column, Row3, Column3, Height1)
distance_pp (Row1, Column1, Row2, Column2, Height2)
tuple_max2 (Height1, Height2, HeightMax)
*第1种投影变换方式
*投影变换后的坐标(利用矩形最宽的边和最高的边长度,分别生成4个顶点坐标。
*优点是整图做投影变换,整幅图像的倾斜都会被校正。缺点是,投影变换过程中可能会导致一些区域跑出了图像外,结果图像相对于原图,这些变换导致的图像外区域会缺失)
projectionRow:=[Row, Row, Row+HeightMax,Row+HeightMax]
projectionColumn:=[Column, Column+WidthMax,Column+WidthMax, Column]
*生成投影变换矩阵,并做投影变换,校正图像
hom_vector_to_proj_hom_mat2d (originalRow, originalColumn, [1,1,1,1], projectionRow, projectionColumn, [1,1,1,1], 'normalized_dlt', HomMat2D)
projective_trans_image (Image, Image_rectified, HomMat2D, 'bilinear', 'false', 'false')
dev_display (Image)
dev_display (Image_rectified)
write_image (Image_rectified, 'png', 0, 'C:/Users/Dell/Desktop/投影变换/新建文件夹/'+Index+'0.png')
*第2种投影变换方式
*投影变换后的坐标(利用矩形最宽的边和最高的边长度,分别生成4个顶点坐标。图像变换后,以左上原点(0,0)为基准,依次赋值各顶点坐标。
*优点是被提取的区域变换到图像坐标系左上角,区域不会缺失。缺点是除了被提取区域外,其余区域可能会缺失。)
projectionRow1:=[0, 0, HeightMax,HeightMax]
projectionColumn1:=[0, WidthMax,WidthMax, 0]
*生成投影变换矩阵,并做投影变换,校正图像
hom_vector_to_proj_hom_mat2d (originalRow, originalColumn, [1,1,1,1], projectionRow1, projectionColumn1, [1,1,1,1], 'normalized_dlt', HomMat2D1)
projective_trans_image (Image, Image_rectified1, HomMat2D1, 'bilinear', 'false', 'false')
dev_display (Image)
dev_display (Image_rectified1)
write_image (Image_rectified1, 'png', 0, 'C:/Users/Dell/Desktop/投影变换/新建文件夹/'+Index+'1.png')
stop()
endfor
原图1
第1种投影变换结果图
第2种投影变换结果图
原图2
第1种投影变换结果图
第2种投影变换结果图
原图3
第1种投影变换结果图
第2种投影变换结果图