Toán học 1170 1270 1096 1059 650 528 570 551 525 498 byte
Phiên bản mới nhất tiết kiệm 27 byte bằng cách không yêu cầu tấm phải được "cắt" trước khi phân tích cú pháp. Phiên bản áp chót đã lưu 26 byte bằng cách chỉ sử dụng 10 trong số 24 điểm mẫu ban đầu.
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 được lưu thông qua ý tưởng của LegionMammal978 về việc đóng gói danh sách dài gồm 10 số cơ bản dưới dạng một số, 36 số cơ bản. Anh ta giảm 20 byte cho mã cuối cùng.
Việc nhảy từ 528 đến 570 byte là do mã bổ sung để đảm bảo rằng thứ tự của các chữ cái được trả về tương ứng với thứ tự của các chữ cái trên biển số xe. Trọng tâm cho mỗi chữ cái chứa tọa độ x, cho thấy vị trí tương đối của các chữ cái dọc theo x.
Mã bị đánh cắp
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
Tổng quan
Ý tưởng cơ bản là kiểm tra xem một mẫu pixel có hệ thống từ hình ảnh đầu vào có khớp với pixel từ cùng một vị trí trên hình ảnh bonafide hay không. Phần lớn mã bao gồm các chữ ký bit cho mỗi ký tự,
Biểu đồ hiển thị các pixel được lấy mẫu từ các chữ cái "J", "P", "Q" và "R".
Các giá trị pixel có thể được biểu diễn dưới dạng ma trận. Màu tối, đậm 1
tương ứng với các ô màu đen. Các 0
'tương ứng với các tế bào trắng.
Đây là các quy tắc thay thế giải mã cho 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"
Có thể hiểu tại sao quy tắc cho "0" là:
{15, 9, 9, 9, 9, 15} -> "0"
và do đó phân biệt với chữ "Q".
Sau đây cho thấy 10 điểm được sử dụng trong phiên bản cuối cùng. Những điểm này là đủ để xác định tất cả các nhân vật.
Các chức năng làm gì
plateCrop[img]
loại bỏ khung và cạnh trái từ tấm, làm cho nền trắng. Tôi đã có thể loại bỏ chức năng này khỏi phiên bản cuối cùng bằng cách chọn các thành phần hình ảnh, các chữ cái có thể cao từ 100 đến 120 pixel.
isolateLetters[img]
loại bỏ các chữ cái riêng lẻ từ hình ảnh cắt.
Chúng ta có thể hiển thị cách thức hoạt động của nó bằng cách hiển thị hình ảnh được cắt, đầu ra từ plateCrop
đâu đi làm đầu vào cho isolateLetters
. Đầu ra là một danh sách các ký tự riêng lẻ.
Coordinates
là 24 vị trí phân bố đồng đều để kiểm tra màu pixel. Các tọa độ tương ứng với những người trong hình đầu tiên.
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
chuyển đổi các pixel thành nhị phân.
h[img_] :=ArrayReshape[PixelValue[img, #] /. {_, _, _, z_} :> ⌈z⌉ & /@ coordinates, {6, 4}];
codes
là chữ ký cho mỗi nhân vật. Các giá trị thập phân là chữ viết tắt của mã nhị phân cho các ô đen (0) và Trắng (1). Trong phiên bản golf, cơ sở 36 được sử dụng.
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
là để thay thế chữ ký bằng ký tự tương ứng *)
decryptRules=Rule@@@codes;
f
là chức năng lấy hình ảnh của biển số xe và trả về một chữ cái.
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"}
Chơi gôn
Mã được rút ngắn bằng cách sử dụng một số thập phân duy nhất để thể hiện tất cả 24 bit (trắng hoặc đen) cho mỗi ký tự. Ví dụ: chữ "J" sử dụng quy tắc thay thế sau : 1118623 -> "J"
.
1118623 tương ứng với
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}
có thể được đóng gói lại như
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}}
đó đơn giản là ma trận cho "J" mà chúng ta đã thấy ở trên.
%//MatrixForm
Một khoản tiết kiệm khác đến từ việc đại diện cho bảng chữ cái "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ"
chứ không phải là một danh sách các chữ cái.
Cuối cùng, tất cả các chức năng từ phiên bản dài, ngoại trừ h
, được tích hợp vào chức năng f
thay vì được xác định riêng biệt.
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"]