ASCII 아트 번호 인식


15

도전

ASCII 아트 번호를 인식하십시오. 흥미로운 점을 위해 이미지에서 임의의 3 개의 점이 뒤집힐 수 있습니다. 예를 들면 다음과 같습니다.

 ***** 
 *  ** 
    ** 

   **  
  **   
 **    

입력

아래 파이썬 스크립트에 의해 생성 된 7x7 ASCII 아트 번호.

산출

숫자

테스트 스크립트

테스트 사례를 생성하는 Python 스크립트 (2.6+)는 다음과 같습니다.

import random

digits = '''\
  ***  
 ** ** 
**   **
**   **
**   **
 ** ** 
  ***  

   *   
 ***   
   *   
   *   
   *   
   *   
 ***** 

  ***  
 *  ** 
     * 
    ** 
   **  
  **   
 ******

  ***  
 *  ** 
     * 
  ***  
     * 
 *  ** 
  ***  

   **  
  ***  
 * **  
*  **  
****** 
   **  
   **  

 ***** 
 **    
 ****  
     * 
     * 
 *   * 
  ***  

  **** 
 **    
 ***** 
 *   * 
 **  **
 **  * 
  **** 

 ***** 
    ** 
    ** 
   **  
   **  
  **   
 **    

  **** 
 **  **
 **  **
  **** 
 **  **
 **  **
  **** 

  ***  
 ** ** 
**   **
 **  * 
  **** 
    ** 
 ****  '''.split('\n\n')

def speckle(image, num_speckles):
    grid = [list(row) for row in image.split('\n')]

    for i in range(num_speckles):
        row = random.choice(grid)
        row[random.randint(0, 6)] = random.choice([' ', '*'])

    return '\n'.join([''.join(row) for row in grid])

digit = random.choice(digits)

print(speckle(digit, 3))

두 자리 사이의 해밍 거리가 6보다 큽니까?
John Dvorak

@ JanDvorak : 문제가되지 않도록 글꼴을 조정했습니다. 하나 보여요?
Blender

답변:


9

APL ( 87 85)

1-⍨⊃⍒(,↑{7↑'*'=⍞}¨⍳7)∘(+.=)¨{49↑,(16/2)⊤⎕UCS⍵}¨↓10 3⍴'嵝䍝뫂傁ဣ␋䠁䊫낫䢝䊅넂垵僡ᑨ嘙쐅嘹䜝䪀슪퀪岹亝尵䌧뮢'

설명:

가능한 각 ASCII 숫자는 48 비트로 인코딩됩니다. (어쨌든 49 번째 비트는 항상 0입니다). 문자열 嵝䍝뫂傁ဣ␋䠁䊫낫䢝䊅넂垵僡ᑨ嘙쐅嘹䜝䪀슪퀪岹亝尵䌧뮢에는 ASCII 번호 당 3 개의 문자가 있으며 각 문자는 16 비트를 인코딩합니다.

  • ↓10 3⍴: 데이터 문자열을 10 개의 3 자리 그룹으로 나누고 각 그룹은 숫자를 인코딩합니다.
  • {... : 각 그룹에 대해 :
    • (16/2)⊤⎕UCS⍵: 세 문자 각각의 처음 16 비트를 가져옵니다.
    • ,: 비트 배열을 하나의 배열로 연결
    • 49↑: 처음 49 개 요소를 가져옵니다. 48 개만 있으므로 0끝에 추가하는 것과 같습니다 .
  • ,↑{7↑'*'=⍞}¨⍳7: 키보드에서 7 줄의 7 줄을 읽고 각 줄에 대해 비트 배열을 만들어 1문자가 a임을 의미합니다 *.
  • (+.=)¨: 가능한 각 자리수에 대해 입력이 해당 자리수와 공통된 비트 수를 계산하십시오.
  • : 목록의 하향 정렬에 대한 인덱스를 가져 와서 결과의 첫 번째 항목이 이전 목록에서 가장 큰 숫자의 색인이되도록합니다.
  • : 숫자의 색인 인 첫 번째 항목을 가져옵니다.
  • 1-⍨: APL 지수는 1을 기준으로하기 때문에 1을 뺍니다.

3
와우 87? 가장 긴 APL 프로그램이어야합니다.
izabera

4
나는 항상 APL이 항상 그리스인처럼 보인다고 생각했습니다. 이제 중국어도?!?
Digital Trauma


5

파이썬

OCR 솔루션이있을 것이라고 확신하지만 내 정확성이 훨씬 높습니다.

import difflib as x;r=range;s='2***3**1**1**3****3****3**1**1**3***23*4***6*6*6*6*4*****12***3*2**6*5**4**4**4******2***3*2**6*3***7*2*2**3***23**4***3*1**2*2**2******4**5**21*****2**5****7*6*2*3*3***22****2**5*****2*3*2**2**1**2*3****11*****5**5**4**5**4**4**42****2**2**1**2**2****2**2**1**2**2****12***3**1**1**3**1**2*3****5**2****2'
for c in r(8):s=s.replace(str(c),' '*c)
s=map(''.join,zip(*[iter(s)]*7));a=[raw_input("") for i in r(7)];l=[[x.SequenceMatcher('','|'.join(a),'|'.join(s[i*7:(i+1)*7])).ratio()] for i in r(10)];print l.index(max(l))

한 번에 한 줄의 텍스트를 입력하십시오.

문자 수를 늘리지 않고 별표를 처리하는 더 좋은 방법을 모릅니다.


4

자바 스크립트 (ES6), 89

f=n=>(a=1,[a=(a+a^c.charCodeAt())%35 for(c of n)],[4,25,5,16,0,11,32,13,10,1].indexOf(a))

용법:

> f("  ***  \n *  ** \n     * \n    ** \n   **  \n  **   \n ******")
2

골프 용 버전 :

f = (n) => (
  // Initialize the digit's hash.
  a=1,
  // Hash the digit.
  // 35 is used because the resulting hash is unique for the first ten digits.
  // Moreover, it generates 4 1-digit hashes.
  [a = (a + a ^ c.charCodeAt()) % 35 for(c of n)],
  // Compare the hash to pre-computed digit hash.
  // The matching hash index is the digit.
  [4,25,5,16,0,11,32,13,10,1].indexOf(a)
)

3
입력이 숫자 중 하나와 정확히 일치하지 않으면 작동합니까? 이 질문에 따르면 세 개의 픽셀이 뒤집어 질 수 있으며 여전히 작동해야합니다.
marinus

3

Bash + ImageMagick + tesseract, 316 자

다음은 OCR 솔루션에 대한 설명입니다. tesseract에 문자가 하나 뿐이고 숫자라는 것을 말할 때조차도 정확하지 않습니다. 적당히 골프를 치지 만 여전히 읽을 수있는 부분 :

w=0
c()((w=${#2}>w?${#2}:w))
mapfile -c1 -Cc -t l
h=${#l[@]}
{
echo "# ImageMagick pixel enumeration: $w,$h,1,gray"
for y in ${!l[@]};{
for((x=0;x<w;x++));{
[ "${l[$y]:$x:1}" != " " ]
echo "$x,$y: ($?,$?,$?)"
}
}
}|convert txt:- i.png
tesseract i.png o -psm 10 <(echo "tessedit_char_whitelist 0123456789")
cat o.txt

스크립트는 stdin에서 입력을 받아 테스트 스크립트에서 파이프 할 수 있습니다.

참고 tee >( cat 1>&2 )테스트 스크립트가 실제로 생성 한 내용을 볼 수 있도록 파이프 라인에 넣었습니다 .

출력 예 (이것은 6 중 1 개의 잘못된 문자로 꽤 잘 실행되었습니다) :

$ python ./asciitest.py | 티> (고양이 1> & 2) | ./scanascii.sh
  ***  
 ** ** 
* **
 ** * 
  **** 
    ***
 ****  
Leptonica가 포함 된 Tesseract 오픈 소스 OCR 엔진 v3.02
9

$ python ./asciitest.py | 티> (고양이 1> & 2) | ./scanascii.sh
   *   
 *** *
   *   
   *   
   *   
   *   
 ***** 
Leptonica가 포함 된 Tesseract 오픈 소스 OCR 엔진 v3.02
1

$ python ./asciitest.py | 티> (고양이 1> & 2) | ./scanascii.sh
  ***  
 ** ** 
** **
** **
** **
  * ** 
  ***  
Leptonica가 포함 된 Tesseract 오픈 소스 OCR 엔진 v3.02
0

$ python ./asciitest.py | 티> (고양이 1> & 2) | ./scanascii.sh
 ***** 
 **    
 ****  
     * 
     * 
 ** * 
  ***  
Leptonica가 포함 된 Tesseract 오픈 소스 OCR 엔진 v3.02
5

$ python ./asciitest.py | 티> (고양이 1> & 2) | ./scanascii.sh
  **** 
 **    
 ***** 
 * * 
*** ***
 ** **
  **** 
Leptonica가 포함 된 Tesseract 오픈 소스 OCR 엔진 v3.02
5

$ python ./asciitest.py | 티> (고양이 1> & 2) | ./scanascii.sh
  ***  
 * ** 
     * 
    ** 
   *** 
  **   
 ******
Leptonica가 포함 된 Tesseract 오픈 소스 OCR 엔진 v3.02
2

$ 

1

LÖVE2D, 560 바이트

t=...;g=love.graphics g.setNewFont(124)g.setBackgroundColor(255,255,255)A=g.newCanvas()B=g.newCanvas()x=1 y=1 g.setColor(255,255,255)g.setCanvas(B)g.clear(0,0,0)for i=1,#t do x=x+1 if t:sub(i,i)=="\n"then x=1 y=y+1 end if t:sub(i,i)=="*"then g.rectangle("fill",x*16,y*16,16,16)end end u=B:newImageData()g.setCanvas(A)S={}for i=0,9 do g.clear(0,0,0,0)g.print(i,48,0)r=A:newImageData()s={i=i,s=0}for x=0,16*8 do for y=0,16*8 do a=u:getPixel(x,y)b=r:getPixel(x,y)s.s=s.s+math.abs(a-b)end end S[i+1]=s end table.sort(S,function(a,b)return a.s<b.s end)print(S[1].i)

먼저 입력 텍스트의 블록 표현을 그린 다음 0-9의 각 숫자에 대해 숫자를 오버레이하고 유사한 픽셀 수를 확인한 후 가장 가까운 숫자를 인쇄합니다. 매우 기본적인 OCR. 모든 테스트 사례와 일치하며 돌연변이와 합리적으로 잘 수행됩니다.

전화 :

love.exe "" "INPUT"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.