halcon第十六讲,图片拼接

一、检测目的
由于一次很难将一个产品拍全,所以我们要多次拍照,然后让图片拼接成一张图。
二、原图


image.png
image.png
image.png

三、代码实现

dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 500, 500, 'white', WindowHandle)
dev_set_color ('green')
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')

*创建一个空的对象元组
gen_empty_obj (Images)
*遍历文件夹图像
iImgNum:=3
ImageFiles:='Image2/'
for J := 1 to iImgNum by 1
    read_image (Image, 'Image2/'+J+'.bmp')
    concat_obj (Images, Image, Images)
    dev_display (Image)
    disp_message (WindowHandle, 'Image ' + J$'d', 'image', -1, -1, 'black', 'true')
    wait_seconds (1)
endfor

*更改活动图形窗口的位置和大小
dev_set_window_extents (-1, -1, 1000/3 ,4600/3 )
*将多个图像对象平铺到具有显式定位信息的大图像中
tile_images_offset (Images, TiledImage, [0,1000,2000], [0,0,0], [-1,-1,-1], [-1,-1,-1], [-1,-1,-1], [-1,-1,-1], 3000,4600)
dev_clear_window ()
dev_display (TiledImage)
stop ()

dev_clear_window ()
dev_display (TiledImage)
disp_message (WindowHandle, 'Point matches', 'window', 12, 3, 'black', 'true')
*定义图像对,即哪个图像应该映射到哪个图像。
From := [1,2]
To := [2,3]
Num := |From|
*一个变量来积累投影变换矩阵。
ProjMatrices := []
*此外,由于我们要在下面创建精确镶嵌,所以我们需要积累所有对应的点和每个图像对的匹配数。
Rows1 := []
Cols1 := []
Rows2 := []
Cols2 := []
NumMatches := []

for J := 0 to Num - 1 by 1
    F := From[J]
    T := To[J]
    select_obj (Images, ImageF, F)
    select_obj (Images, ImageT, T)
   
    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)
    *通过查找点之间的对应关系,计算两个图像之间的投影变换矩阵。
    proj_match_points_ransac (ImageF, ImageT, RowJunctionsF, ColJunctionsF, RowJunctionsT, ColJunctionsT, 'ncc', 21, 0, 0, 1000, 1000, 0, 0.5, 'gold_standard', 1, 4364537, ProjMatrix, Points1, Points2)
    * Accumulate the transformation matrix.
    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|]
    * Generate crosses that represent the extracted points in the tiled image.
    * Note that we have to take the row offsets of the images in the tiled image
    * into account.
    *生成表示平铺图像中提取点的十字。 请注意,我们必须考虑平铺图像中的图像的行偏移量。
    *参数1:生成XLD轮廓。
    *参数2,3:输入点的行、列坐标
    *参数4:横杠的长度。
    *参数5:取向的十字架。
    gen_cross_contour_xld (PointsF, RowJunctionsF + (F - 1) * 1000, ColJunctionsF, 6, rad(45))
    gen_cross_contour_xld (PointsT, RowJunctionsT + (T - 1) * 1000, ColJunctionsT, 6, rad(45))
    * Generate a representation of the matched point pairs as lines.  We create
    * XLD contours from the lines so that we can zoom into the graphics window
    * to take a closer look at the matches.
    *生成匹配点对的表示为行。 我们从行中创建XLD轮廓,
    *以便我们可以放大图形窗口,以便仔细观察匹配。
    *t := subset(t,i) 选取数组t中的第i个元素
    RowF := subset(RowJunctionsF,Points1) + (F - 1) * 1000
    ColF := subset(ColJunctionsF,Points1)
    RowT := subset(RowJunctionsT,Points2) + (T - 1) * 1000
    ColT := subset(ColJunctionsT,Points2)
    gen_empty_obj (Matches)
    for K := 0 to |RowF| - 1 by 1
        *从多边形(给定为元组)生成XLD轮廓。
        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
stop ()

*最后,我们可以从投影变换生成马赛克图像。
*将多个图像合并成一个镶嵌图像。
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 ()

*为了更清楚地显示图像中可见的折叠不是由镶嵌形成的,
*我们将显示镶嵌图像中的图像之间的接缝。 这可以通过创建包含图像边框的图像,
*从中生成镶嵌并分割生成的镶嵌图像来最容易地完成。
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 iImgNum 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)//Seams接缝
disp_message (WindowHandle, '各图像间的接缝', 'window', 12, 12, 'black', 'true')
dev_set_color ('yellow')
dev_display (Seams)
disp_message (WindowHandle, 'Click \'Run\'\nto continue', 'window', 550, 12, 'black', 'true')
*将窗口内容写入文件
dump_window (WindowHandle, 'bmp', ImageFiles+'拼接缝截图')
stop ()
*对图像马赛克进行捆绑调整。
bundle_adjust_mosaic (iImgNum, 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, '精确拼接图', 'window', 12, 12, 'black', 'true')
dump_window (WindowHandle, 'bmp', ImageFiles+'精确拼接截图')

运行结果:


image.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342