import cv2
import numpy as np
import pytesseract
from PIL import Image
from PIL import ImageFilter
import os
class Analyzer(object):
def __init__(self, img_path):
self.img_path = img_path
self.img = cv2.imread(img_path)
self.imgPreprocess = None
self.rows, self.cols, self.channels = self.img.shape
self.height, self.width = self.img.shape[:2]
self.m_debug = True
def th1(self,img):
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 0, 255,
cv2.THRESH_BINARY + cv2.THRESH_OTSU)
return thresh
def preprocess(self):
self.resizeCaptcha()
img_thresh = self.th1(self.img)
if self.m_debug:
cv2.imshow("thres", img_thresh)
cv2.imwrite("debug/threshold.png", img_thresh)
kernel = np.ones((2,2),np.uint8)
closing = cv2.morphologyEx(img_thresh , cv2.MORPH_CLOSE, kernel)
if self.m_debug:
cv2.imshow("close", closing)
cv2.imwrite("debug/closing.png",closing)
constant = cv2.copyMakeBorder(closing ,30,30,30,30,cv2.BORDER_CONSTANT,value=255)
constant = self.inverseColor(constant)
constantSrc = cv2.merge((constant,constant,constant))
self.imgPreprocess = constantSrc.copy()
def tessRecognize(self):
os.system('tesseract debug/closing.png ./result')
try:
with open('result.txt', 'r') as f :
for line in f:
print line
except:
pass
cv2.imshow('orignal',self.img)
cv2.waitKey(0)
def inverseColor(self,img):
if len(img.shape)==2:
for i in range(img.shape[0]):
for j in range(img.shape[1]):
if img[i][j]==255:
img[i][j]=0
else:
img[i][j]=255
elif len(img.shape)==3:
for i in range(img.shape[0]):
for j in range(img.shape[1]):
for k in range(img.shape[2]):
if img[i][j][k]==255:
img[i][j][k]=0
else:
img[i][j][k]=255
return img
def analyze(self):
self.resizeCaptcha()
img_thresh = self.th1(self.img)
if self.m_debug:
cv2.imshow("thres", img_thresh)
cv2.imwrite("debug/threshold.png", img_thresh)
kernel = np.ones((2,2),np.uint8)
closing = cv2.morphologyEx(img_thresh , cv2.MORPH_CLOSE, kernel)
if self.m_debug:
cv2.imshow("close", closing)
cv2.imwrite("debug/closing.png",closing)
constant = cv2.copyMakeBorder(closing ,30,30,30,30,cv2.BORDER_CONSTANT,value=255)
constant = self.inverseColor(constant)
constantSrc = cv2.merge((constant,constant,constant))
self.imgPreprocess = constantSrc.copy()
if self.m_debug:
cv2.imwrite('debug/constant.png',constant)
cv2.imwrite('debug/constantSrc.png',constant)
constant, contours, hierarchy = cv2.findContours(constant,
cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if self.m_debug:
for i in range(len(contours)):
print '绘制第',i,'个轮廓'
imgContours = cv2.drawContours(constantSrc, contours, i, (0,255,0), 2)
cv2.imshow('contours',imgContours)
cv2.imwrite('debug/contours.png',imgContours)
cv2.waitKey(0)
rotate_rects = []
box_rects = []
for i in range(0,len(contours)):
mr = cv2.minAreaRect(contours[i])
if self.verifySize(mr):
box = cv2.boxPoints(mr)
box = np.int0(box)
rotate_rects.append(mr)
box_rects.append(box)
else:
pass
rotate_rects = sorted(rotate_rects,key = lambda x:x[0][0])
box_rects = sorted(box_rects,key = lambda x:x[0][0])
if self.m_debug:
for i in range(len(box_rects)):
print "绘制第",i,"个矩形"
mr = rotate_rects[i]
print mr
print box_rects[i]
imgContoursChosen = cv2.drawContours(constantSrc, box_rects, i, (255,0,0), 1)
cv2.imshow('contours chosen',imgContoursChosen)
cv2.imwrite('debug/contoursChosen.png',imgContoursChosen)
cv2.waitKey(0)
charTarget = []
for i in range(0,len(rotate_rects)):
mr = rotate_rects[i]
if mr[1][1] == 0:
continue
ratio = mr[1][0] / mr[1][1]
angle = mr[2]
rect_size = [mr[1][0],mr[1][1]]
print '正在处理第',i,'个矩形'
if ( ratio > 1 ):
angle = 90 + angle
rect_size[0],rect_size[1] = rect_size[1],rect_size[0]
center_x = (box_rects[i][0][0]+box_rects[i][1][0]+box_rects[i][2][0]+box_rects[i][3][0])/4
center_y = (box_rects[i][0][1]+box_rects[i][1][1]+box_rects[i][2][1]+box_rects[i][3][1])/4
center = (center_x,center_y)
rotmat = cv2.getRotationMatrix2D(center,angle,1)
imgSrc = self.imgPreprocess
rows,cols,channels = imgSrc.shape
rotated = cv2.warpAffine(imgSrc, rotmat,(cols,rows))
print rotated .shape
if self.m_debug:
picname = 'debug/rotate_'+str(i)+'.png'
cv2.imwrite(picname,rotated)
imgResized = self.showResultMat(rotated, (int(rect_size[0]),int(rect_size[1])),center , i)
charTarget.append(imgResized)
def verifySize(self, minAreaRect):
area = minAreaRect[1][0] * minAreaRect[1][1]
if area > 6000 and area < 15000:
return True
return False
def captureChar(self, img, rect_size, center, index):
imgCorp = cv2.getRectSubPix(imgRotated,rect_size,center)
def showResultMat(self, imgRotated, rect_size, center, index):
m_width = 136
m_height = 36
imgCorp = cv2.getRectSubPix(imgRotated,rect_size,center)
imgCorp = cv2.copyMakeBorder(imgCorp ,30,30,30,30,cv2.BORDER_CONSTANT,value=(0,0,0))
imgCorp = self.inverseColor(imgCorp)
print 'resize',imgCorp.shape
if self.m_debug:
picname = 'debug/rotate_fragment_'+str(index)+'.png'
cv2.imwrite(picname,imgCorp)
return imgCorp
def show(self):
cv2.namedWindow("Image")
cv2.imshow("Image", self.img)
cv2.waitKey(0)
def resizeCaptcha(self):
rows,cols,channels = self.img.shape
img_resize = cv2.resize(self.img,(cols*10,rows*10),interpolation = cv2.INTER_LINEAR)
self.img = img_resize
if __name__ == '__main__':
analyzer = Analyzer('./testpic/4.jpg')
analyzer.preprocess()
analyzer.tessRecognize()