* 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. hdu 3694 10 福州 现场 E - Fermat Point in Quadrangle 费马点 计算几何 难度:1

    In geometry the Fermat point of a triangle, also called Torricelli point, is a point such that the t ...

  2. oracle创建定时器详解|interval属性

    定时任务首先先创建定时任务中的存储过程 create or replace procedure pro_jggl as                                          ...

  3. Scrum立会报告+燃尽图(3)选题

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2193 一.小组介绍 组长:刘莹莹 组员:朱珅莹 孙韦男 祝玮琦 王玉潘 ...

  4. L187 DKK2

    Why can millions of hairs grow from our heads, and yet our palms手掌 and the soles of our feet are as ...

  5. opencv:基于颜色空间的肤色检测方法

    参考链接:https://www.cnblogs.com/skyfsm/p/7868877.html

  6. Winform开发常用控件之DataGridView的简单数据绑定——自动绑定

    DataGridView控件可谓是Winform开发的重点控件,对于数据的呈现和操作非常方便,DataGridView可谓是既简单又复杂.简单在于其已经集成了很多方法,复杂在于可以使用其实现复杂的数据 ...

  7. OK335xS pwm buzzer Linux driver hacking

    /**************************************************************************** * OK335xS pwm buzzer L ...

  8. 前端imageBuffer设置图片src(后端到前端直传buffer)

    本质为buffer转base64 let bytes = new Uint8Array(imageBuffer.data); let data = ""; let len = by ...

  9. 用 dotTrace 进行性能分析时,各种不同性能分析选项的含义和用途

    对 .NET 程序进行性能分析,dotTrace 能应对绝大多数的场景.在开启一个进程进行性能分析之前,我们会看到一些性能分析选项(Profiler Options).本文将介绍这几个选项的含义,并用 ...

  10. iMac 10年

    10年前,也就是1998年8月15号,Apple 推出了蓝色半透明的 iMac G3(指上市,发布时间为当年5月6号),当年销售200万台,从此开启了它的一个时代,人们一旦说起设计,那么 Apple ...