Mathematica 1170 1270 1096 1059 650 528 570 551 525 498 byte
Versi terbaru menghemat 27 byte dengan tidak mengharuskan plat "dipangkas" sebelum diuraikan. Versi kedua terakhir menyimpan 26 byte dengan hanya menggunakan 10 dari 24 titik sampel asli.
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 disimpan melalui ide LegionMammal978 tentang pengemasan daftar panjang nomor basis 10 sebagai nomor tunggal, nomor 36. Dia mengupas 20 byte lagi dari kode akhir.
Lompatan dari 528 ke 570 byte adalah karena kode tambahan untuk memastikan bahwa urutan surat-surat yang dikembalikan sesuai dengan urutan surat-surat di plat nomor. Centroid untuk setiap huruf berisi koordinat x, yang mengungkapkan posisi relatif huruf sepanjang x.
Kode Tidak Terkunci
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
Ikhtisar
Ide dasarnya adalah untuk memeriksa apakah pengambilan sampel piksel secara sistematis dari gambar input cocok dengan piksel dari lokasi yang sama pada gambar bonafide. Sebagian besar kode terdiri dari tanda tangan bit untuk setiap karakter,
Diagram menunjukkan piksel yang diambil dari huruf "J", "P", "Q", dan "R".
Nilai piksel dapat direpresentasikan sebagai matriks. Gelap, tebal 1
berhubungan dengan sel hitam. Ini 0
sesuai dengan sel putih.
Ini adalah aturan penggantian dekripsi untuk JPQ R.
{1, 1, 1, 1, 9, 15} -> "J",
{15, 9, 15, 14, 8, 8} -> "P",
{15, 9, 9, 9, 9, 15, 15 } -> "Q",
{15, 9, 15, 14, 10, 11} -> "R"
Seharusnya dimungkinkan untuk memahami mengapa aturan untuk "0" adalah:
{15, 9, 9, 9, 9, 15} -> "0"
dan dengan demikian dapat dibedakan dari huruf "Q".
Berikut ini menunjukkan 10 poin yang digunakan dalam versi final. Poin-poin ini cukup untuk mengidentifikasi semua karakter.
Apa fungsinya
plateCrop[img]
menghilangkan bingkai dan tepi kiri dari piring, membuat latar belakang putih. Saya dapat menghilangkan fungsi ini dari versi final dengan memilih komponen gambar, kemungkinan huruf yang tingginya antara 100 dan 120 piksel.
isolateLetters[img]
menghapus setiap huruf dari gambar yang dipangkas.
Kita dapat menampilkan cara kerjanya dengan menunjukkan di mana gambar yang dipangkas, output dari plateCrop
masuk sebagai input untuk isolateLetters
. Outputnya adalah daftar karakter individu.
Coordinates
adalah 24 posisi yang didistribusikan secara merata untuk memeriksa warna piksel. Koordinat sesuai dengan yang ada di gambar pertama.
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
mengubah piksel menjadi biner.
h[img_] :=ArrayReshape[PixelValue[img, #] /. {_, _, _, z_} :> ⌈z⌉ & /@ coordinates, {6, 4}];
codes
adalah tanda tangan untuk setiap karakter. Nilai desimal adalah singkatan dari kode biner untuk sel hitam (0) dan Putih (1). Dalam versi golf, base 36 digunakan.
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
untuk mengganti tanda tangan dengan karakter masing-masing *)
decryptRules=Rule@@@codes;
f
adalah fungsi yang mengambil gambar plat dan mengembalikan surat.
f[plate_]:=FromDigits[#,2]&/@#&/@h/@isolate[plateCrop@plate]/.decryptRules;
{"A", "B", "C", "D", "E", "F", "G"}
{"H", "1", "J", "K", "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", "8", "9"}
Golf
Kode ini disingkat dengan menggunakan angka desimal tunggal untuk mewakili semua 24 bit (putih atau hitam) untuk setiap karakter. Misalnya, huruf "J" menggunakan aturan pengganti berikut: 1118623 -> "J"
.
1118623 berkorespondensi dengan
IntegerDigits[1118623 , 2, 24]
{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1}
yang dapat dikemas ulang sebagai
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}}
yang hanya merupakan matriks untuk "J" yang kita lihat di atas.
%//MatrixForm
Penghematan lain datang dari mewakili alfabet "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
bukan sebagai daftar huruf.
Akhirnya, semua fungsi dari versi panjang, kecuali h
, diintegrasikan ke dalam fungsi f
daripada ditentukan secara terpisah.
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"]