Domanda su HoughLineTransform mi ha fatto iniziare su questo.
HoughLineTransform trasforma i segmenti di linea retta in una matrice di input in punti in una matrice di output. I punti luminosi nella matrice di output rappresentano un angolo e una distanza dal centro di una linea. La matrice di output rappresenta la linea contenente il segmento (le informazioni sul punto finale sono per lo più perse).
Nel JSL di seguito, la matrice di input è 100x100, un campo di zeri con quelli in cui si trovano le linee. La dimensione della matrice di output è determinata dai parametri nAngle e nRadius; le colonne rappresentano l'angolo della linea e le righe sono la distanza dal centro. IL gen La funzione viene chiamata per ogni cambiamento delle maniglie nel grafico a sinistra. Gen ri-fabbrica il stuoia matrix (100x100) e chiama la trasformazione. Gen quindi ricostruisce una bitmap con l'output della trasformazione e aggiorna l'immagine a destra. La maggior parte del codice è solo una vetrina; la chiamata alla trasformazione è vicina al centro.
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 crea una GUI per aiutare a comprendere la trasformazione della linea di Hough
aggiornamento 25 giugno 2018: riparazione commento... gen aggiorna il file Giusto -immagine a mano