गणितज्ञ 1170 1270 1096 1059 650 528 570 551 525 498 बाइट्स
नवीनतम संस्करण 27 बाइट्स को सहेजने की आवश्यकता नहीं है, इससे पहले कि यह पार्स हो प्लेट को "छंटनी" की आवश्यकता नहीं है। मूल 24 नमूना बिंदुओं में से केवल 10 का उपयोग करके 26 संस्करण बचे।
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 बाइट्स ने सिंगल, बेस 36 नंबर के रूप में बेस 10 नंबरों की लंबी सूची को पैक करने के विचार के साथ लीजनमैमल 978 के माध्यम से बचाया। उन्होंने एक और 20 बाइट्स को अंतिम कोड से निकाल दिया।
528 से 570 बाइट तक की छलांग अतिरिक्त कोड के कारण यह सुनिश्चित करने के लिए थी कि लाइसेंस प्लेट पर अक्षरों के क्रम के अनुरूप पत्र का क्रम वापस आ गया है। प्रत्येक अक्षर के लिए केन्द्रक में x-निर्देशांक होता है, जो x के साथ अक्षरों के सापेक्ष पदों को प्रकट करता है।
अघोषित कोड
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
अवलोकन
मूल विचार यह जांचना है कि क्या इनपुट छवि से पिक्सेल का व्यवस्थित नमूना बोनएफ़ाइड छवियों पर एक ही स्थान से पिक्सेल से मेल खाता है। अधिकांश कोड में प्रत्येक वर्ण के लिए बिट हस्ताक्षर होते हैं,
आरेख उन पिक्सेल को दिखाता है जो "J", "P", "Q" और "R" अक्षरों से लिए गए हैं।
पिक्सेल मूल्यों को मेट्रिस के रूप में दर्शाया जा सकता है। काले, बोल्ड 1
काले कोशिकाओं के अनुरूप हैं। 0
सफेद कोशिकाओं को के अनुरूप हैं।
ये JPQ R के लिए डिक्रिप्शन रिप्लेसमेंट नियम हैं।
{1, 1, 1, 1, 9, 15} -> "जे",
{15, 9, 15, 14, 8, 8} -> "पी",
{15, 9, 9, 9, 15, 15 } -> "क्यू",
{15, 9, 15, 14, 10, 11} -> "आर"
यह समझना संभव होना चाहिए कि "0" के लिए नियम क्यों है:
{१५, ९, ९, ९, ९, १५} -> "०"
और इस प्रकार "क्यू" अक्षर से अलग।
निम्नलिखित अंतिम संस्करण में उपयोग किए जाने वाले 10 बिंदुओं को दर्शाता है। ये बिंदु सभी वर्णों की पहचान के लिए पर्याप्त हैं।
कार्य क्या करते हैं
plateCrop[img]
प्लेट से फ्रेम और बाएं किनारे को हटाता है, पृष्ठभूमि को सफेद बनाता है। मैं छवि घटकों, संभव पत्र जो 100 और 120 पिक्सल के बीच उच्च थे, का चयन करके इस फ़ंक्शन को अंतिम संस्करण से समाप्त करने में सक्षम था।
isolateLetters[img]
फसली छवि से अलग-अलग अक्षरों को निकालता है।
हम यह प्रदर्शित कर सकते हैं कि यह दिखाता है कि क्रॉप की गई छवि, आउटपुट से plateCrop
इनपुट के रूप में कैसे काम करती है isolateLetters
। आउटपुट व्यक्तिगत पात्रों की एक सूची है।
Coordinates
पिक्सेल रंग की जाँच के लिए 24 समान रूप से वितरित स्थान हैं। निर्देशांक पहले आंकड़े में उन लोगों के अनुरूप हैं।
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
पिक्सेल को बाइनरी में कनवर्ट करता है।
h[img_] :=ArrayReshape[PixelValue[img, #] /. {_, _, _, z_} :> ⌈z⌉ & /@ coordinates, {6, 4}];
codes
प्रत्येक वर्ण के लिए हस्ताक्षर हैं। दशमलव मान काले (0) और सफेद (1) कोशिकाओं के लिए द्विआधारी कोड के संक्षिप्त रूप हैं। गोल्फ वाले संस्करण में, बेस 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
अपने संबंधित चरित्र के साथ हस्ताक्षर बदलने के लिए हैं *)
decryptRules=Rule@@@codes;
f
वह कार्य है जो एक लाइसेंस प्लेट की एक छवि लेता है और एक पत्र देता है।
f[plate_]:=FromDigits[#,2]&/@#&/@h/@isolate[plateCrop@plate]/.decryptRules;
{"A", "B", "C", "D", "E", "F", "G"}
{"H", "1", "J", "K", "L", "एम", "एन", "0"}
{"पी", "क्यू", "आर", "एस", "टी", "यू", "वी", "डब्ल्यू"}
{"एक्स", "वाई", "जेड", "0", "1", "2", "3", "4"}
"{5", "6", "7", "8", "9"}।
golfed
प्रत्येक वर्ण के लिए सभी 24 बिट्स (सफ़ेद या काले) का प्रतिनिधित्व करने के लिए एकल दशमलव संख्या का उपयोग करके कोड को छोटा किया जाता है। उदाहरण के लिए, "J" अक्षर निम्नलिखित प्रतिस्थापन नियम का उपयोग करता है 1118623 -> "J"
:।
1118623 से मेल खाती है
IntegerDigits[1118623 , 2, 24]
{, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1}
जिसे फिर से रद्द किया जा सकता है
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}}
जो "जे" के लिए बस मैट्रिक्स है जिसे हमने ऊपर देखा था।
%//MatrixForm
एक और बचत "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
पत्र की सूची के बजाय वर्णमाला का प्रतिनिधित्व करने से आती है ।
अंत में, लंबे संस्करण से सभी कार्यों को छोड़कर h
, f
अलग से परिभाषित करने के बजाय फ़ंक्शन में एकीकृत किया गया था ।
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"]