利用opencv-python和tessract-ocr实现简单是身份证矫正和信息识别(未封装面向对象)个人记录未整合

 
  
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import cv2
import numpy as np
from imutils.perspective import four_point_transform

img=cv2.imread('./img/img1.png')
# cv2.imshow('img',img)
# cv2.waitKey()
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #灰度处理
# cv2.imshow('gray',gray)
# cv2.waitKey()
blurred = cv2.GaussianBlur(gray, (5,5),0,0) #高斯滤波
# cv2.imshow('blurred',blurred)
# cv2.waitKey()
element=cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))  # 获取自定义核 第一个参数MORPH_RECT表示矩形的卷积核,当然还可以选择椭圆形的、交叉型的
dilate = cv2.dilate(blurred,element) # 膨胀操作
# cv2.imshow('dilate',dilate)
# cv2.waitKey()
canny = cv2.Canny(dilate, 30, 130, 3)  # 边缘提取
cv2.imshow('canny',canny)
cv2.waitKey()

image, contours, hier = cv2.findContours(canny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #找轮廓
# 找出最大轮廓
max_area = 0
max_contour = 0
for contour in contours:
    tmparea = abs(cv2.contourArea(contour))
    if max_area < tmparea:
        max_area = tmparea
        max_contour = contour
# print(max_contour)
imge=cv2.drawContours(img.copy(),max_contour,-1,(0,0,255),3) #画出轮廓
# cv2.imshow('imge',imge)
# cv2.waitKey()

# 透视变化
rect = cv2.minAreaRect(max_contour)  #得到最小外接矩形的(中心(x,y), (,), 旋转角度)
# print(rect)
boxPoints=cv2.boxPoints(rect)   # cv2.boxPoints(rect) for OpenCV 3.x 获取最小外接矩形的4个顶点

# 去掉边缘 取最小
for i in range(len(boxPoints)) :
    x1 = boxPoints[i][0]
    y1 = boxPoints[i][1]
    # print(x1,y1)
    min_distancey = 0
    for point in max_contour:
        distancey = abs(point[0][0] - x1) + abs(point[0][1] - y1)
        if min_distancey == 0 :
            min_distancey = distancey
        else :
            if distancey < min_distancey :
                min_distancey = distancey
                boxPoints[i] = point

fin=four_point_transform(img, boxPoints.reshape(4,2))
cv2.imshow('fin',fin)
cv2.waitKey()

cv2.imwrite('./img/fin.png',fin)

import pytesseract
import cv2
import matplotlib.pyplot as plt
import dlib
import matplotlib.patches as mpatches
from skimage import io,draw,transform,color
import numpy as np
import pandas as pd
import re
import pytesseract

detector = dlib.get_frontal_face_detector()
image = io.imread("./img/fin.png")
dets = detector(image, 2) #使用detector进行人脸检测 dets为返回的结果
## 将识别的图像可视化
# cv2.imshow('img',dets)
# cv2.waitKey()
plt.figure()
ax = plt.subplot(111)
ax.imshow(image)
plt.axis("off")

for i, face in enumerate(dets):
    # 在图片中标注人脸,并显示
    left = face.left()
    top = face.top()
    right = face.right()
    bottom = face.bottom()
    # rect = mpatches.Rectangle((left,bottom), (right - left)*2, (top - bottom)*2,fill=False, edgecolor='red', linewidth=1)
    # ax.add_patch(rect)
    width = right - left
    high = bottom - top
    left2 = np.uint(left - 0.4 * width)
    bottom2 = np.uint(bottom + 0.55 * high)
    rect = mpatches.Rectangle((left2, bottom2), 1.85 * width, -2.2 * high,fill=False, edgecolor='blue', linewidth=1)
    ax.add_patch(rect)
    # print(bottom2)
    # print(left2)

    x=int(left2+1.85*width)-1
    y=int(bottom2-2.2*high)-1
    # print(high,width)
    # print(x,y)
    # print(bottom2,left2)

    cross=image[y:bottom2,left2:x]
    cv2.imshow('ee',cross)
    cv2.waitKey()
    img=cv2.imread('./img/fin.png')
    img[0:bottom2,left2:-1]=255
    cv2.imshow('ee', img)
    cv2.waitKey()
    cv2.imwrite('./img/cut.png',img)
plt.show()




#
# ax.add_patch(rect)
# plt.show()
#
# ## 身份证上人的照片
# top2 = np.uint(bottom2+2.2*high)
# right2 = np.uint(left2+1.8*width)
# image3 = image[top2:bottom2,left2:right2]
# # plt.imshow(image3)
# plt.axis("off")
# plt.show()


# coding:utf8

import sys

import cv2
import numpy as np
import pytesseract
from PIL import Image

def preprocess(gray):
    # 1. Sobel算子,x方向求梯度
    sobel = cv2.Sobel(gray, cv2.CV_8U, 1, 0, ksize = 3)
    # 2. 二值化
    ret, binary = cv2.threshold(sobel, 0, 255, cv2.THRESH_OTSU+cv2.THRESH_BINARY)

    # 3. 膨胀和腐蚀操作的核函数
    element1 = cv2.getStructuringElement(cv2.MORPH_RECT, (30, 9))
    element2 = cv2.getStructuringElement(cv2.MORPH_RECT, (24, 6))

    # 4. 膨胀一次,让轮廓突出
    dilation = cv2.dilate(binary, element2, iterations = 1)

    # 5. 腐蚀一次,去掉细节,如表格线等。注意这里去掉的是竖直的线
    erosion = cv2.erode(dilation, element1, iterations = 1)

    # 6. 再次膨胀,让轮廓明显一些
    dilation2 = cv2.dilate(erosion, element2, iterations = 4)


    # 7. 存储中间图片
    # cv2.imwrite("binary.png", binary)
    # cv2.imwrite("dilation.png", dilation)
    # cv2.imwrite("erosion.png", erosion)
    # cv2.imwrite("dilation2.png", dilation2)

    return dilation2


def findTextRegion(img):
    region = []

    # 1. 查找轮廓
    (_,contours,_)= cv2.findContours(img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

    # 2. 筛选那些面积小的
    for i in range(len(contours)):
        cnt = contours[i]
        # 计算该轮廓的面积
        area = cv2.contourArea(cnt)

        # 面积小的都筛选掉
        if(area < 1000):
            continue

        # 轮廓近似,作用很小
        epsilon = 0.001 * cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, epsilon, True)

        # 找到最小的矩形,该矩形可能有方向
        rect = cv2.minAreaRect(cnt)
        # print("rect is: ")
        # print(rect)

        # box是四个点的坐标
        box = cv2.boxPoints(rect)
        box = np.int0(box)

        # 计算高和宽
        height = abs(box[0][1] - box[2][1])
        width = abs(box[0][0] - box[2][0])

        # 筛选那些太细的矩形,留下扁的
        if(height > width * 1.2):
            continue

        region.append(box)

    return region


def detect(img):
    cut_img=[]
    # 1.  转化成灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # cv2.imshow('w',gray)
    # img_GaussianBlur = cv2.GaussianBlur(gray, (7, 7), 0)
    # sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0)
    # sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1)
    #
    # sobelx = np.uint8(np.absolute(sobelx))
    # sobely = np.uint8(np.absolute(sobely))
    # sobelcombine = cv2.bitwise_or(sobelx, sobely)
    # img_bilateralFilter = cv2.bilateralFilter(sobelcombine, 1, 75, 75)
    # dst = cv2.bilateralFilter(gray, 0, 100, 15)
    # cv2.imshow('g',dst)
    # cv2.waitKey()
    #
    #
    # # im_at_mean = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5,10)  # 算术平法的自适应二值化
    # im_at_mean = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 8) # 高斯加权均值法自适应二值化
    # # retval, thresh = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)  # 固定阈值二值化
    # cv2.imshow('w', im_at_mean)
    # cv2.waitKey()
    # img_medianBlur = cv2.medianBlur(gray, 5)
    # img_Blur = cv2.blur(gray, (5, 5))
    img_bilateralFilter = cv2.bilateralFilter(gray, 15, 50, 50)
    # img_Blur = cv2.blur(gray, (5, 5))
    # img_GaussianBlur = cv2.GaussianBlur(gray, (7, 7), 0)
    # img_medianBlur = cv2.medianBlur(gray, 5)
    # kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
    #
    # # 开运算
    # opened = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
    # # 显示腐蚀后的图像
    # cv2.imshow("Open", opened)
    # # 腐蚀图像
    # eroded = cv2.erode(gray, kernel)
    # # 显示腐蚀后的图像
    # cv2.imshow("Eroded Image", eroded)

    im_at_mean = cv2.adaptiveThreshold(img_bilateralFilter, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 5, 5)  # 算术平法的自适应二值化
    cv2.imshow('pic2',im_at_mean)
    cv2.waitKey()

    ###########二值化算法

    # 2. 形态学变换的预处理,得到可以查找矩形的图片
    dilation = preprocess(im_at_mean)
    # cv2.imshow('2',dilation)
    # 3. 查找和筛选文字区域
    region = findTextRegion(dilation)
    # print(region)
    # 4. 用红线画出这些找到的轮廓
    for box in region:
        # cv2.drawContours(im_at_mean, [box], 0, (0, 0, 255), 2)

        Xs = [i[0] for i in box]
        Ys = [i[1] for i in box]
        x1 = min(Xs)
        x2 = max(Xs)
        y1 = min(Ys)
        y2 = max(Ys)
        hight = y2 - y1
        width = x2 - x1
        # print(hight,width)
        crop_img= im_at_mean[y1:y1 + hight, x1:x1 + width]
        # cv2.imshow('re',crop_img)
        # cv2.waitKey()
        code = pytesseract.image_to_string(crop_img, lang='chi_sim')

        print(code)










    # # # 带轮廓的图片
    # # cv2.imwrite("contours.png", img)
    #
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()

if __name__ == '__main__':
    # 读取文件

    img = cv2.imread('./img/cut.png')
    detect(img)


你可能感兴趣的:(ocr技术)