http://www.dareyourmind.net/menu.php
들어가보면 스도쿠모양의 틀이 있고, 노란색 점 갯수로 스도쿠를 하면 된다. 매번 이미지는 바뀌며, 제한시간은 5초이다.
저런 이미지에서 뽑아서 하면 된다. 스도쿠 문제는 예전에 풀었던 포스트가 있으므로 거기서 알고리즘을 또 그대로... 가져왔다.
방법론
1. 주변의 회색부분은 흰색으로 만들고 검은색 사각형을 인식한다. 각 81개의 검은 사각형이 인식되는데, 각각의 검은 사각형의 x,y좌표를 처음엔 y좌표로 정렬 그다음엔 x좌표로 정렬해서 따로 저장해둔다.
그러면 현재 위 사진 기준으로 (7,2,5,8,4,' ',' ',3,6,4,1...) 순서로 정렬된다.
2. 노란색 점을 인식해서 각각 노란색점이 위에서 저장해놓은 x,y좌표의 사각형 안에 있는지 확인한다. 사각형 안에 있으면 어떤 변수를 +1시켜줘서 개수를 증가시킨다. 0이면 없는걸로 친다.
3. 스도쿠를 계산해서 알아서 잘 처리해서 보낸다.
코딩.
# -*- encoding: cp949 -*- import urllib2 import re import random import os import operator import numpy as np import Image import cv2 session = 'PHPSESSID=gscil0mtiv6qpehu275cebp6c6' # GLOBAL VARIABLES grid_size = 81 def isFull (grid): return grid.count('.') == 0 # can be used more purposefully def getTrialCelli(grid): for i in range(grid_size): if grid[i] == '.': #print 'trial cell', i return i def isLegal(trialVal, trialCelli, grid): cols = 0 for eachSq in range(9): trialSq = [ x+cols for x in range(3) ] + [ x+9+cols for x in range(3) ] + [ x+18+cols for x in range(3) ] cols +=3 if cols in [9, 36]: cols +=18 if trialCelli in trialSq: for i in trialSq: if grid[i] != '.': if trialVal == int(grid[i]): #print 'SQU', return False for eachRow in range(9): trialRow = [ x+(9*eachRow) for x in range (9) ] if trialCelli in trialRow: for i in trialRow: if grid[i] != '.': if trialVal == int(grid[i]): #print 'ROW', return False for eachCol in range(9): trialCol = [ (9*x)+eachCol for x in range (9) ] if trialCelli in trialCol: for i in trialCol: if grid[i] != '.': if trialVal == int(grid[i]): #print 'COL', return False #print 'is legal', 'cell',trialCelli, 'set to ', trialVal return True def setCell(trialVal, trialCelli, grid): grid[trialCelli] = trialVal return grid def clearCell( trialCelli, grid ): grid[trialCelli] = '.' #print 'clear cell', trialCelli return grid def hasSolution (grid): if isFull(grid): #print '\nSOLVED' return True else: trialCelli = getTrialCelli(grid) trialVal = 1 solution_found = False while ( solution_found != True) and (trialVal < 10): #print 'trial valu',trialVal, if isLegal(trialVal, trialCelli, grid): grid = setCell(trialVal, trialCelli, grid) if hasSolution (grid) == True: solution_found = True return True else: clearCell( trialCelli, grid ) #print '++' trialVal += 1 return solution_found def printGrid (grid, add_zeros): print i = 0 for val in grid: if add_zeros == 1: if int(val) < 10: print '0'+str(val), else: print val, else: print val, i +=1 if i in [ (x*9)+3 for x in range(81)] +[ (x*9)+6 for x in range(81)] +[ (x*9)+9 for x in range(81)] : print '|', if add_zeros == 1: if i in [ 27, 54, 81]: print '\n---------+----------+----------+' elif i in [ (x*9) for x in range(81)]: print else: if i in [ 27, 54, 81]: print '\n------+-------+-------+' elif i in [ (x*9) for x in range(81)]: print 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.dareyourmind.net/Challenge/sudoku2.php') req.add_header('Cookie',session) 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 def main (): download_photo('sudoku.png') im = Image.open('sudoku.png').convert('RGB') for i in range(im.size[1]): for j in range(im.size[0]): if im.getpixel((j,i))==(74,74,74): im.putpixel((j,i),(255,255,255)) im.save('sudoku1.png') im = cv2.imread('sudoku1.png') imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(imgray,127,255,0) contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) square = [] for cnt in contours: if int(cv2.contourArea(cnt)) == 782: #작은 네모 하나 인식. [x,y,w,h] = cv2.boundingRect(cnt) square.append([x,y,x+w,y+h,0]) #rect = cv2.minAreaRect(cnt) #box = cv2.cv.BoxPoints(rect) #box = np.int0(box) #cv2.drawContours(im,[box],0,(0,255,0),2) #cv2.imshow('result',im) #cv2.waitKey(0) square = sorted(square, key = lambda x:(x[1],x[0])) for cnt in contours: if int(cv2.contourArea(cnt)) < 10: #노란색 점 인식. [x,y,w,h] = cv2.boundingRect(cnt) for s in square: if s[0] < x and s[2] > x and s[1] < y and s[3] > y: s[4] += 1 sampleGrid = []; answer_index = [] for s in range(len(square)): if square[s][4]==0: sampleGrid.append('.') answer_index.append(s) else: sampleGrid.append(square[s][4]) #sampleGrid = ['2', '1', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '.', '3', '1', '.', '.', '.', '.', '9', '4', '.', '.', '.', '.', '7', '8', '2', '5', '.', '.', '4', '.', '.', '.', '.', '.', '.', '6', '.', '.', '.', '.', '.', '1', '.', '.', '.', '.', '8', '2', '.', '.', '.', '7', '.', '.', '9', '.', '.', '.', '.', '.', '.', '.', '.', '3', '1', '.', '4', '.', '.', '.', '.', '.', '.', '.', '3', '8', '.'] printGrid(sampleGrid, 0) if hasSolution (sampleGrid): printGrid(sampleGrid, 0) else: print 'NO SOLUTION' answer = '' for i in range(len(answer_index)): answer += str(sampleGrid[answer_index[i]]) #print answer req = urllib2.Request('http://www.dareyourmind.net/menu.php?page=programming8&checked='+answer) req.add_header('cookie',session) print urllib2.urlopen(req).read() if __name__ == "__main__": main()
'machine learning, image' 카테고리의 다른 글
데이터마이닝, 머신러닝 공부관련(커리큘럼) (2) | 2015.09.01 |
---|---|
Net-Force Hmmm, I don't see it... (0) | 2015.07.24 |
W3Challs Chuck Norris Challenge(half) (0) | 2015.07.23 |
WeChall Crackcha 관련 삽질. (0) | 2015.07.11 |
python OCR of Hand-written Data using kNN 코드해석 (0) | 2015.06.30 |