Mathematica 1170 1270 1096 1059 650 528 570 551 525 498 byte
L'ultima versione consente di risparmiare 27 byte non richiedendo che la "piastra" venga tagliata prima di essere analizzata. La penultima versione ha salvato 26 byte utilizzando solo 10 dei 24 punti campione originali.
z=Partition;h@i_:=i~PixelValue~#/.{_,_,_,z_}:>⌈z⌉&/@z[{45,99,27,81,63,81,9,63,45,63,9,45,45,45,63,45,45,27,45,9},2];f@p_:=h/@SortBy[Select[p~ColorReplace~Yellow~ComponentMeasurements~{"Image","Centroid"},100<Last@ImageDimensions@#[[2,1]]<120&],#[[2,2,1]]&][[All,2,1]]/.Thread[IntegerDigits[#,2,10]&/@(z[IntegerDigits[Subscript["ekqeuiv5pa5rsebjlic4i5886qsmvy34z5vu4e7nlg9qqe3g0p8hcioom6qrrkzv4k7c9fdc3shsm1cij7jrluo", "36"]],4]/.{a__Integer}:> FromDigits[{a}])-> Characters@"BD54TARP89Q0723Z6EFGCSWMNVYXHUJKL1"]
122 byte salvati attraverso l'idea di LegionMammal978 di impacchettare la lunga lista di numeri di base 10 come un singolo numero di base 36. Ha eliminato altri 20 byte dal codice finale.
Il salto da 528 a 570 byte era dovuto a un codice aggiuntivo per garantire che l'ordine delle lettere restituite corrispondesse all'ordine delle lettere sulla targa. Il centroide per ogni lettera contiene la coordinata x, che rivela le posizioni relative delle lettere lungo x.
Codice Ungolfed
coordinates=Flatten[Table[{x,y},{y,99,0,-18},{x,9,72,18}],1];
h[img_] :=ArrayReshape[PixelValue[img, #] /. {_, _, _, z_} :> ⌈z⌉ & /@ coordinates, {6, 4}];
plateCrop[img_]:=ColorReplace[ImageTrim[img,{{100,53},{830,160}}],Yellow];
codes={{{15,13,15,13,13,15},"B"},{{15,8,8,8,9,15},"C"},{{15,13,13,13,13,15},"D"},{{15,8,14,8,8,15},"E"},{{15,8,14,8,8,8},"F"},{{15,8,8,11,9,15},"G"},{{6,6,6,6,15,9},"A"},{{9,9,15,15,9,9},"H"},{{8,8,8,8,8,15},"L"},{{9,15,15,15,13,9},"M"},{{15,9,9,9,9,15},"0"},{{9,10,12,14,10,9},"K"},{{9,13,13,11,11,9},"N"},{{8,8,8,8,8,8},"1"},{{1,1,1,1,9,15},"J"},{{15,9,15,14,8,8},"P"},{{15,9,9,9,15,15},"Q"},{{15,9,15,14,10,11},"R"},{{15,8,12,3,1,15},"S"},{{9,15,6,6,6,6},"V"},{{15,6,6,6,6,6},"T"},{{9,15,15,15,15,15},"W"},{{9,9,9,9,9,15},"U"},{{9,14,6,6,14,9},"X"},{{9,14,6,6,6,6},"Y"},{{15,3,2,4,12,15},"Z"},{{15,9,9,9,9,15},"0"},{{8,8,8,8,8,8},"1"},{{15,1,3,6,12,15},"2"},{{15,1,3,1,9,15},"3"},{{2,6,6,15,2,2},"4"},{{7,12,14,1,1,15},"5"},{{15,8,14,9,9,15},"6"},{{15,1,2,2,6,4},"7"},{{15,9,15,9,9,15},"8"},{{15,9,15,1,9,15},"9"}};
decryptRules=Rule@@@codes;
isolateLetters[img_]:=SortBy[Select[ComponentMeasurements[plateCrop[img],{"Image","Centroid"}],ImageDimensions[#[[2,1]]][[2]]>100&],#[[2,2,1]]&][[All,2,1]]
f[plate_]:=FromDigits[#,2]&/@#&/@h/@isolateLetters[plate]/.decryptRules
Panoramica
L'idea di base è verificare se un campionamento sistematico di pixel dall'immagine di input corrisponde a pixel dalla stessa posizione sulle immagini in buona fede. Gran parte del codice è costituito dalle firme dei bit per ciascun carattere,
Il diagramma mostra i pixel campionati dalle lettere "J", "P", "Q" e "R".
I valori dei pixel possono essere rappresentati come matrici. Gli oscuri, in grassetto 1
corrispondono ai globuli neri. La 0
's corrispondono alle cellule bianche.
Queste sono le regole di sostituzione della decodifica per JPQ R.
{1, 1, 1, 1, 9, 15} -> "J",
{15, 9, 15, 14, 8, 8} -> "P",
{15, 9, 9, 9, 15, 15 } -> "Q",
{15, 9, 15, 14, 10, 11} -> "R"
Dovrebbe essere possibile capire perché la regola per "0" è:
{15, 9, 9, 9, 9, 15} -> "0"
e quindi distinguibile dalla lettera "Q".
Quanto segue mostra i 10 punti utilizzati nella versione finale. Questi punti sono sufficienti per identificare tutti i personaggi.
Cosa fanno le funzioni
plateCrop[img]
rimuove la cornice e il bordo sinistro dal piatto, rende lo sfondo bianco. Sono stato in grado di eliminare questa funzione dalla versione finale selezionando i componenti dell'immagine, possibili lettere alte tra 100 e 120 pixel.
isolateLetters[img]
rimuove le singole lettere dall'immagine ritagliata.
Siamo in grado di visualizzare come funziona mostrando dove l'immagine ritagliata, l'output da plateCrop
va come input per isolateLetters
. L'output è un elenco di singoli caratteri.
Coordinates
sono 24 posizioni distribuite uniformemente per controllare il colore dei pixel. Le coordinate corrispondono a quelle nella prima figura.
coordinates=Flatten[Table[{x,y},{y,99,0,-18},{x,9,72,18}],1];
{{9, 99}, {27, 99}, {45, 99}, {63, 99}, {9, 81}, {27, 81}, {45, 81}, {63, 81}, { 9, 63}, {27, 63}, {45, 63}, {63, 63}, {9, 45}, {27, 45}, {45, 45}, {63, 45}, {9, 27}, {27, 27}, {45, 27}, {63, 27}, {9, 9}, {27, 9}, {45, 9}, {63, 9}}
h
converte i pixel in binari.
h[img_] :=ArrayReshape[PixelValue[img, #] /. {_, _, _, z_} :> ⌈z⌉ & /@ coordinates, {6, 4}];
codes
sono la firma per ogni personaggio. I valori decimali sono abbreviazioni del codice binario per le celle nere (0) e bianche (1). Nella versione da golf, viene utilizzata la base 36.
codes={{{15, 9, 9, 9, 9, 15}, "0"}, {{8, 8, 8, 8, 8, 8}, "1"}, {{15, 1, 3,6,12, 15}, "2"}, {{15, 1, 3, 1, 9, 15}, "3"}, {{2, 6, 6, 15, 2, 2}, "4"}, {{7, 12, 14, 1, 1, 15},"5"}, {{15, 8, 14, 9, 9, 15}, "6"}, {{15, 1, 2, 2, 6, 4},"7"}, {{15, 9, 15, 9, 9, 15}, "8"}, {{15, 9, 15, 1, 9, 15},"9"}, {{6, 6, 6, 6, 15, 9}, "A"}, {{15, 13, 15, 13, 13, 15}, "B"}, {{15, 8, 8, 8, 9, 15}, "C"}, {{15, 13, 13, 13, 13, 15}, "D"}, {{15, 8, 14, 8, 8, 15}, "E"}, {{15, 8, 14, 8, 8, 8},"F"}, {{15, 8, 8, 11, 9, 15}, "G"}, {{9, 9, 15, 15, 9, 9}, "H"}, {{1, 1, 1, 1, 9, 15}, "J"}, {{9, 10, 12, 14, 10, 9}, "K"}, {{8, 8, 8, 8, 8, 15}, "L"}, {{9, 15, 15, 15, 13, 9}, "M"}, {{9, 13, 13, 11, 11, 9}, "N"}, {{15, 9, 15, 14, 8, 8}, "P"}, {{15, 9, 9, 9, 15, 15}, "Q"}, {{15, 9, 15, 14, 10, 11}, "R"}, {{15, 8, 12, 3, 1, 15}, "S"}, {{15, 6, 6, 6, 6, 6}, "T"}, {{9, 9, 9, 9, 9, 15}, "U"}, {{9, 15, 6, 6, 6, 6}, "V"}, {{9, 15, 15, 15, 15, 15}, "W"}, {{9, 14, 6, 6, 14, 9}, "X"}, {{9, 14, 6, 6, 6, 6}, "Y"}, {{15, 3, 2, 4, 12, 15}, "Z"}};
(* decryptRules
servono per sostituire le firme con i rispettivi caratteri *)
decryptRules=Rule@@@codes;
f
è la funzione che acquisisce l'immagine di una targa e restituisce una lettera.
f[plate_]:=FromDigits[#,2]&/@#&/@h/@isolate[plateCrop@plate]/.decryptRules;
{"A", "B", "C", "D", "E", "F", "G"}
{"H", "1", "J", "K", "L", "M", "N", "0"}
{"P", "Q", "R", "S", "T", "U", "V", "W"}
{"X", "Y", "Z", "0", "1", "2", "3", "4"}
{"5", "6", "7", "8", "9"}
golfed
Il codice viene abbreviato utilizzando un singolo numero decimale per rappresentare tutti i 24 bit (bianco o nero) per ciascun carattere. Per esempio, la lettera "J" utilizza la seguente regola di sostituzione: 1118623 -> "J"
.
1118623 corrisponde a
IntegerDigits[1118623 , 2, 24]
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1}
che può essere riconfezionato come
ArrayReshape[{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1}, {6, 4}]
{{0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {0, 0, 0, 1}, {1, 0, 0, 1} , {1, 1, 1, 1}}
che è semplicemente la matrice per "J" che abbiamo visto sopra.
%//MatrixForm
Un altro risparmio deriva dal rappresentare l'alfabeto "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
piuttosto che come un elenco di lettere.
Infine, tutte le funzioni della versione lunga, tranne h
, sono state integrate nella funzione f
anziché definite separatamente.
h@i_:=ArrayReshape[i~PixelValue~#/.{_,_,_,z_}:>⌈z⌉&/@Join@@Table[{x,y},{y,99,0,-18},{x,9,72,18}],{6,4}];f@p_:=#~FromDigits~2&/@(Join@@@h/@SortBy[Select[p~ImageTrim~{{100,53},{830,160}}~ColorReplace~Yellow~ComponentMeasurements~{"Image","Centroid"},Last@ImageDimensions@#[[2,1]]>100&],#[[2,2,1]]&][[;;,2,1]])/.Thread[IntegerDigits[36^^1c01agxiuxom9ds3c3cskcp0esglxf68g235g1d27jethy2e1lbttwk1xj6yf590oin0ny1r45wc1i6yu68zxnm2jnb8vkkjc5yu06t05l0xnqhw9oi2lwvzd5f6lsvsb4izs1kse3xvx694zwxz007pnj8f6n,8^8]->Characters@"J4A51LUHKNYXVMW732ZTCGSFE60Q98PRDB"]