测量的目的就是得到测量点的图像坐标
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)
5. 平滑过后预处理就结束了。要开始找测量点了,找边缘最常用的就是找梯度求导了derivate_funct_1d (fuction: Mode: Derivative),其中Mode = first表示一阶导数,second表示求二阶导数。在求导过后找点就是边缘点了,很明显导数为0的点就是边缘点。但是如果直接找0点的话,会找到很多,我们不太好筛选,所以我们选择求二阶导数找最大值来筛选。先设定一个阈值,大于这个阈值的点才被定为测量点。下图是对上图Profile
Line进行一阶导和二阶导
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)
这样每一个测量点的坐标就可以计算出来了,计算图解见下图:
- 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[i], 'constant', Y)
- if(Y > MinimumMagnitudeOfSecondDerivative)
- * 写成PositionOfSalientLinep[i] := ZeroCrossings[i]不可以
- PositionOfSalientLine := [PositionOfSalientLine,ZeroCrossings[i]]
- 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[i]
- Col := ColLine[i]
-
- * 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
|