In [221]:
#import requests
#with open('kaptcha.png', 'wb') as f:
#    res = requests.get('http://railway.hinet.net/ImageOut.jsp')
#    f.write(res.content)

In [1]:
from PIL import Image, ImageEnhance
image = Image.open('kaptcha.png')
image


Out[1]:

In [2]:
import cv2
import numpy
from matplotlib import pyplot as plt
im = cv2.imread('kaptcha.png', flags=cv2.IMREAD_GRAYSCALE)
retval, im = cv2.threshold(im, 115, 255, cv2.THRESH_BINARY_INV)

In [3]:
%pylab inline
plt.imshow(im)


Populating the interactive namespace from numpy and matplotlib
Out[3]:
<matplotlib.image.AxesImage at 0x6cb6670>

In [4]:
for i in xrange(len(im)):
    for j in xrange(len(im[i])):
        if im[i][j] == 255:
            count = 0 
            for k in range(-2, 3):
                for l in range(-2, 3):
                    try:
                        if im[i + k][j + l] == 255:
                            count += 1
                    except IndexError:
                        pass
            if count <= 4:
                im[i][j] = 0

In [5]:
im = cv2.dilate(im, (2, 2), iterations=1)
plt.imshow(im)


Out[5]:
<matplotlib.image.AxesImage at 0x6dd8630>

In [6]:
print len(im[0])


200

In [7]:
image, contours, hierarchy = cv2.findContours(im.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted([(c, cv2.boundingRect(c)[0]) for c in contours], key=lambda x:x[1])

arr = []

for index, (c, _) in enumerate(cnts):
    (x, y, w, h) = cv2.boundingRect(c)
    #print (x, y, w, h)
    try:
        # 只將寬高大於 10 視為數字留存
        if w > 10 and h > 10:
            add = True
            for i in range(0, len(arr)):
                # 這邊是要防止如 0、9 等,可能會偵測出兩個點,當兩點過於接近需忽略
                if abs(cnts[index][1] - arr[i][0]) <= 3:
                    add = False
                    break
            if add:
                arr.append((x, y, w, h))
                print (x, y, w, h)
    except IndexError:
        pass


(12, 11, 16, 17)
(41, 16, 16, 16)
(78, 17, 16, 17)
(137, 26, 16, 16)
(158, 10, 18, 20)

In [9]:
import time
for index, (x, y, w, h) in enumerate(arr):
    roi = im[y: y + h, x: x + w]
    thresh = roi.copy() 
    
    angle = 0
    smallest = 999
    row, col = thresh.shape

    for ang in range(-60, 61):
        M = cv2.getRotationMatrix2D((col / 2, row / 2), ang, 1)
        t = cv2.warpAffine(thresh.copy(), M, (col, row))

        r, c = t.shape
        right = 0
        left = 999

        for i in xrange(r):
            for j in xrange(c):
                if t[i][j] == 255 and left > j:
                    left = j
                if t[i][j] == 255 and right < j:
                    right = j

        if abs(right - left) <= smallest:
            smallest = abs(right - left)
            angle = ang

    M = cv2.getRotationMatrix2D((col / 2, row / 2), angle, 1)
    thresh = cv2.warpAffine(thresh, M, (col, row))
    # resize 成相同大小以利後續辨識
    thresh = cv2.resize(thresh, (50, 50))
    plt.imshow(thresh)
    plt.show()
    cv2.imwrite('C:\\Users\\Yen\\imag\\' + str(index) + time.strftime("%Y%m%d%H%M%S", time.localtime()) + '.png', thresh)



In [ ]: