machine learning, image

Enigmagroup missions/programming 8 (섞여있는 글자 인식)

qkqhxla1 2015. 4. 5. 17:45

이미지를 해석해서 해당 이미지가 어떤 글자를 나타내는지 보고, 해석해서 보내면 된다.

일단 문제 페이지에 들어가보면 이런식의 이미지가 하나 뜬다.


딱 봐도 흰색 부분을 잘 어떻게 만들다보면 어떤 글자가 만들어질것 같다. 처음에는 못풀다가, 생활코딩에 질문을 올려서 힌트를 좀 얻었다. 가장 도움이 됬던 말은 '자연 영상의 변화는 공간상에서 급격하게 변하지 않는다' 라는 말이었다. 음... 이미지를 다운받아서 각 색상을 RGB값으로 변경 후, 첫번째 RGB값만 정렬해서 출력해보았다. 그런데 R,G,B중 특정 하나의 글자가 어떤 값에서 시작해서 1씩 증가하는걸 발견했다.


딱 이걸 보고 감이 대충 왔다. 아마도 작은 순서대로 위에서부터 이미지를 하나씩 복사하면 되지 않을까..? 

코딩을 했더니 그게 맞았다.


위와 같던 섞여있던 사진이 잘 변화된다. 이 이후로는 pytesser로 인식해서 보냈더니 성공했다.

# -*- encoding: cp949 -*-
import Image
import urllib2
import copy
import pytesser

def download_photo(filename):
    file_path = "%s%s" % ("C:\\Users\\Ko\\Documents\\Visual Studio 2012\\Projects\\PythonApplication37\\", filename)
    downloaded_image = file(file_path, "wb")
    
    req = urllib2.Request('http://www.enigmagroup.org/missions/programming/8/image.php')
    req.add_header('Cookie','본인 쿠키값')
    image_on_web = urllib2.urlopen(req)
    while True:
        buf = image_on_web.read()
        if len(buf) == 0:
            break
        downloaded_image.write(buf)
    
    downloaded_image.close()
    image_on_web.close()
    return file_path
 
download_photo('image.png') #캡챠를 다운로드받아서
im = Image.open('image.png').convert('RGB').save('image1.png') #RGB형식으로 변환 후 백업용으로 image1.png라는 이름으로 저장해둔다.
im = Image.open('image.png').convert('RGB') #다운받은 image.png를 RGB형식으로 변환 후 연다.
image_l = []
for i in range(im.size[1]): #각 row의 가장 첫번째 픽셀들만 가져와서 image_l리스트에 집어넣는다. (이걸로 정렬하면 된다.)
    first = im.getpixel((0,i))
    image_l.append(first)

image_l_backup = copy.copy(image_l) #백업용으로 image_l_backup리스트에 복사해둔다. copy.copy를 사용하는 이유는 깊은 복사를 위해서이다.
image_l.sort() #정렬한다. 이걸 출력해보면 R,G,B중 하나가 어떤 특정 숫자 순서부터 1씩 증가하는걸 확인할수 있다.
dic = {}
for i in range(len(image_l)): #위에 만들어놓은 image_l과 백업해놓은 image_l_backup리스트로 사전을 만든다. 각 줄이 섞여있는데, 몇번째 줄이 원래는 몇번째인지를 판별하기 위한 사전이다.
    for j in range(len(image_l_backup)):
        if image_l[i]==image_l_backup[j]:
            dic[j] = i

im = Image.open('image.png').convert('RGB') 
im_copy = Image.open('image1.png')
for i in range(len(dic)): #위에 만들어놓은 사전만큼 반복한다. 이건 각 사진의 row만큼 반복하는것과 같다.
    for j in range(im.size[0]): #각 사진의 column만큼 반복.
        im_copy.putpixel((j,dic[i]),im.getpixel((j,i))) #여기가 가장 중요한 부분이다. putpixel함수로 image1.png의 원래 글자의 좌표(j,dic[i])에 이미지의 해당 픽셀을 가져와서
#붙여넣는다. 이부분은 복잡해서 직접 짠 나말고는 이해 못할듯....
im_copy.save('image1.png') #제대로 위치 복사 후 image1.png로 저장한다.

answer = pytesser.image_to_string(Image.open('image1.png')).replace('\n','') #해당 image1.png에서 글자를 추출해내서 보낸다.
req = urllib2.Request('http://www.enigmagroup.org/missions/programming/8/image.php','answer='+answer+'&submit=1')
req.add_header('Cookie','본인 쿠키값')
req.add_header('referer','http://www.enigmagroup.org/missions/programming/8/image.php')
print urllib2.urlopen(req).read()