問題在 HoughLineTransform 上讓我開始了這個。
HoughLineTransform 將輸入矩陣中的直線段轉換為輸出矩陣中的點。 輸出矩陣中的亮點表示與線中心的角度和距離。 輸出矩陣表示包含線段的線(端點信息大部分丟失)。
在下面的 JSL 中,輸入矩陣是 100x100,一個由 0 和 1 組成的字段。 輸出矩陣維度由nAngle和nRadius參數決定;列代表線的角度,行代表距中心的距離。 這根左側圖中句柄的每次更改都會調用該函數。 Gen 再製造墊矩陣 (100x100) 並調用變換。 然後 Gen 使用轉換的輸出重建位圖並更新右側圖片。 大多數代碼只是門面裝飾;對轉換的調用在中間附近。
mx = [10 10 90 90 20 80]; // starter points
my = [10 90 10 90 10 90];
mat = J( 100, 100, 0 ); // input to hough line transform
New Window( "Hough Line Transform",
H List Box(
radio = Radio Box( {"1", "2", "3"}, gen() ), // sometimes you want to see just one line
Graph Box( // left side is just a GUI to position 3 lines
Frame Size( 400, 400 ),
Y Scale( -10, 110 ),
X Scale( -10, 110 ),
xaxis( Add Ref Line( 50, "Dashed", blue, "", 1 ), showmajorticks( 0 ), showminorticks( 0 ), showlabels( 0 ) ),
xname( "drag the square handles" ),
yaxis( Add Ref Line( 50, "Dashed", blue, "", 1 ), showmajorticks( 0 ), showminorticks( 0 ), showlabels( 0 ) ),
yname( "" ),
// when the 6 handles are moved, they capture their location AND generate results
Handle( mx[1], my[1], mx[1] = clamp( x ); my[1] = clamp( y ); gen(); );
Handle( mx[2], my[2], mx[2] = clamp( x ); my[2] = clamp( y ); gen(); );
Line( mx[1 :: 2], my[1 :: 2] ); // draw the lines in the GUI
text({(mx[1]+mx[2])/2,(my[1]+my[2])/2},char(mod(360+180*atan(my[1]-my[2],mx[1]-mx[2])/pi(),180),4));// label angle
If( radio << get > 1,
Handle( mx[3], my[3], mx[3] = clamp( x ); my[3] = clamp( y ); gen(); );
Handle( mx[4], my[4], mx[4] = clamp( x ); my[4] = clamp( y ); gen(); );
Line( mx[3 :: 4], my[3 :: 4] );
text({(mx[3]+mx[4])/2,(my[3]+my[4])/2},char(mod(360+180*atan(my[3]-my[4],mx[3]-mx[4])/pi(),180),4));// label angle
);
If( radio << get > 2,
Handle( mx[5], my[5], mx[5] = clamp( x ); my[5] = clamp( y ); gen(); );
Handle( mx[6], my[6], mx[6] = clamp( x ); my[6] = clamp( y ); gen(); );
Line( mx[5 :: 6], my[5 :: 6] );
text({(mx[5]+mx[6])/2,(my[5]+my[6])/2},char(mod(360+180*atan(my[5]-my[6],mx[5]-mx[6])/pi(),180),4));// label angle
);
),
// reserve a place to display results
H List Box(
V List Box(
imgholder = Border Box( Left( 5 ), Right( 5 ), top( 5 ), bottom( 5 ), Text Box( "drag handles" ) ),
H Center Box( anglebox = Text Box( "angle" ) )
),
V Center Box( Text Box( "Distance from black line to blue center", < )
),
hcenterbox(textbox("
The blue cross hair and the nearest point on the line (defined by the black line segment) form a distance.
When the blue cross hair is on the line defined by the black segment, the red cross hair is centered vertically (zero distance).
The black segment's slope forms the angle. The displayed angle is for the point identified by the red cross hair, which is on the brightest point.
",<);
// keep the handles in range so the drawline function is happy
clamp = Function( {t},
Max( 1, Min( 99, t ) )
);
//
// the three lines in the gui generate three lines in mat
// then the transform runs on mat and the result updates
//
gen = Function( {},
{xy, r, c},
mat[0, 0] = 0; // reset mat
drawline( mx[1 :: 2], my[1 :: 2] ); // add lines to mat
If( radio << get > 1,
drawline( mx[3 :: 4], my[3 :: 4] )
);
If( radio << get > 2,
drawline( mx[5 :: 6], my[5 :: 6] )
);
// run hough...
result = Hough Line Transform( mat, nangle( 200 ), nradius( 200 ) );// just to make result matrix square
// normalize...
result = result / Max( result );
result = result^.5; // boost brightness
ResultRed = result;
If( 1,//radio << get == 1,
xy = Loc Max( result ); // maximum bright point in transform
r = Floor( (xy - 1) / N Cols( result ) ) + 1;
c = xy - (r - 1) * N Cols( result );
anglebox << settext( "Black line angle "||Char( 180 * c / N Cols( result ), 4 ) || "°" );
ResultRed[r, 0] = .5;
ResultRed[0, c] = .5;
);
// update the results
img = New Image( "rgb", {resultRed, result, result} ); // gray scale bitmap from result
img << scale( 2 ); // bigger
(imgholder << child) << delete; // swap out old
imgholder << append( img ); // for new
);
// taken from scripting index example, a fast drawline in a matrix
drawline = Function( {mx, my},
{dx = mx[2] - mx[1], dy = my[2] - my[1], adx = Abs( dx ), ady = Abs( dy ), m, b},
If( adx > ady,
xx = Round( mx[1] ) :: Round( mx[2] );
m = dy / dx;
b = my[1] - m * mx[1];
yy = Round( xx * m + b );
,
yy = Round( my[1] ) :: Round( my[2] );
m = dx / dy;
b = mx[1] - m * my[1];
xx = Round( yy * m + b );
);
singleindex = (N Row( mat ) - yy) * N Col( mat ) + xx;
Try( mat[singleindex] = 1, 0 ); /* catch indexing errors and ignore the problems */
);
gen(); // do the first round
The JSL creates a GUI to help understand the Hough Line TransformJSL 創建了一個 GUI 來幫助理解霍夫線變換
2018 年 6 月 25 日更新:修復評論...生成更新正確的-手繪圖