* This example program shows how several images of a PCB can be combined

* into a large mosaic image of the PCB.  The program shows how to use

* proj_match_points_ransac and gen_projective_mosaic to achieve this.

* Please note that the PCB has some degradations on its surface, which look

* like folds and may easily be mistaken as the seams between the images

* in the mosaic image.  To show that this is not the case, the program

* also displays the true seams of the mosaic image.

**本示例程序显示了PCB的几个图像可以如何组合到PCB的大型拼接图像中。

*该程序显示如何使用proj_match_points_rations_transac和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')

* Read in the images and show them one-by-one.  Please not the fold-like

* degradations running across the 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', 'image', -1, -1, 'black', 'true')

wait_seconds (1)

endfor

disp_continue_message (WindowHandle, 'black', 'true')

stop ()

* To show the point matches that are used to compute the projective

* transformation between the images, we will show all images in a large

* tiled image with some space between the images so that the extents

* of the images are easily visible.

*要显示用于计算图像之间的投影变换的点匹配,我们将以大的平铺图像显示所有图像,

*并在图像之间留有一些空间,以使图像的范围容易看到

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 ()

* Now we compute point matches between the five pairs of images and with this

* the projective transformation between the image pairs.  Note that the code

* below calls the point operator for each image pair.  Since the images form

* a strip, with a little book keeping we could make the process a little more

* efficient by saving the points from the last iteration (ImageT in pair J will

* be identical to ImageF in pair J+1).  This is not done here because such an

* optimization would be quite cumbersome in the general case where the images

* can lie in a general configuration that cannot be represented by a strip.

**现在我们计算五对图像之间的点匹配,并且通过这些图像对之间的投影变换。 请注意,

*下面的代码调用每个图像对的点运算符。由于图像形成一个条带,有一点小书保留,我们

*可以通过保存最后一次迭代中的点(J对中的ImageT与J + 1中的ImageF相同)来使该过

*程更有效。 这不是在这里做的,因为在一般情况下,这样的优化将是相当麻烦的,其中

*图像可以位于不能由条带表示的一般配置中。

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|

* We need a variable to accumulate the projective transformation matrices.

*我们需要一个变量来积累投影变换矩阵。

ProjMatrices := []

* Furthermore, since we want to create a rigid mosaic below we need to

* accumulate all the point correspondences and the number of matches per

* image pair.

*此外,由于我们要在下面创建精确镶嵌,所以我们需要积累所有对应的点和每个图像对的匹配数。

Rows1 := []

Cols1 := []

Rows2 := []

Cols2 := []

NumMatches := []

* Now we can determine the transformations between the five image pairs.

*现在我们可以确定五个图像对之间的变换。

for J := 0 to Num - 1 by 1

F := From[J]

T := To[J]

select_obj (Images, ImageF, F)

select_obj (Images, ImageT, T)

* Extract the points in both images.

* Extract the points in both images.*提取两个图像中的点。

* 参数2:用于计算梯度的平滑量。 如果平滑是平均值,则忽略SigmaGrad。

* 参数3:用于梯度积分的平滑量。

* 参数4:在优化功能中使用的平滑量。

* 参数5:不均匀图像区域的分割阈值。

* 参数6:点区域的分割阈值。

* 参数7:平滑法。

* 参数8:消除多重检测点。

* 参数9,10:检测到的连接点的行、列坐标。

* 参数11,12:检测结点的协方差矩阵的行、列部分。

* 参数13,14:检测到的区域点的行、列坐标。

* 参数15,16:检测区域的协方差矩阵的行、列部分点。

* 参数17:检测区域的协方差矩阵的混合部分点。

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)

* Determine the point matches and the transformation for the current

* image pair.

*参数3、4:图像1中特征点的行、列坐标。

*参数5、6:图像2中特征点的行、列坐标。

*参数7:灰度值比较指标。

*参数8:灰度值掩码的大小。

*参数9、10:平均行、列坐标移位。

*参数11、12:匹配搜索窗口的一半高、宽度。

*参数13:旋转角度范围

*参数14:灰度值匹配的阈值。

*参数15:变换矩阵估计算法。

*参数16:变换一致性检查阈值。

*参数17:寻找随机数发生器。

*参数18:均匀投影变换矩阵。

*参数19:图像1中匹配输入点的指标。

*参数20:图像2中匹配输入点的指标。

*通过查找点之间的对应关系,计算两个图像之间的投影变换矩阵。

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)

* 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) * 500, ColJunctionsF, 6, rad(45))

gen_cross_contour_xld (PointsT, RowJunctionsT + (T - 1) * 500, 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) * 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.

*最后,我们可以从投影变换生成马赛克图像。

*参数3:中央输入图像的索引。

*参数4:转换的源图像的索引。

*参数5:转换的目标图像的索引。

*参数6:3x3射影变换矩阵的数组。

*参数7:将图像叠加在马赛克上。

*参数8:输入图像的域是否也应该被转换?

*参数9:由3x3投影变换矩阵构成的阵列,它决定了图象在镶嵌中的位置。

*将多个图像合并成一个镶嵌图像。

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) //Seams接缝

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 ()

* If you look very closely at the projective mosaic above, you may note that

* there is a very slight projective distortion in the mosaic.  This happens

* because the transformations cannot be determined with perfect accuracy

* because of very small errors in the point coordinates due to noise.  Because

* of the strip configuration, essentially the overlapping area between the image

* pairs can act like a hinge around which the images may rotate out of the image

* plane.  In this example, we know that the mapping between the images must

* be a rigid transformation.  If we want to force the transformation to be rigid

* we can simply use bundle_adjust_mosaic.

*如果你仔细观察上面的投影马赛克,你可能会注意到马赛克中有一个非常轻微的投射失真。

*发生这种情况是因为无法以完美的准确度确定转换因为噪音引起的点坐标误差很小。

*由于条带配置,基本上,图像对之间的重叠区域可以像铰链一样起作用,图像可绕其旋转出图像平面。

*在这个例子中,我们知道图像之间的映射必须是刚性变换。 如果我们想强制转换为刚性,

*我们可以简单地使用bundle_adjust_mosaic。

*参数1:用于校准的不同图像的数量。

*参数2:参考图像的索引。

*参数3:转换的源图像的索引。

*参数4:转换的目标图像的索引。

*参数5:3x3射影变换矩阵的数组。

*参数6:在相应的源图像中对应点的行坐标。

*参数7:在各自的源图像中对应点的列坐标。

*参数8:在各自的目标图像中对应点的行坐标。

*参数9:在各自的目标图像中对应的点的列坐标。

*参数4:在各自的图像对中对应的点的数量。

*参数5:要使用的转换类。

*参数6:由3个投影变换矩阵构成的阵列,它们决定了图像在镶嵌中的位置。

*参数7:由bundle调整所重建的点的行坐标。

*参数8:由bundle调整重建的点的列坐标。

*参数9:每个重建点的平均误差。

*对图像马赛克进行捆绑调整。

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')

gen_projective_mosaic(Halcon例子)的更多相关文章

  1. 激光三角测量(sheet of light)halcon示例详解 Reconstruct_Connection_Rod_Calib.hdev 三维重建

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11555100.html 前言:最近项目用到halcon的3d模板匹配,三维重建,相机标定,所以 ...

  2. halocn/C++ (第一篇)

        在使用C++编写halcon之前,确定自己有较好的C++基础,并熟悉一套开发平台如VC   Programmers_guide.pdf chapter7中有关于creating Aplicat ...

  3. halcon算子

    halcon的算子列表   Chapter 1 :Classification 1.1 Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一个训练样 ...

  4. halcon的算子列表

    Chapter 1 :Classification 1.1 Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一个训练样本添加到一个高斯混合模型的训 ...

  5. 《zw版·delphi与halcon系列原创教程》zw版_THOperatorSetX控件函数列表 v11中文增强版

    <zw版·delphi与halcon系列原创教程>zw版_THOperatorSetX控件函数列表v11中文增强版 Halcon虽然庞大,光HALCONXLib_TLB.pas文件,源码就 ...

  6. Halcon 常用算子使用场合

    Chapter 1 :Classification 1.1 Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一个训练样本添加到一个高斯混合模型的训 ...

  7. Halcon算子解释

    Halcon算子解释大全 Halcon/Visionpro视频教程和资料,请访问 重码网,网址: http://www.211code.com Chapter 1 :Classification 1. ...

  8. HALCON中的算子大全(中英对照)

    HALCON中的算子大全(中英对照) Chapter 1 :Classification1.1 Gaussian-Mixture-Models1.add_sample_class_gmm功能:把一个训 ...

  9. HALCON学习之算子大全

    1.1 Gaussian-Mixture-Models 1.add_sample_class_gmm 功能:把一个训练样本添加到一个高斯混合模型的训练数据上. 2.classify_class_gmm ...

随机推荐

  1. 分析器错误信息: 服务器标记不能包含 <% ... %> 构造

    我的程序如下:<form runat="server"><TABLE><TR><TD>用户名:</TD><TD&g ...

  2. Git 之 git原理简介

    这里只是很简单.超简单的介绍下git,为的是方便记忆: 本地仓库分为三个部分:工作区.暂存区.仓库区,其中暂存区和仓库区属于版本区. 对于文件的操作,需要从工作区----> 暂存区 ----&g ...

  3. [置顶] HashTable vs HashMap

    转载请注明出处:http://blog.csdn.net/crazy1235/article/details/76686891 HashTable vs HashMap 构造函数 hash函数 syn ...

  4. C#读写 AB PLC 直接通过节点来读写数据 读写 AllenBradley PLC

    本文将使用一个Github开源的组件库技术来读写AB PLC,使用的是基于以太网的实现,不需要额外的组件,读取操作只要放到后台线程就不会卡死线程,本组件支持超级方便的高性能读写操作 官网:http:/ ...

  5. JQuery和Zepto的差异(部分)

    1.width()/height() Zepto.js: 由盒模型(box-sizing)决定 jQuery: 忽略盒模型,始终返回内容区域的宽/高(不包含 padding.border) jQuer ...

  6. 1029:Ignatius and the Princess IV

    题目大意是找出数组中出现次数超过一半的数. 基本思想:每遇到两个不同的数就消掉,设一个计数器就行了.   存出现次数最大的那个数的出现次数. 当下一个数与当前的数不同时,计数器减一,相同,则加一. 实 ...

  7. java中读取配置文件

    若是Javaweb项目,项目运行于tomcat或其他容器时,可以使用下面方式来获取文件的输入流 1.当属性文件放在src下面时 InputStream is = Thread.currentThrea ...

  8. vCenter 6.5安装

    http://guanjianfeng.com/archives/1160269 最近,VMware发布了vSphere 6.5版本,之前的最新版本为6.0.新版本已经开始试行使用HTML5来管理vS ...

  9. Mplayer1.0rc2移植到am335x开发板

    因项目需要媒体播放器,所以准备使用QT+Mplayer来做,但遇到了屏幕闪烁的问题,无法满足需求. 1.参考<mplayer 移植到 arm 心得> ,http://blog.csdn.n ...

  10. 在vc++上简单搭建环境(包括文件引用)

    1,triplet_head.h 文件 #define TRUE 1 #define FALSE 0 #define OK 1 #define ERROR 0 #define OVER_FLOW -2 ...