नंबर प्लेट गोल्फ: मान्यता


20

यह भी देखें: पार्सिंग

परिचय

आप एक सरकारी प्रोग्रामिंग टीम पर काम कर रहे हैं, जो गति कैमरों की प्रोग्रामिंग कर रही है। हालांकि, गति कैलकुलेटर को प्रोग्राम करने वाले लोगों के समूह ने बहुत अधिक स्थान ले लिया है, इसलिए आपको नंबर प्लेट मान्यता सॉफ्टवेयर को यथासंभव छोटा करना होगा।

चुनौती

एक नंबर प्लेट की एक छवि को देखते हुए, प्लेट पर पाठ वापस करें।

नंबर प्लेट्स

निम्नलिखित सभी पात्र हैं जिन्हें आपके कार्यक्रम को पहचानना चाहिए:

ABCDEFG

H1JKLMN0

PQRSTUVW

XYZ01234

56789

ध्यान दें

ब्रिटिश नंबर प्लेटों पर, I (i) और 1 (एक) के लिए वर्ण समान हैं और O (o) और 0 (शून्य) के लिए वर्ण समान हैं। उस कारण से, हमेशा मान लें कि संख्याएं हैं। यानी निम्नलिखित संख्या प्लेट 10 (एक शून्य) है:

उदाहरण

C0D3 GLF

बी 3 टी 4 डीसीवाई

M1NUS 15

YET1CGN

अन्य नियम

इंटरनेट का उपयोग और ओसीआर पुस्तकालयों और कार्यों को रोक दिया जाता है।

नंबर प्लेट हमेशा ऊपर दिखाए गए लोगों के समान दिखेंगी। सभी संख्या प्लेटें लगभग एक ही आकार की होंगी (फसल विधि के कारण कुछ अशुद्धियाँ होंगी)।

यदि आपको किसी भी नंबर प्लेट के दोषरहित पीएनजी संस्करण की आवश्यकता होती है, तो मैं आपको उन्हें आपूर्ति करूंगा।

स्कोरिंग

बाइट्स में सबसे छोटा कार्यक्रम जीत जाता है।

इस साइट पर सभी नंबर प्लेट सर्च बार के स्क्रीनशॉट हैं


8
मुझे अपनी गति जाल के माध्यम से ड्राइव करने के लिए याद दिलाएं। (मेरी नंबर प्लेट में एक अक्षर O है।)
नील

3
हां, इस सवाल का शीर्षक बहुत गलत है। "ओसीआर एक ब्रिटिश लाइसेंस प्लेट" के बारे में कैसे ?
लिन

3
@ नील मेरी यूके नंबर प्लेट में O और 0 दोनों हैं और वे एक जैसे दिखते हैं। यह निर्धारित करने के लिए निश्चित नियम हैं कि सही व्याख्या क्या है, लेकिन यह एक पूरी चुनौती होगी।
लेवल रिवर सेंट।

2
यह बहुत बुरा है कि पात्र निश्चित चौड़ाई नहीं हैं। यह कुछ बहुत ही कम कोड संभावनाओं के लिए बना सकता है।
गिटारपैकर

1
@YetiCGN आपकी इच्छा मेरी आज्ञा है;)
बीटा

जवाबों:


11

सी, 409 बाइट्स (और मैं किसी के रूप में हैरान हूं)

f(w,h,d,X,T,B,x,y,b,v,u,t,a)char*d;{for(x=X=0;++x<w;){for(y=b=h;y--;a=0)d[(y*w+x)*3+1]&224||(b=0,X||(X=x,T=B=y),T=y<T?y:T,B=y>B?y:B);if(X*b){for(B+=1-T,X=x-X,v=5;v--;)for(u=4;u--;a|=(b>X/4*(B/5)*.35)<<19-u*5-v)for(b=0,t=X/4;t--;)for(y=B/5;y--;)b+=!(d[((v*B/5+y+T)*w+x-X+u*X/4+t)*3+1]&224);X=!putchar("g------a----mj---et-u--6----7--8s4-c-x--q--d9xy5-0v--n-2-hw-k-----3---bf-----t-r---pzn-1---l"[a%101-7]);}}}

इनपुट के रूप में लेता है: छवि की चौड़ाई ( w) और ऊंचाई ( h) charएस के सरणी के रूप में पैक आरजीबी डेटा के बाद ( d)। अन्य सभी फ़ंक्शन पैरामीटर भेस में परिवर्तनशील घोषणाएं हैं। ग्रीन चैनल को छोड़कर सब कुछ को अनदेखा करता है, और प्रारंभिक पास के रूप में 32 की सीमा लागू करता है।

ज्यादातर @ डेविडसी की विधि के समान है, सिवाय इसके कि प्रत्येक नमूना बॉक्स का कम से कम 35% भरा जाता है। उम्मीद है कि यह बदलावों को और अधिक मजबूत बनाता है, लेकिन कौन जानता है।

मैंने यह जानने के लिए कि कौन सा आकार और कवरेज प्रतिशत को फिर से उपयोग करने के लिए एक ब्रूट-फोर्स विधि का उपयोग किया है (यानी एक वर्ण के कई मामलों में सबसे कम मामले)। यह पता चला कि 35% कवरेज के साथ 4x5 ग्रिड सबसे अच्छा था। मैंने तब चरित्र डेटा को एक शॉर्ट स्ट्रिंग में पैक करने के लिए सबसे अच्छी बिट व्यवस्था और मोडुलो वैल्यू की गणना करने के लिए एक दूसरी ब्रूट-फोर्स विधि का उपयोग किया - शीर्ष-बाईं ओर कम बिट, फिर x में वृद्धि, अंतिम मान% 101 के साथ सबसे अच्छा, यह लुकअप टेबल दे रहा है:

-------g------a----mj---et-u--6----7--8s4-c-x--q--d9xy5-0v--n-2-hw-k-----3---bf-----t-r---pzn-1---l--

घटाना 7 का अर्थ है प्रारंभिक-हटाया जा सकता है, और अंतिम 2 को बिना किसी अतिरिक्त काम के हटाया जा सकता है। इस निष्कासन का अर्थ है कि कुछ अमान्य इनपुटों से एक अमान्य मेमोरी रीड हो सकती है, इसलिए यह विशेष छवियों पर सेगफ़ॉल्ट कर सकता है।

उपयोग:

इसमें चित्र प्राप्त करने के लिए, मैंने libpng का उपयोग करके एक आवरण लिखा है। यह भी पता चला है कि फ़ाइल नाम के बावजूद, प्रश्न में छवियां वास्तव में jpegs (!) हैं, इसलिए आपको उन्हें पहले pngs के रूप में मैन्युअल रूप से निर्यात करने की आवश्यकता होगी।

#include <png.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, const char *const *argv) {
    if(argc < 2) {
        fprintf(stderr, "Usage: %s <file.png>\n", argv[0]);
        return 1;
    }

    const char *file = argv[1];

    FILE *const fp = fopen(file, "rb");
    if(fp == NULL) {
        fprintf(stderr, "Failed to open %s for reading\n", file);
        return 1;
    }

    png_structp png_ptr = png_create_read_struct(
        PNG_LIBPNG_VER_STRING, NULL, NULL, NULL
    );

    if(!png_ptr) {
        fclose(fp);
        fprintf(stderr, "Failed to initialise LibPNG (A)\n");
        return 1;
    }

    png_infop info_ptr = png_create_info_struct(png_ptr);

    if(!info_ptr) {
        png_destroy_read_struct(&png_ptr, NULL, NULL);
        fclose(fp);
        fprintf(stderr, "Failed to initialise LibPNG (B)\n");
        return 1;
    }

    if(setjmp(png_jmpbuf(png_ptr))) {
        png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
        fclose(fp);
        fprintf(stderr, "Error while reading PNG\n");
        return 1;
    }

    png_init_io(png_ptr, fp);
    png_set_sig_bytes(png_ptr, 0);

    png_read_png(
        png_ptr, info_ptr,
        PNG_TRANSFORM_STRIP_16 |
        PNG_TRANSFORM_GRAY_TO_RGB |
        PNG_TRANSFORM_STRIP_ALPHA,
        NULL
    );
    const png_bytep *const rows = png_get_rows(png_ptr, info_ptr);
    const int w = png_get_image_width(png_ptr, info_ptr);
    const int h = png_get_image_height(png_ptr, info_ptr);
    unsigned char *const data = malloc(w*h*3 * sizeof(unsigned char));
    for(int y = 0; y < h; ++ y) {
        for(int x = 0; x < w; ++ x) {
            memcpy(&data[y*w*3], rows[y], w * 3 * sizeof(unsigned char));
        }
    }
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    fclose(fp);

    f(w, h, (char*) data);

    free(data);

    return 0;
}

टूट - फूट

f(                          // Function
    w,h,d,                  // Parameters: width, height, RGB data
    X,T,B,x,y,b,v,u,t,a     // Variables
)char*d;{                   // K&R syntax to save lots of type decls
  for(x=X=0;++x<w;){        // Loop through each column of the image:
    for(y=b=h;y--;a=0)      //  Loop through pixels in column:
      d[(y*w+x)*3+1]&224||( //   If green < 32: (char could be signed or unsigned)
        b=0,                //    This is not a blank line
        X||(X=x,T=B=y),     //    Start a new character if not already in one
        T=y<T?y:T,          //    Record top of character
        B=y>B?y:B           //    Record bottom of character
      );
    if(X*b){                //  If we just found the end of a character:
      // Check cell grid & record bits into "a"
      for(B+=1-T,X=x-X,v=5;v--;)
        for(u=4;u--;a|=(b>X/4*(B/5)*.35)<<19-u*5-v)
          // Calculate coverage of current cell
          for(b=0,t=X/4;t--;)
            for(y=B/5;y--;)
              b+=!(d[((v*B/5+y+T)*w+x-X+u*X/4+t)*3+1]&224);

      // Look up meaning of "a" in table & print, reset X to 0
      X=!putchar(
        "g------a----mj---et-u--6----7--8s4-c-x--q--d9x"
        "y5-0v--n-2-hw-k-----3---bf-----t-r---pzn-1---l"
        [a%101-7]
      );
    }
  }
}

गुस्सा के साथ अजगर और Mathemetica को पीछे छोड़ते हुए +1 सी । Oooollllld स्कूल, यो।
रॉबर्ट फ्रेजर

C के साथ जीत के लिए +1, जैसे, कभी नहीं सोचा था कि ऐसा हो सकता है,
हाय

12

गणितज्ञ 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" अक्षरों से लिए गए हैं।

jpqr

पिक्सेल मूल्यों को मेट्रिस के रूप में दर्शाया जा सकता है। काले, बोल्ड 1काले कोशिकाओं के अनुरूप हैं। 0सफेद कोशिकाओं को के अनुरूप हैं।

jjjj

ये 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 पिक्सल के बीच उच्च थे, का चयन करके इस फ़ंक्शन को अंतिम संस्करण से समाप्त करने में सक्षम था।

platecrop


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"]

@ डेविड सीम्स की तरह लगता है कि इसे गड़बड़ कर दिया; इसके {1118623, 2518818, ..., 16645599}साथ बदलने का प्रयास करें
लीजियनममाल 978

@ LegionMammal978, आपके सुझाव के कारण कोड को 100 बाइट से छोटा कर दिया गया। मैं अब बेहतर समझता हूं कि गणितज्ञ आधारों को कैसे संभालता है।
डेविड एबीसी

@DavidC इसके अलावा, ऐसा प्रतीत होता है जैसे कुछ व्हॉट्सएप आपके गोल्फ कोड के माध्यम से टकरा गया है, और मैं इसके बिना 571 बाइट्स गिनता हूं। इसके अतिरिक्त, कुछ फ़ंक्शन को infix रूप में परिवर्तित किया जा सकता है। x[[All,2,1]]से बदला जा सकता है x[[;;,2,1]]Flatten[x,1]के बराबर है Join@@x, और Flatten[#,1]&/@xके बराबर है Join@@@x। कुछ अन्य मामूली अनुकूलन हैं जो किए जा सकते हैं। इन गोल्फ के बाद 551-बाइट कोड।
लीजियनममाल 978

अच्छा सुझाव और सावधान पढ़ने। धन्यवाद।
डेविड 14

क्या आपने उन्हें स्थानांतरित करके नमूना बिंदुओं की संख्या को कम करने का प्रयास किया?
स्पर्म

4

सी #, 1040 1027 बाइट्स

using System;using System.Drawing;class _{static Bitmap i;static bool b(int x,int y)=>i.GetPixel(x,y).GetBrightness()<.4;static char l(int x,int y){if(y<45)return b(x+5,145)?((b(x+30,100)||b(x+30,50))?(b(x+68,94)?(b(x+40,50)?'D':b(x+40,120)?(b(x+45,80)?'M':'N'):'H'):b(x,97)?(b(x+30,140)?'E':b(x+60,70)?(b(x+50,140)?'R':'P'):'F'):b(x+65,45)?(b(x+5,100)?'K':b(x+30,145)?'Z':'X'):'B'):b(x+30,140)?'L':'1'):b(x+30,55)?(b(x+60,70)?'7':'T'):b(x+2,100)?'U':b(x+30,70)?'W':b(x+15,100)?'V':'Y';if(y<70)return b(x+50,110)?(b(x+50,70)?(b(x+10,110)?(b(x+30,100)?(b(x+55,80)?'8':'6'):b(x+55,80)?'0':'G'):b(x+10,70)?(b(x+60,80)?'9':'S'):b(x+60,120)?'3':'2'):'G'):b(x+30,125)?'Q':'C';if(y>150)return'A';if(y>120)return'J';else return b(x+10,135)?'5':'4';}static void Main(string[]z){i=new Bitmap(Console.ReadLine());bool s=true;int w=int.MinValue;for(int x=100;x<800;++x){for(int y=40;y<160;++y)if(s){if(b(x,y)){if(w>50)Console.Write(' ');Console.Write(l(x,y));s=false;goto e;}}else if(b(x,y))goto e;if(!s){s=true;w=0;}else++w;e:continue;}}}

Ungolfed:

using System;
using System.Drawing;

class _
{
    static Bitmap bmp;
    static bool b(int x, int y) => bmp.GetPixel(x, y).GetBrightness() < .4;
    static char l(int x, int y)
    {
        if (y < 45)
            return b(x + 5, 145) ? ((b(x + 30, 100) || b(x + 30, 50)) ? (b(x + 68, 94) ? (b(x + 40, 50) ? 'D' : b(x + 40, 120) ? (b(x + 45, 80) ? 'M' : 'N') : 'H') : b(x, 97) ? (b(x + 30, 140) ? 'E' : b(x + 60, 70) ? (b(x + 50, 140) ? 'R' : 'P') : 'F') : b(x + 65, 45) ? (b(x + 5, 100) ? 'K' : b(x + 30, 145) ? 'Z' : 'X') : 'B') : b(x + 30, 140) ? 'L' : '1') : b(x + 30, 55) ? (b(x + 60, 70) ? '7' : 'T') : b(x + 2, 100) ? 'U' : b(x + 30, 70) ? 'W' : b(x + 15, 100) ? 'V' : 'Y';
        if (y < 70)
            return b(x + 50, 110) ? (b(x + 50, 70) ? (b(x + 10, 110) ? (b(x + 30, 100) ? (b(x + 55, 80) ? '8' : '6') : b(x + 55, 80) ? '0' : 'G') : b(x + 10, 70) ? (b(x + 60, 80) ? '9' : 'S') : b(x + 60, 120) ? '3' : '2') : 'G') : b(x + 30, 125) ? 'Q' : 'C';
        if (y > 150)
            return 'A';
        if (y > 120)
            return 'J';
        if (y > 95)
            return b(x + 10, 135) ? '5' : '4';
        return '-';
    }
    static void Main(string[] args)
    {
        bmp = new Bitmap(Console.ReadLine());
        bool state = true;
        int space = int.MinValue;
        for (int x = 100; x < 800; ++x)
        {
            for (int y = 40; y < 160; ++y)
                if (state)
                {
                    if (b(x, y))
                    {
                        if (space > 50)
                            Console.Write(' ');
                        Console.Write(l(x, y));
                        state = false;
                        goto bad;
                    }
                }
                else if (b(x, y))
                    goto bad;
            if (!state)
            {
                state = true;
                space = 0;
            }
            else
                ++space;
            bad:
            continue;
        }
    }
}

मूल रूप से मुझे प्रत्येक वर्ण की पहचान निर्धारित करने के लिए पीले / काले रंग की जांच करने के लिए कुछ विशिष्ट संदर्भ बिंदु मिले।


क्या आप सुनिश्चित हैं कि प्रदान की गई छवियों के लिए कोई ओवरफिट नहीं है और यह लाइसेंस प्लेटों को पहचान लेगा जहां वर्ण 10 पिक्सेल द्वारा स्थानांतरित किए गए हैं?
यतिसीजीएन

@YetiCGN को इसे तब तक पहचानना चाहिए जब तक आकार समान है, और वे एक ही ऊर्ध्वाधर स्थिति में हैं। मैंने सभी प्रदान किए गए उदाहरणों के साथ कोशिश की है, और यह काम करता है; कृपया मुझे बताएं कि क्या आपको ऐसा लगता है जहां यह नहीं है
निक मर्टिन

मैं केवल इसके लिए विजुअल स्टूडियो स्थापित नहीं करना चाहता, लेकिन आप i.imgur.com/i8jkCJu.png आज़मा सकते हैं जो आकार में थोड़ा छोटा है। मुझे लगता है कि यह मानना ​​सुरक्षित है कि सभी प्रस्तुतियाँ उस विशेष वेबसाइट की छवियां होंगी। शुरू में मेरी टिप्पणी "क्या हुआ अगर यह एक असली प्लेट स्कैन है?" / "क्या होगा अगर किसी और ने प्लेट बनाने के लिए सभी पात्रों को 10 पिक्सेल से लंबवत स्थानांतरित कर दिया?"
यतिसीजीएन

@YetiCGN को आपको संकलन करने के लिए VisualStudio की आवश्यकता नहीं है, बसcsc.exe main.cs /r:System.Drawing.dll
VisualMelon

2

PHP - 1741 1674 1143 बाइट्स

इसे पहले कुछ उदाहरणों से वर्णों के प्रोफाइल को सीखकर स्थापित किया गया था, जिसने फिर प्रत्येक वर्ण को छह संख्याओं में संक्षेपित किया। मैंने छह को चुना क्योंकि मेरे पास मूल रूप से पांच थे, और यह उतना अच्छा काम नहीं करता था जितना मैं चाहूंगा, लेकिन छह बहुत बेहतर काम करते हैं। अधिकांश अनुकूलन में इन प्रोफाइल को छोटे और छोटे बाइट की संख्या में निचोड़ना शामिल है।

पहली और दूसरी प्रोफ़ाइल *lhdfdnऔर |nnmmkkवास्तव में नीचे "जीबी" के साथ नीले रंग की बूँदें हैं *, और सही सीमा है |, जिसे हम अनदेखा कर रहे हैं। यह उन्हें शामिल करने के लिए सुरक्षित है ताकि बूँद और सही सीमा के खिलाफ मैच के लिए कुछ हो।

किसी भी छवि प्रारूप को संभालना चाहिए, किसी भी उचित स्केलिंग ने प्रदान किया पहलू अनुपात बहुत अधिक नहीं बदलता है, हल्के रंग पर कोई भी अंधेरा, और यहां तक ​​कि थोड़ा सा शोर और छायांकन!

इसे सीमा की आवश्यकता है, कम से कम ऊपर और नीचे, यह प्रोफ़ाइल का हिस्सा है।

<?php $X=[];foreach(str_split('*lhdfdn|nnmmkkA<njjk;BOnKB`^Chn::E7DHn?1X`EnkGGD4Fn_330!Gnj9G[IHnX!!XnJ%(##knKnX.EN6LnX!!!!Mn_<:bnNn^77_nPn^33@6QhfBDjnRn_8LaDSOlYYnUT$$nn$$Uh_##^nV9c][n;W_nWTlhXHnLTiCY4LhnM5ZJbnmaI0ng88lk1nnnnnn2C[__n`34B?Kna4+=Fnb"5NnUReX6gnKKaM7*4Xnb=8gkIIne9K`KKni',7)as$s){$t=[];foreach(str_split(substr($s,1))as$u)$t[]=ord($u)-11;$X[$s[0]]=$t;}echo m(r($argv[1]),$X)."\n";function r($u){$a=[];$i=imagecreatefromstring(file_get_contents($u));$w=imagesx($i);$h=imagesy($i);$s=[];for($x=0;$x<$w;$x++){$s[$x]=0;for($y=0;$y<$h;$y++){$p=imagecolorsforindex($i,imagecolorat($i,$x,$y));if(3*$p['red']+6*$p['green']+$p['blue']<1280)$s[$x]++;}}$j=0;$k=[];for($x=0;$x<$w;$x++){if($s[$x]>$h/10)for($o=0;$o<6;$o++)$k[]=$s[$x];elseif(count($k)){$a[]=$k;$j++;$k=[];}}$b=[];foreach($a as$v){$t=[];$u=array_chunk($v,intval(count($v)/6));foreach($u as$c)$t[]=array_sum($c)/count($c);$m=99/max($t);$e=[];foreach($t as$x)$e[]=intval($x*$m+0.5);$b[]=$e;}return$b;}function m($A,$X){$r='';foreach($A as$a){$s=INF;$c='';foreach($X as$k=>$x){$t=0;for($i=0;$i<6;$i++)$t+=pow($a[$i]-$x[$i],2);if($s>$t){$s=$t;$c=$k;}}$r.=$c;}return trim($r,'|*');}

इस रूप में सहेजें ocr.php, फिर कमांड लाइन से चलाएँ:

$ php ocr.php http://i.imgur.com/UfI63md.png
ABCDEFG

$ php ocr.php http://i.imgur.com/oSAK7dy.png
H1JKLMN0

$ php ocr.php http://i.imgur.com/inuIHjm.png
PQRSTUVW

$ php ocr.php http://i.imgur.com/Th0QkhT.png
XYZ01234

$ php ocr.php http://i.imgur.com/igH3ZPQ.png
56789

$ php ocr.php http://i.imgur.com/YfVwebo.png
10

$ php ocr.php http://i.imgur.com/3ibQARb.png
C0D3GLF

$ php ocr.php http://i.imgur.com/c7XZqhL.png
B3T4DCY

$ php ocr.php http://i.imgur.com/ysBgXhn.png
M1NUS15

जो लोग रुचि रखते हैं, उनके लिए यहां सीखने का कोड है। के रूप में सहेजें learn.phpऔर कमांड लाइन से चलाएं, कोई तर्क नहीं।

<?php

define('BANDS', 6);

main();

function main()
{
    $glyphs = [];

    learn($glyphs, 'http://imgur.com/UfI63md.png', '*ABCDEFG|');
    learn($glyphs, 'http://imgur.com/oSAK7dy.png', '*H1JKLMN0|');
    learn($glyphs, 'http://imgur.com/inuIHjm.png', '*PQRSTUVW|');
    learn($glyphs, 'http://imgur.com/Th0QkhT.png', '*XYZ01234|');
    learn($glyphs, 'http://imgur.com/igH3ZPQ.png', '*56789|');

    $profiles = summarize($glyphs);

    foreach ($profiles as $glyph=>$profile)
    {
        print $glyph;
        foreach ($profile as $value)
            print chr($value + 11);
        print "\n";
    }
}

function learn(&$glyphs, $url, $answer)
{
    $image = imagecreatefromstring(file_get_contents($url));
    $width = imagesx($image);
    $height = imagesy($image);
    $counts = [];
    for ($x = 0; $x < $width; $x++)
    {
        $counts[$x] = 0;
        for ($y = 0; $y < $height; $y++)
        {
            $pixel = imagecolorsforindex($image, imagecolorat($image, $x, $y));
            if (3 * $pixel['red'] + 6 * $pixel['green'] + $pixel['blue'] < 1280)
                $counts[$x]++;
        }
    }

    $index = 0;
    $expanded = [];
    for ($x = 0; $x < $width; $x++)
    {
        if ($counts[$x] > $height / 10)
            for ($inner = 0; $inner < BANDS; $inner++)
                $expanded[] = $counts[$x];
        else if (count($expanded)) {
            $glyphs[$answer[$index]] = $expanded;
            $index++;
            $expanded = [];
        }
    }
}

function summarize($glyphs)
{
    $profiles = [];
    foreach ($glyphs as $glyph=>$expanded)
    {
        $averages = [];
        $bands = array_chunk($expanded, count($expanded) / BANDS);
        foreach ($bands as $band)
            $averages[] = array_sum($band) / count($band);
        $scaling = 99 / max($averages);
        $profile = [];
        foreach ($averages as $average)
            $profile[] = intval($average * $scaling + 0.5);
        $profiles[$glyph] = $profile;
    }
    return $profiles;
}

?>

आपको आउटपुट में रिक्त स्थान शामिल करना चाहिए
बीटा डेके

3
यह चश्मा के अंतर्गत नहीं है निम्नलिखित सभी वर्ण हैं जिन्हें आपके कार्यक्रम को पहचानना चाहिए , बस वर्ण AH, JN, PZ, और 0-9। रिक्त स्थान का कोई उल्लेख नहीं।

ओह, ठीक है, तुम्हारा तब ठीक है
बीटा डिके

"पहला और दूसरा प्रोफाइल [...] वास्तव में नीचे" GB "के साथ नीला बूँद है, और सही सीमा है, जो उपेक्षा कर रहा है।" फिर आपने उन्हें कोड में क्यों शामिल किया, खासकर अगर एक खाली स्ट्रिंग के साथ सरणी कुंजी ओवरराइट की गई है? प्लस: यह कोड गोल्फ के लिए छोटे खुले वाक्यविन्यास का उपयोग करने की अनुमति है! :-)
यतिजीएनएन

@YetiCGN - यदि वे नहीं हैं तो कोड उन्हें किसी और चीज़ से मिलाने का प्रयास करेगा! मुझे नहीं पता था कि वे ओवरराइट किए गए थे, भाग्यशाली है कि कोड अभी भी काम करता है। बदलना। आप मेरे कुछ परिवर्तनों को अपने उत्तर में ढालने में सक्षम हो सकते हैं।

0

PHP, 971 970 बाइट्स

पर भारी खींचता Yimin रोंग के जवाब है, जो गंभीरता से नीचे golfed जा सकता है, विशेष रूप से सरणी सूचकांक, और gzip संपीड़न के साथ एक फर में डाल दिया।

फ़ार डाउनलोड करें

यह 1557 1535 बाइट्स में मेरा बेहतर आधार संस्करण है , बस फ़ाइलनाम "ओ" के तहत सहेजा गया है:

<?$X=[[99,92,45,45,97,96],[99,99,99,99,99,99],[56,80,84,84,99,85],[41,55,52,64,99,86],[32,50,59,99,87,23],[67,99,74,71,90,77],[92,99,64,64,86,66],[31,41,77,99,87,50],[92,96,62,62,99,90],[64,85,64,64,99,94],''=>[99,99,98,98,96,96],A=>[49,99,95,95,96,48],B=>[68,99,64,55,85,83],C=>[93,99,47,47,58,44],D=>[61,99,52,38,77,85],E=>[99,96,60,60,57,41],F=>[99,84,40,40,37,22],G=>[99,95,46,60,80,62],H=>[99,77,22,22,77,99],1=>[99,99,99,99,99,99],J=>[26,29,24,24,96,99],K=>[99,77,35,58,67,43],L=>[99,77,22,22,22,22],M=>[99,84,49,47,87,99],N=>[99,83,44,44,84,99],P=>[99,83,40,40,53,43],Q=>[93,91,55,57,95,99],R=>[99,84,45,65,86,57],S=>[68,97,78,78,99,74],T=>[25,25,99,99,25,25],U=>[93,84,24,24,83,99],V=>[46,88,82,80,99,48],W=>[84,99,76,73,97,93],X=>[61,99,65,73,94,56],Y=>[41,65,93,99,66,42],Z=>[63,87,99,98,86,62]];echo m(r($argv[1]),$X);function r($u){$a=[];$i=imagecreatefromstring(join('',file($u)));$w=imagesx($i);$h=imagesy($i);$s=[];for(;$x<$w;$x++){$s[$x]=0;for($y=0;$y<$h;$y++){$p=imagecolorsforindex($i,imagecolorat($i,$x,$y));if(3*$p[red]+6*$p[green]+$p[blue]<1280)$s[$x]++;}}$j=0;$k=[];for(;$z<$w;$z++){if($s[$z]>$h/10)for($o=0;$o<6;$o++)$k[]=$s[$z];elseif(count($k)){$a[]=$k;$j++;$k=[];}}$b=[];foreach($a as$v){$t=[];$u=array_chunk($v,~~(count($v)/6));foreach($u as$c)$t[]=array_sum($c)/count($c);$m=99/max($t);$e=[];foreach($t as$x)$e[]=~~($x*$m+.5);$b[]=$e;}return$b;}function m($A,$X){$r='';foreach($A as$a){$s=INF;$c='';foreach($X as$k=>$x){$t=0;for($i=0;$i<6;)$t+=($a[$i]-$x[$i++])**2;if($s>$t){$s=$t;$c=$k;}}$r.=$c;}return$r;}

सुधार:

पहला चरण

  • अंकीय सरणी सूचकांकों को हटा दिया गया है और सरणी, स्ट्रिंग सूचकांकों को निहित स्थिरांक के रूप में हटा दिया गया है

दूसरा चरण

  • के intvalसाथ प्रतिस्थापित ~~(8 बाइट्स बचाता है, दो घटनाएँ)
  • जहां अनावश्यक के लिए लूप इनिशियलाइज़ेशन को हटा दिया गया
  • file_get_contents($u)के साथ प्रतिस्थापित join('',file($u))(5 बाइट बचाता है)
  • और कुछ अन्य

दुर्भाग्य से, सभी दूसरे चरण के सुधार केवल 1 बाइट कम gzipped कोड में अनुवाद करते हैं। :-D

और इस कोड का उपयोग Phar बनाने के लिए किया गया था:

<?php
$phar = new Phar('o.phar');
$phar->addFile('o');
$phar['o']->compress(Phar::GZ);
$phar->setStub('<?Phar::mapPhar(o.phar);include"phar://o.phar/o";__HALT_COMPILER();');

php ocr.phar http://i.imgur.com/i8jkCJu.pngपरीक्षण केस छवियों के साथ या किसी अन्य परीक्षण के साथ ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.