Frage auf HoughLineTransform hat mich dazu gebracht.
Die HoughLineTransform wandelt gerade Liniensegmente in einer Eingabematrix in Punkte in einer Ausgabematrix um. Die hellen Flecken in der Ausgabematrix repräsentieren einen Winkel und Abstand von der Mitte einer Linie. Die Ausgabematrix stellt die Zeile dar, die das Segment enthält (die Endpunktinformationen gehen meistens verloren).
In der JSL unten ist die Eingabematrix 100x100, ein Feld aus Nullen mit Einsen, wo die Linien sind. Die Dimension der Ausgabematrix wird durch die Parameter nAngle und nRadius bestimmt; die Spalten stellen den Winkel der Linie dar und die Reihen sind der Abstand von der Mitte. Der Gen -Funktion wird für jede Änderung der Ziehpunkte im linken Diagramm aufgerufen. Gen stellt die wieder her Matte Matrix (100x100) und ruft die Transformation auf. Gen erstellt dann eine Bitmap mit der Ausgabe der Transformation neu und aktualisiert das rechte Bild. Der größte Teil des Codes ist nur Augenwischerei; Der Aufruf zur Transformation befindet sich in der Mitte.
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 TransformThe JSL creates a GUI to help understand the Hough Line TransformThe JSL creates a GUI to help understand the Hough Line TransformThe JSL creates a GUI to help understand the Hough Line TransformDie JSL erstellt eine GUI zum besseren Verständnis der Hough-Linien-Transformation
Update 25. Juni 2018: Reparaturkommentar ... Gen aktualisiert die Rechts -Handbild