Mathematica 1170 1270 1096 1059650528570551525 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"]
LegionMammal978의 기본 10 개 숫자 목록을 단일 기본 36 개 숫자로 묶는 아이디어를 통해 122 바이트가 절약되었습니다. 그는 최종 코드에서 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}-> "J",
{15, 9, 15, 14, 8, 8}-> "P",
{15, 9, 9, 9, 15, 15 }-> "Q",
{15, 9, 15, 14, 10, 11}-> "R"
"0"에 대한 규칙이 다음과 같은 이유를 이해할 수 있어야합니다.
{15, 9, 9, 9, 9, 15}-> "0"
따라서 문자 "Q"와 구별됩니다.
다음은 최종 버전에서 사용 된 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
각 캐릭터의 서명입니다. 10 진수 값은 검정 (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", "M", "N", "0"}
{ "P", "Q", "R", "S", "T", "U", "V", "W"}
{ "X", "Y", "Z", "0", "1", "2", "3", "4"}
{ "5", "6", "7", "8", "9"}
골프
각 문자의 24 비트 (흰색 또는 검은 색)를 모두 나타내는 단일 10 진수를 사용하여 코드를 줄입니다. 예를 들어, 문자 "J"는 다음 교체 규칙을 사용합니다.1118623 -> "J"
.
1118623는
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}
다음과 같이 다시 포장 할 수 있습니다.
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}}
위의 "J"에 대한 행렬입니다.
%//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"]