Question sur HoughLineTransform m'a lancé là-dessus.
Le HoughLineTransform transforme les segments de ligne droite dans une matrice d'entrée en points dans une matrice de sortie. Les points lumineux dans la matrice de sortie représentent un angle et une distance depuis le centre d'une ligne. La matrice de sortie représente la ligne contenant le segment (les informations sur le point final sont généralement perdues).
Dans le JSL ci-dessous, la matrice d'entrée est 100x100, un champ de zéros avec des uns où se trouvent les lignes. La dimension de la matrice de sortie est déterminée par les paramètres nAngle et nRadius ; les colonnes représentent l'angle de la ligne et les lignes sont la distance du centre. Le gén La fonction est appelée pour chaque changement de poignées dans le graphique de gauche. Gen re-fabrique le tapis matrix (100x100) et appelle la transformation. Gen reconstruit ensuite un bitmap avec la sortie de la transformation et met à jour l'image de droite. La majeure partie du code n'est que de la poudre aux yeux ; l'appel à la transformation est proche du milieu.
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 TransformLe JSL crée une interface graphique pour aider à comprendre la transformation de la ligne de Hough
mise à jour 25 juin 2018 : commentaire de réparation... la génération met à jour droite -photo de la main