이 문제풀이는 앞장에서의 트레이닝을 했다고 가정한다. 앞장에서의 트레이닝을 안했으면 인식을 못한다.
1. 이미지를 다운받는다.
2. 앞장에서와 같이 인식률을 높이기 위해 다운받은 이미지를 변경시킨다.
3. 인식후 x좌표를 기준으로 정렬해서 변수에 집어넣는다.
4. 변수의 알파벳과 표정을 매치시켜 답을 도출한다.
#-*- coding: cp949 -*-
import operator
import cv2
import numpy as np
import urllib2
import Image
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('https://www.hackthis.co.uk/levels/extras/captcha2.php')
req.add_header('cookie','PHPSESSID=쿠키')
urllib2.urlopen(req).read()
req = urllib2.Request('https://www.hackthis.co.uk/levels/extras/captcha2.php')
req.add_header('cookie','PHPSESSID=쿠키')
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('python.png') #python.png라는 이름으로 이미지를 받아온다. 나의 프로젝트의 경로에.
im = Image.open('python.png') #이미지를 열어서 이모티콘 부분은 검은색으로, 배경은 흰색으로 채색한다.
for i in range(0,im.size[1]):
for j in range(0,im.size[0]):
if im.getpixel((j,i))[0] > 15:
im.putpixel((j,i),(255,255,255))
else:
im.putpixel((j,i),(0,0,0))
im.save('test1.png')
#아래는 인식하는 부분 그대로 붙여넣었다.
####### training part ###############
samples = np.loadtxt('generalsamples.data',np.float32)
responses = np.loadtxt('generalresponses.data',np.float32)
responses = responses.reshape((responses.size,1))
model = cv2.KNearest()
model.train(samples,responses)
############################# testing part #########################
im = cv2.imread('test1.png')
out = np.zeros(im.shape,np.uint8)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray,(5,5),0)
thresh = cv2.adaptiveThreshold(blur,255,1,1,11,2)
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
dic = {}
for cnt in contours:
if cv2.contourArea(cnt)>10:
[x,y,w,h] = cv2.boundingRect(cnt)
move = 0
if (w==19 and h==20) or (w==17 and h==15): #h==20은 이모티콘용, h==15는 하트용
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
roi = thresh[y:y+h,x:x+w]
roismall = cv2.resize(roi,(10,10))
roismall = roismall.reshape((1,100))
roismall = np.float32(roismall)
retval, results, neigh_resp, dists = model.find_nearest(roismall, k = 1)
string = str(chr(int((results[0][0]))+97))
cv2.putText(out,string,(x,y+h),0,1,(0,255,0))
dic[x]=string
move -= 10
cv2.waitKey(0)
dic = sorted(dic.iteritems(), key=operator.itemgetter(0)) #바로 앞장에서 말했는데, x좌표순으로 인식한 이모티콘들을 정렬했다.
answer = ''
face = {'a':':D','b':':)','c':':p','d':':(','e':';)','f':'B)','g':':@','h':':o','i':':s','j':':|','k':':/','l':'<3'} #각각 사전에 어떤 영소문자와 이모티콘이 대입되는지 확인 후 변경해준다.
for i in range(len(dic)):
answer += face[dic[i][1]]
print answer
req = urllib2.Request('https://www.hackthis.co.uk/levels/captcha/2','answer='+answer) #만들어진 이모티콘을 보내준다.
req.add_header('cookie','PHPSESSID=쿠키')
print urllib2.urlopen(req).read()
hackthis captcha3번도 위의 코드에서 사진 받아오는 부분만 3으로, 요청 받고 보내는 부분만 3으로 바꾸면 잘 된다. 또 if (w==19 and h==20) or (w==17 and h==15): 부분에서 w>=17 and h==20인가?로 바꿔주면 된다. 다만 위 아래로 올라가있는건 상관없이 인식되는데 종족 맞닿아 있는 이모티콘들은 인식을 못할 때가 있으므로 될 때까지 여러번 요청을 보내면 된다. (5번정도 보내면 됨)