*这个示例程序展示了如何将多个PCB图像合并成一个大的PCB拼接图像。
*程序演示了如何使用proj_match_points_ransac和gen_projective_mosaic来实现这一目标。请注意,*PCB表面有一些损坏,看起来像是折痕,很容易被误认为是拼接图像中的接缝。为了证明这不是这种情况,
*程序还显示了拼接图像的真实接缝。
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 640, 480, 'white', WindowHandle)
dev_set_color ('green')
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
*读取图像并逐个显示。请注意沿PCB上运行的类似折痕的损坏。
gen_empty_obj (Images)
for J := 1 to 6 by 1
read_image (Image, 'mosaic/pcb_' + J$'02')
concat_obj (Images, Image, Images)
dev_display (Image)
disp_message (WindowHandle, 'Image ' + J$'d', 'window', 12, 12, 'black', 'true')
wait_seconds (1)
endfor
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 显示用于计算图像之间投影变换的点匹配。将所有图像显示在一个大的平铺图像中,图像之间有一些间在*隔,以便易于看到图像的范围。
dev_set_window_extents (-1, -1, 640 / 4, 2980 / 4)
tile_images_offset (Images, TiledImage, [0,500,1000,1500,2000,2500], [0,0,0,0,0,0], [-1,-1,-1,-1,-1,-1], [-1,-1,-1,-1,-1,-1], [-1,-1,-1,-1,-1,-1], [-1,-1,-1,-1,-1,-1], 640, 2980)
dev_clear_window ()
dev_display (TiledImage)
disp_message (WindowHandle, 'All 6 images', 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'Click \'Run\'\nto continue', 'window', 2980 / 4 - 50, 12, 'black', 'true')
stop ()
dev_clear_window ()
dev_display (TiledImage)
disp_message (WindowHandle, 'Point matches', 'window', 12, 3, 'black', 'true')
* We define the image pairs, i.e., which image should be mapped to which image.
From := [1,2,3,4,5]
To := [2,3,4,5,6]
Num := |From|
*
ProjMatrices := []
*
Rows1 := []
Cols1 := []
Rows2 := []
Cols2 := []
NumMatches := []
* Step1
for J := 0 to Num - 1 by 1
F := From[J]
T := To[J]
select_obj (Images, ImageF, F)
select_obj (Images, ImageT, T)
*Step2
points_foerstner (ImageF, 1, 2, 3, 200, 0.3, 'gauss', 'false', RowJunctionsF, ColJunctionsF, CoRRJunctionsF, CoRCJunctionsF, CoCCJunctionsF, RowAreaF, ColAreaF, CoRRAreaF, CoRCAreaF, CoCCAreaF)
points_foerstner (ImageT, 1, 2, 3, 200, 0.3, 'gauss', 'false', RowJunctionsT, ColJunctionsT, CoRRJunctionsT, CoRCJunctionsT, CoCCJunctionsT, RowAreaT, ColAreaT, CoRRAreaT, CoRCAreaT, CoCCAreaT)
* Step3
proj_match_points_ransac (ImageF, ImageT, RowJunctionsF, ColJunctionsF, RowJunctionsT, ColJunctionsT, 'ncc', 21, 0, 0, 480, 640, 0, 0.5, 'gold_standard', 1, 4364537, ProjMatrix, Points1, Points2)
* Step4
ProjMatrices := [ProjMatrices,ProjMatrix]
* Accumulate the point matches and number of point matches.
Rows1 := [Rows1,subset(RowJunctionsF,Points1)]
Cols1 := [Cols1,subset(ColJunctionsF,Points1)]
Rows2 := [Rows2,subset(RowJunctionsT,Points2)]
Cols2 := [Cols2,subset(ColJunctionsT,Points2)]
NumMatches := [NumMatches,|Points1|]
*
gen_cross_contour_xld (PointsF, RowJunctionsF + (F - 1) * 500, ColJunctionsF, 6, rad(45))
gen_cross_contour_xld (PointsT, RowJunctionsT + (T - 1) * 500, ColJunctionsT, 6, rad(45))
*
RowF := subset(RowJunctionsF,Points1) + (F - 1) * 500
ColF := subset(ColJunctionsF,Points1)
RowT := subset(RowJunctionsT,Points2) + (T - 1) * 500
ColT := subset(ColJunctionsT,Points2)
gen_empty_obj (Matches)
for K := 0 to |RowF| - 1 by 1
gen_contour_polygon_xld (Match, [RowF[K],RowT[K]], [ColF[K],ColT[K]])
concat_obj (Matches, Match, Matches)
endfor
* Now display the extracted data.
dev_set_color ('blue')
dev_display (Matches)
dev_set_color ('green')
dev_display (PointsF)
dev_display (PointsT)
endfor
disp_message (WindowHandle, 'Click \'Run\'\nto continue', 'window', 2980 / 4 - 50, 12, 'black', 'true')
stop ()
* Finally, we can generate the mosaic image from the projective transformations.
gen_projective_mosaic (Images, MosaicImage, 2, From, To, ProjMatrices, 'default', 'false', MosaicMatrices2D)
get_image_size (MosaicImage, Width, Height)
dev_set_window_extents (-1, -1, Width / 3, Height / 3)
dev_clear_window ()
dev_display (MosaicImage)
disp_message (WindowHandle, 'Projective mosaic', 'window', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'Click \'Run\'\nto continue', 'window', Height / 3 - 50, 12, 'black', 'true')
stop ()
* To show more clearly that the folds visible in the image do not result from the
* mosaicking, we display the seams between the images in the mosaic image.
* This can be done most easily by creating an image that contains the border
* of the images, generating a mosaic from it, and segmenting the resulting
* mosaic image.
get_image_size (Image, Width, Height)
gen_image_const (ImageBlank, 'byte', Width, Height)
gen_rectangle1 (Rectangle, 0, 0, Height - 1, Width - 1)
paint_region (Rectangle, ImageBlank, ImageBorder, 255, 'margin')
gen_empty_obj (ImagesBorder)
for J := 1 to 6 by 1
concat_obj (ImagesBorder, ImageBorder, ImagesBorder)
endfor
gen_projective_mosaic (ImagesBorder, MosaicImageBorder, 2, From, To, ProjMatrices, 'default', 'false', MosaicMatrices2D)
threshold (MosaicImageBorder, Seams, 128, 255)
dev_clear_window ()
dev_display (MosaicImage)
disp_message (WindowHandle, 'Seams between the\nimages', 'window', 12, 12, 'black', 'true')
dev_set_color ('yellow')
dev_display (Seams)
disp_message (WindowHandle, 'Click \'Run\'\nto continue', 'window', 550, 12, 'black', 'true')
stop ()
*
bundle_adjust_mosaic (6, 1, From, To, ProjMatrices, Rows1, Cols1, Rows2, Cols2, NumMatches, 'rigid', MosaicMatrices2D, Rows, Cols, Error)
* Now, we can generate the mosaic image from the rigid transformations.
gen_bundle_adjusted_mosaic (Images, MosaicImageRigid, MosaicMatrices2D, 'default', 'false', TransMatrix2D)
get_image_size (MosaicImageRigid, Width, Height)
dev_set_window_extents (-1, -1, Width / 3, Height / 3)
dev_clear_window ()
dev_display (MosaicImageRigid)
disp_message (WindowHandle, 'Rigid mosaic', 'window', 12, 12, 'black', 'true')
Halcon---图像拼接 Sample学习一. gen_projective_mosaic
于 2023-08-14 15:00:30 首次发布