Halcon学习之边缘提取

  • Post author:
  • Post category:其他


转自:http://qing.blog.sina.com.cn/2316220871/8a0eb9c733002oyv.html


从今天起不是所有新遇到的函数都加黑体,重要的我会写出参数对象并加粗,不重要的只是文字解释即可




1,


autobahn.hdev: Fast detection of lane markers


控制语句

MinSize:=30

get_system(‘init_new_image’, Information)

得到当前halcon系统的参数值(这里执行后得到information的值为’ true’)

set_system(‘init_new_image’, ‘false’)

gen_grid_region(Grid, MinSize,MinSize,’lines’,512,512)

创建一个网格区域

注意,这里用网格是为了减少处理的内容从而提高速度,如图是后面计算出来的边缘幅值



Halcon学习之边缘提取1-4




clip_region(Grid, StreetGrid, 130,10,450,502)

把一个region剪切成一个矩形

。。。

读图并显示剪切后的网格

。。。

for i:=0 to 28 by 1

read_image( ActualImage, ‘autobahn/scene_’+(i$’02’))

注意:这里的i$  意义是i的值去两位,即01,  02等等



reduce_domain( ActualImage, StreetGrid, Mask)


sobel_amp( Mask, Gradient,’sum_abs’, 3)



sobel_amp(


Image


:


EdgeAmplitude


:


FilterType


,


Size


: )计算边缘的幅值




threshold( Gradient, Points, 20, 255)

dilation_rectangle1(Points, RegionDilation, MinSize, MinSize)

使用矩形模板进行膨胀运算得到如图大致区域

Halcon学习之边缘提取1-4


reduce_domain(ActualImage, RegionDilation, StripGray)

threshold(StripGray,Strip, 190,255)

把白色的线从候选区域中提取出来


fill_up(Strip,RegionFillUp)


填充内容

显示

endfor

set_system(‘init_new_image’, ‘ true’ )




2,

background_seg.hdev

从给定区域中找到背景的连通的区域


read_image

sobel_amp

threshold

得到提取出来的边缘Edges

background_seg(Edges,BackgroundRegions)


background_seg(


Foreground


:


BackgroundRegions


: : )


注意,这里Edges是前景区域,background_seg是为了根据给定的前景,找出连通的背景。这个操作通常在边缘检测之后(边缘作为前景),利用是否接近来判断连通性(使用4-neighborhood来判断连通与否)

fill_up_shape




3,

bandpass_image.hdev

read_image

bandpass_image(Bk45,Lines, ‘lines’)

带通滤波器找出所有的线条(滤波器利用了sobel_amp 来检测线条)

threshold(Lines,Region,128,255)

skeleton(Region,Skeleton)


skeleton(


Region


:


Skeleton


: : )


检测区域的骨架

dev_set_colored(12)

gen_contours_skeleton_xld(Skelton,Contours, 5, ‘filter’)



gen_contours_skeleton_xld(

Skeleton





:





Contours





:





Length

,





Mode





: )




生成骨架边界线段,这里Length指的是线段最少应该包含的点数,Mode:

如果Mode是filter, 直接取边界线存为contours,因为边界线在‘连接会和的点’处被分开,很长的边缘可能被分成几个短的线段。

用‘generalize1’,如果线段长度不够Length,会自动生成满足条件的线段

用‘generalize2’,如果一个线段的两端都是‘连接点’,这个线段会保留并且认为是之前的线段的一部分。

dev_display显示结果




4,

close_edges.hdev

sobel_amp

threshold

使用边界的幅值图像来完整边界之间的间隙

例子中先把得到的幅值图进行筛选分离,得到可能不完整的contours,这时候需要用完整的幅值图像EdgeImage信息来完善滤波后的边界Edges,从而得到完整的边界信息ClosedEdges


close_edges_length(


Edges


,


Gradient


:


ClosedEdges


:


MinAmplitude


,


MaxGapLength


: )除了完成上面CloseEdge功能之外, 在MaxGapLength之内(限制作用),有意义的边缘点都会被加入到边界信息中

















5,

derivate_gauss.hdev


a)

高斯导数滤波用作

平滑滤波器

(使用分水岭watershed得到contours)(用于很多小块的图像)
read_image…

derivate_gauss(Meningg5,Smoothed, 2, ‘none’)

derivate_gauss(

Image

:

DerivGauss

(这里指输出图像) :

Sigma

,

Component

: )

用一个图片Image和一个高斯函数的导数求卷积,从而计算出不同的特征值。sigma控制高斯函数,当sigma为一个值时候,行和列的方向上sigma相同,当sigma为两个值时候,第一个控制列的程度,第二个控制行的程度。‘none’这里指Smoothing only,其余参数请自行查看帮助文档。



convert_image_type(Smoothed, SmoothedByte,’byte’)


convert_image_type(


Image


:


ImageConverted


:


NewType


: )

转换图像类型



watersheds(SmoothedByte, Basins, Watersheds)

watersheds(

Image

:

Basins

,

Watersheds

: : )
找出图片的分水岭和凹陷块区域,用于图片分割
b) 高斯导数滤波用作

边缘检测
read_image….
derivate_gauss(Image,

GradientAmp1

, 1.5,’gradient’)
threshold….

c)

高斯导数滤波用作

角检测​
derivate(Image, Det, 1.5, ‘det’)
threshold(Det, Corners, 20, 1000000)

d )

高斯导数滤波用作

边缘检测( 二阶导数)
derivate_gauss(Image, EdgesAreZero, 3, ‘2nd_ddg’)

zero_crossing(EdgesAreZero, Edges)



zero_crossing returns the zero crossings of the input image as a region. A pixel is accepted as a zero crossing if its gray value (in

Image

) is zero, or if at least one of its neighbors of the 4-neighborhood has a different sign.

This operator is intended to be used after edge operators returning the second derivative of the image (e.g.,

laplace_of_gauss

), which were possibly followed by a smoothing operator. In this case, the zero crossings are (candidates for) edges.)


6, 各种滤波


diff_of_gauss        +              zero_crossing

laplace_of_gauss   +             zero_crossing

derivate_gauss      +             zero_crossing

7,显示一个保存边界的XLD对象


read_image


edges_sub_pix(Image,Edges, ‘mderiche2’, 0.7, 10,20)

使用Deriche, Lanser, Shen, or Canny滤波器来精确检测边缘



edges_image(Image, ImaAmp, ImaDir,’mderiche2′, 0.7,’nms’,10, 20)

使用Deriche, Lanser, Shen, or Canny滤波器来检测边缘,并得到边缘的幅值和方向



count_seconds(a1)  记录当前时间
disp_xld(Edges, WindowID)

count_seconds(a2)
Time:=a2-a1
记录执行下面一步所用的时间



8, edge_segments.hdev 边缘分割
read_image…

get_image_size(Image, Width, Height)
dev_open_window_fit_image
显示
edges_image(Image, ImaAmp, ImaDir,’lanser2′, 0.5,’nms’,20, 40)
lanser精度很高, 用来计算边界
threshold
connection
用来提取出边界
边界的显示:
count_obj(ConnectedRegions, Number)
gen_empty_obj(XLDContours)   用来存储边界
for i:=1 to Number by 1

select_obj(ConnectedRegions, SingleEdgeObject, i)



split_skeleton_lines(SingleEdgeObject, 2, BeginRow, BeginCol, EndRow, EndCol)



split_skeleton_lines(


SkeletonRegion


: :


MaxDistance


:


BeginRow


,


BeginCol


,


EndRow


,


EndCol


)


寻找骨骼线,删除小分支,得到骨骼线的头和尾节点,主意这里可能产生的头和尾是一个数组,其中可能有多个头节点和尾节点

for k:= 0 to |BeginRow|-1 by 1

gen_contour_polygon_xld

( Contour,[BeginRow[k], endRow[k]], [BeginCol[k], EndCol[k]])

concat_obj(XLDContours, Contour, XLDContours)
把两个对象连起来
endfor
endfor