Trevan
管理员
管理员
  • 最后登录2017-04-26
  • 发帖数989
  • 金币18335枚
  • 贡献勋章5枚
阅读:2971回复:7

Halcon 1D测量(2) :测量特定灰度值像素

楼主#
更多 发布于:2014-06-25 17:48
测量的目的就是得到测量点的图像坐标
1. 首先在测量之前我们明白,测量点和背景之间一定有灰度值的差异,这是前提。
2. 和前面一样,首先必须找到一个ROI。然后通过gen_measure_rectangle2得到一个测量的句柄。
3. 由于我们不是测量边缘对,所以要换方法了,但是和测量边缘对的原理相同,我们需要先得到灰度值分布(gray value Profile),算子measure_projection可以找到,但是注意,他返回的是原始的,没有经过平滑滤波的“线条”上的灰度值,注意这里的Profile只是一个元组,也就是从0开始间隔1采集到的像素值(把Profile均分为主轴长度个像素Length1*2,当然像素值要插值),我们所要找的测量点必须要在这个“线条”上,然后才能得到测量点的坐标。
4. 为了减小噪声的影响,使结果更准确,必须先对Profile进行平滑滤波smooth_funct_1d_gauss,但是前面说过Profile是离散的点,必须要先把这些点使用create_funct_1d_array连接成一个函数才可以对其进行函数操作。下图是对某图Profile像滤波过后的灰度分布(注意根据横坐标的长度可以看出ROI Length1 = 220)

图片:1.jpg



5. 平滑过后预处理就结束了。要开始找测量点了,找边缘最常用的就是找梯度求导了derivate_funct_1d (fuction: Mode: Derivative),其中Mode = first表示一阶导数,second表示求二阶导数。在求导过后找点就是边缘点了,很明显导数为0的点就是边缘点。但是如果直接找0点的话,会找到很多,我们不太好筛选,所以我们选择求二阶导数找最大值来筛选。先设定一个阈值,大于这个阈值的点才被定为测量点。下图是对上图Profile Line进行一阶导和二阶导
 

图片:2.jpg



6. get_y_value_funct_1d函数你给他提供X值它给你返回Y值,Y值就是我们要筛选的点,过滤后剩下的X值,就是我们需要的测量点的位置信息,但是这个位置是相对于Profile的,也就是从Profile开始点(Start)到测量点的距离(Position of line)。我们需要将它转换成他对应的坐标。我们已知的就是ROI的中心点坐标和ROI的长和宽。一般情况下,中心点的坐标是四舍五入的,Length1的长度是向上取整的。            
RowStart =└ (Row + 0.5)┘ +└ Length1┘ · sin(Phi)
 ColStart = └ (Column + 0.5)┘ −└ Length1┘ · cos(Phi)



RowLine = RowStart − PositionOfSalientLine · sin(Phi)
ColLine = ColStart + PositionOfSalientLine · cos(Phi)



Hdevelop中这样写:
RowStart := floor(Row+0.5)+floor(Length1)*sin(Phi)
 ColStart := floor(Column+0.5)-floor(Length1)*cos(Phi)



RowLine = RowStart − PositionOfSalientLine · sin(Phi)
 ColLine = ColStart + PositionOfSalientLine · cos(Phi)



这样每一个测量点的坐标就可以计算出来了,计算图解见下图:

图片:3.jpg








[cpp] view plaincopyprint?
  1. dev_close_window()  
  2. read_image (Image, 'D:/picture/20131005110428.jpeg')  
  3. decompose3 (Image, Red, Green, Blue)  
  4. rgb3_to_gray (Red, Green, Blue, ImageGray)  
  5. write_image (ImageGray, 'tiff', 0, 'C:/Users/YangK/Desktop/cizi.tiff')  
  6. get_image_size (ImageGray, Width, Height)  
  7.  
  8. dev_open_window (0, 0, Width, Height, 'black', WindowHandle)  
  9. dev_set_draw ('margin')  
  10. dev_set_color ('red')  
  11. dev_display (ImageGray)  
  12.  
  13.  
  14. Row := 335.5  
  15. Column := 348.5  
  16. Angle := -2.22819  
  17. Length1 := 72.0069  
  18. Length2 := 5  
  19. * Length2 := 7.63302  
  20.  
  21. *draw_rectangle2_mod (WindowHandle, 100, 100, 0, 100, 50, Column1, Row2, Column2, Length1, Length2)  
  22. gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)  
  23. gen_rectangle2 (Rectangle, Row, Column, Angle, Length1, Length2)  
  24. measure_projection (Image, MeasureHandle, GrayValues)  
  25. create_funct_1d_array (GrayValues, Function)  
  26. smooth_funct_1d_gauss (Function, 0.3, SmoothedFunction)  
  27. derivate_funct_1d (SmoothedFunction, 'first', FirstDerivative)  
  28. derivate_funct_1d (SmoothedFunction, 'second', SecondDerivative)  
  29.  
  30. zero_crossings_funct_1d (FirstDerivative, ZeroCrossings)  
  31. MinimumMagnitudeOfSecondDerivative := 8  
  32. PositionOfSalientLine := []  
  33. for i:=0 to |ZeroCrossings|-1 by 1  
  34.    get_y_value_funct_1d (SecondDerivative, ZeroCrossings, 'constant', Y)  
  35.    if(Y > MinimumMagnitudeOfSecondDerivative)  
  36.        * 写成PositionOfSalientLinep := ZeroCrossings不可以  
  37.        PositionOfSalientLine := [PositionOfSalientLine,ZeroCrossings]  
  38.    endif  
  39. endfor  
  40. stop()  
  41.  
  42. RowStart := floor(Row+0.5)+floor(Length1)*sin(Angle)  
  43. ColStart := floor(Column+0.5)-floor(Length1)*cos(Angle)  
  44.  
  45. RowLine := RowStart-PositionOfSalientLine*sin(Angle)  
  46. ColLine := ColStart+PositionOfSalientLine*cos(Angle)  
  47.  
  48. NumRows := |RowLine|  
  49. NumCols := |ColLine|  
  50. Num := min([NumRows, NumCols])  
  51. for i := 0 to Num-1 by 1  
  52.    Row := RowLine  
  53.    Col := ColLine  
  54.      
  55. *   RowStart := Row - Length2*sin(rad(90) - Angle)  
  56. *   RowEnd := Row + Length2*sin(rad(90) - Angle)  
  57. *   ColStart := Col - Length2*cos(rad(90) - Angle)  
  58. *   ColEnd := Col + Length2*cos(rad(90) - Angle)  
  59.      
  60.    RowStart := Row+Length2*cos(Angle)  
  61.    RowEnd := Row-Length2*cos(Angle)  
  62.    ColStart := Col+Length2*sin(Angle)  
  63.    ColEnd := Col-Length2*sin(Angle)  
  64.      
  65.    gen_contour_polygon_xld (Marker, [RowStart,RowEnd], [ColStart,ColEnd])  
  66.    dev_set_color ('white')  
  67.    dev_set_line_width(1)  
  68.    dev_display (Marker)  
  69.    
  70. endfor  

dev_close_window()
read_image (Image, 'D:/picture/20131005110428.jpeg')
decompose3 (Image, Red, Green, Blue)
rgb3_to_gray (Red, Green, Blue, ImageGray)
write_image (ImageGray, 'tiff', 0, 'C:/Users/YangK/Desktop/cizi.tiff')
get_image_size (ImageGray, Width, Height)

dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
dev_set_draw ('margin')
dev_set_color ('red')
dev_display (ImageGray)


Row := 335.5
Column := 348.5
Angle := -2.22819
Length1 := 72.0069
Length2 := 5
* Length2 := 7.63302

*draw_rectangle2_mod (WindowHandle, 100, 100, 0, 100, 50, Column1, Row2, Column2, Length1, Length2)
gen_measure_rectangle2 (Row, Column, Angle, Length1, Length2, Width, Height, 'nearest_neighbor', MeasureHandle)
gen_rectangle2 (Rectangle, Row, Column, Angle, Length1, Length2)
measure_projection (Image, MeasureHandle, GrayValues)
create_funct_1d_array (GrayValues, Function)
smooth_funct_1d_gauss (Function, 0.3, SmoothedFunction)
derivate_funct_1d (SmoothedFunction, 'first', FirstDerivative)
derivate_funct_1d (SmoothedFunction, 'second', SecondDerivative)

zero_crossings_funct_1d (FirstDerivative, ZeroCrossings)
MinimumMagnitudeOfSecondDerivative := 8
PositionOfSalientLine := []
for i:=0 to |ZeroCrossings|-1 by 1
    get_y_value_funct_1d (SecondDerivative, ZeroCrossings, 'constant', Y)
    if(Y > MinimumMagnitudeOfSecondDerivative)
        * 写成PositionOfSalientLinep := ZeroCrossings不可以
        PositionOfSalientLine := [PositionOfSalientLine,ZeroCrossings]
    endif
endfor
stop()

RowStart := floor(Row+0.5)+floor(Length1)*sin(Angle)
ColStart := floor(Column+0.5)-floor(Length1)*cos(Angle)

RowLine := RowStart-PositionOfSalientLine*sin(Angle)
ColLine := ColStart+PositionOfSalientLine*cos(Angle)

NumRows := |RowLine|
NumCols := |ColLine|
Num := min([NumRows, NumCols])
for i := 0 to Num-1 by 1
    Row := RowLine
    Col := ColLine
    
 *   RowStart := Row - Length2*sin(rad(90) - Angle)
 *   RowEnd := Row + Length2*sin(rad(90) - Angle)
 *   ColStart := Col - Length2*cos(rad(90) - Angle)
 *   ColEnd := Col + Length2*cos(rad(90) - Angle)
    
    RowStart := Row+Length2*cos(Angle)
    RowEnd := Row-Length2*cos(Angle)
    ColStart := Col+Length2*sin(Angle)
    ColEnd := Col-Length2*sin(Angle)
    
    gen_contour_polygon_xld (Marker, [RowStart,RowEnd], [ColStart,ColEnd])
    dev_set_color ('white')
    dev_set_line_width(1)
    dev_display (Marker)
  
endfor


图片:4.jpg



捐助网站请点击 http://www.ihalcon.com/read-6416.html
tzw142
助理工程师
助理工程师
  • 最后登录2017-04-19
  • 发帖数103
  • 金币395枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
沙发#
发布于:2014-06-25 21:58
学习了~~~~~~~~~~~~~
jon_liu
工程师
工程师
  • 最后登录2017-03-14
  • 发帖数189
  • 金币1142枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
板凳#
发布于:2014-06-25 22:08
不错,很详细!!学习了
xiaoshuyi_1979
助理工程师
助理工程师
  • 最后登录2017-04-14
  • 发帖数122
  • 金币516枚
  • 贡献勋章0枚
地板#
发布于:2014-06-30 15:48
          很详细哦,学习了
wangqm
助理工程师
助理工程师
  • 最后登录2014-12-31
  • 发帖数38
  • 金币209枚
  • 贡献勋章0枚
4楼#
发布于:2014-09-01 19:52
一看就是高手学习了...
qingzhuye
工程师
工程师
  • 最后登录2017-03-19
  • 发帖数117
  • 金币712枚
  • 贡献勋章0枚
  • 社区居民
5楼#
发布于:2014-10-30 22:02
楼主真的是高手啊。学习了
gyl_miracle
初学者
初学者
  • 最后登录2016-12-25
  • 发帖数6
  • 金币70枚
  • 贡献勋章0枚
  • 社区居民
6楼#
发布于:2015-12-22 12:14
非常详细,很有用,赞
SuperMessi
初学者
初学者
  • 最后登录2017-01-13
  • 发帖数13
  • 金币39枚
  • 贡献勋章0枚
  • 社区居民
  • 忠实会员
7楼#
发布于:2016-12-05 20:57
楼主真的是高手啊。学习了
游客

返回顶部