对应示例程序:
phase_correlation_fft.hdev
目标:先人为的将原始图像进行平移,再使用相位相关法计算两个图像之间的变换(即计算出人为平移的值)
思路为:
1.读取图像,并人为的设定平移参数,利用仿射变换将图像进行平移
2.利用二阶多项式创建一个灰色曲面,并将其与平移后的图像进行叠加
3.对原始图像以及叠加后图像进行傅里叶变换,从空间域转换到频率域
4.利用算子phase_correlation_fft计算上述两幅频率域图像的向外相关性
5.将相位相关性图像转换到空间域,利用图像中心纠正和local_max_sub_pix算子计算出最后的偏移值
6.在窗口上进行相关显示
图像:
代码:
dev_update_off ()
read_image (Image, 'wafer/wafer_dies.png')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
disp_message (WindowHandle, 'Original image', 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Translate the image.
RowTrans := 92.4
ColumnTrans := 58.2
optimize_rft_speed (Width, Height, 'standard') //优化傅里叶变换的运行时间
hom_mat2d_identity (HomMat2D) //生成二维其次变换矩阵
hom_mat2d_translate (HomMat2D, RowTrans, ColumnTrans, HomMat2D) //将平移添加到齐次二维变换矩阵。
* We set 'init_new_image' to 'true' to ensure the translated image has
* defined values of 0 in the part that lies outside the original image.
*我们将“init_new_image”设置为“true”,以确保转换后的图像
*在原始图像之外的像素值为0。
get_system ('init_new_image', InitNewImage) //获取Halcon系统的当前值
set_system ('init_new_image', 'true') //设置参数
affine_trans_image (Image, ImageTrans, HomMat2D, 'constant', 'false') //仿射变换图像(将图像原点平移到(RowTrans ,ColumnTrans))
full_domain (ImageTrans, ImageTranslated) //将图像的域扩展到最大。
set_system ('init_new_image', InitNewImage)
* Simulate a degradation of the image by an uneven illumination. 通过不均匀照明模拟图像的退化,(通过与二阶灰色曲面叠加进行实现)
*用二阶多项式创建一个灰色曲面。
gen_image_surface_second_order (ImageSurface, 'byte', 0.0005, -0.0008, 0, 0, 0, 128, Height / 2, Width / 2, Width, Height)
add_image (ImageTranslated, ImageSurface, ImageDegraded, 1, -128) //叠加两幅图像 g' := (g1 + g2) * Mult + Add
dev_display (ImageDegraded)
disp_message (WindowHandle, ['Image translated by (' + RowTrans$'4.1f' + ',' + ColumnTrans$'4.1f' + ')','and degraded by uneven illumination'], 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Compute the phase correlation. 计算相位相关
rft_generic (Image, ImageFFT, 'to_freq', 'none', 'complex', Width) //原始图像 空间域到频率域 傅里叶变换
rft_generic (ImageDegraded, ImageTransFFT, 'to_freq', 'none', 'complex', Width) //模拟的退化后图像 空间域到频率域 傅里叶变换
phase_correlation_fft (ImageFFT, ImageTransFFT, ImagePhaseCorrelationFFT) //计算两幅图像在频域中的相位相关性
rft_generic (ImagePhaseCorrelationFFT, ImagePhaseCorrelation, 'from_freq', 'n', 'real', Width) //相位相关性图像 频率域到空间域 傅里叶变换
dev_display (ImagePhaseCorrelation)
gen_circle_contour_xld (Circle, RowTrans, ColumnTrans, 20, 0, 6.28318, 'positive', 1) //在平移后的原点上生成一个圆形轮廓
dev_set_color ('green')
dev_display (Circle)
*注意左上角的峰值
disp_message (WindowHandle, ['Phase correlation image:','note the peak in the upper left corner'], 'window', 12, 12, 'black', 'true')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* Since the phase correlation is cyclic, negative translations result in
* peaks in lower or right part of the image. If the translation is close
* 0 in one or two directions, the interpolation in local_max_sub_pix would
* therefore access wrong values because of its border treatment (which is
* not cyclic). To obtain a translation that is correct in all cases, we
* shift the phase correlation cyclically so that a zero translation
* corresponds to the center of the image. We then correct the coordinates
* returned by local_max_sub_pix.
*由于相位相关是周期性的,负平移将导致图像在下部或者右部出现峰值。
*如果平移在一个或两个方向上接近0,则利用local_max_sub_pix进行插值时将返回错误的值,因为边界问题(不是周期性的)。
*为了获得在任何情况下都是正确的平移信息,循环移动相位相关性,使零平移对应于图像的中心。然后我们修正local_max_sub_pix返回的坐标
RowOffset := Height / 2 //图像Row 中心
ColumnOffset := Width / 2 //图像Column 中心
cyclic_shift_image (ImagePhaseCorrelation, ImageCyclicShift, RowOffset, ColumnOffset)
local_max_sub_pix (ImageCyclicShift, 'facet', 1, 0.02, RowShifted, ColumnShifted) //图像中局部极大值的亚像素精确检测
Row := RowShifted - RowOffset //计算出的平移Row
Column := ColumnShifted - ColumnOffset //计算出的平移Column
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (ImageDegraded)
disp_message (WindowHandle, 'Translation computed by the phase correlation:\n (' + Row$'5.2f' + ',' + Column$'5.2f' + ')', 'window', 12, 12, 'black', 'true')
gen_cross_contour_xld (Cross, Row, Column, 20, 0.0) //显示平移后的原点位置
dev_display (Cross)
用到的几个算子:
decompose3–分离三通道图像
hom_mat2d_identity–生成二维齐次变换矩阵
hom_mat2d_rotate-- 向二维齐次变换矩阵中添加旋转向量
affine_trans_image–对图像进行仿射变换
gen_image_surface_second_orde–用二阶多项式创建一个灰色曲面。
add_image–叠加两幅图像 g’ := (g1 + g2) * Mult + Add
rft_generic–计算图像的快速傅立叶变换(FFT)值
phase_correlation_fft–计算两幅图像在频域中的相位相关性
local_max_sub_pix–图像中局部极大值的亚像素精确检测