Problema
Hai una matrice 2D. Hai utilizzato la funzione Loc per individuare elementi interessanti, ma Loc ha restituito indici per una matrice 1D. Come è possibile riconvertire gli indici 1D in indici 2D?
Soluzione
Dovrai utilizzare le funzioni Floor e Mod e dovrai conoscere il numero di colonne nella tua matrice 2D. Ecco le tre righe, sepolte nell'esempio commentato di seguito. pixmat è una matrice 2D, Loc trova i pixel diversi da zero, che sono neri:
blacklocs = (Loc( pixmat ) - 1); // blacklocs è una matrice di indici 1D (in base 0)
rowlocs = Floor( (blacklocs) / nc ) + 1; // nc è il numero di colonne nel pixmat 2D
collocs = Mod( (blacklocs), nc ) + 1; // rowlocs e collocs sono indici 2D (in base 1)
// we need a bitmap to work with; use a text box with a moderate size font
textbox = Text Box( "Gargoyle", <<SETFONTSIZE> .5 are antialiasing fading to white background of the "paper".
// the next statement makes the 0 to .5 values be 1 and the .5 to 1 values be 0
pixmat = pixmat < .75; // cut off edge at some gray value. flip the 0..1 significance.
// the pixels are in a 2D matrix of rows and cols. get the dimensions.
nr = N Rows( pixmat );
nc = N Cols( pixmat );
// now we can find the location of the black pixels (1s) that form the text.
// the LOC function returns a 1D matrix of the offsets of non-zero
// elements in the 2D matrix pixmat. if pixmat was 3 rows of 5 elements each,
// the LOC could return a 1D matrix of 0 to 15 elements with values from 1 to 15.
// JMP uses 1-based indexing. subtract one to get 0-based for future steps.
blacklocs = (Loc( pixmat ) - 1);
// Here's the JSL that convers the 1D answers back to 2D answers.
// use the 0-based blacklocs (previous statement), then add 1 to
// turn the 0-based results back into the 1-based indexes JMP expects.
rowlocs = Floor( (blacklocs) / nc ) + 1;
collocs = Mod( (blacklocs), nc ) + 1;
// Show the results
scale = 16; // try bigger or smaller scale for your screen size
New Window( "Example",
Graph Box(
// make the graph the same aspect ratio as the bitmap
framesize( nc * scale, nr * scale ),
// make the point marker size big; .65 is approximately right
<<MARKER size=""></MARKER></SETFONTSIZE>
Pixels from a bitmap, displayed as markers in a graphPixels from a bitmap, displayed as markers in a graphPixel di una bitmap, visualizzati come indicatori in un grafico
Discussione
Il -1 e il +1 sono importanti, non lasciarli fuori. Leggi i commenti in base 1 e 0 nel JSL.
Il testo nella bitmap è anti-alias, il che significa che i pixel del bordo sono sfumature di grigio proporzionali a come il bordo perfetto del carattere sarebbe caduto tra i pixel. Ho scelto una soglia di grigio di .75 perché il risultato mi piaceva di più di .5; la tua applicazione probabilmente non se ne occuperà affatto.
La funzione Shape() di JMP converte la forma di una matrice. Questo non aiuterà qui.
Molte delle istruzioni nell'esempio operano su una matrice senza utilizzare un ciclo for JSL esplicito. Buono per la velocità.
Guarda anche
https://www.jmp.com/support/help/14-2/matrix-functions.shtml
Guarda anche: Cos'è la matrice JSL? per un'introduzione alle matrici in JMP.