深度学习 09_1 图像扫描(OpenCV系列)

  1. 图片预处理
  2. 透视变换,拉正视角
  3. tesseract进行识别

def cv_show(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

# 导包
import numpy as np
import cv2

# 读取图片
image = cv2.imread('./images/page.jpg')
print(image.shape)

# 计算比例,限定高度500
ratio = image.shape[0] / 500.0
orig = image.copy()

# 对图片进行统一的resize
# 封装resize功能
# cv_show('img', image)

def resize(image, width = None, height = None, inter = cv2.INTER_AREA):
    # cv2.resize()
    dim = None
    (h, w) = image.shape[:2]
    # print(image.shape[:2])
    if width is None and height is None:
        return image
    if width is None:  # 只提供了高度
        r = height /float(h)
        dim = (int(w * r), height)
        # print(dim)
    else: # 如果只提供了宽度
        r = width / float(w)
        dim = (width, int(h * r))

    resized = cv2.resize(image, dim, interpolation = inter)
    return resized

# 对图片进行热size
image = resize(orig, height = 500)

# 灰度化处理
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 高斯模糊去噪点
gray = cv2.GaussianBlur(gray, (5,5), 0)

# 边缘检测
edged = cv2.Canny(gray, 75, 200)
cv_show('img', edged)


# 用边缘检测的结果进行轮廓检测
cnts = cv2.findContours(edged.copy(), cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)[0]

# 按照面积排序
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)
print(len(cnts))

# 显示轮廓
image_contours = cv2.drawContours(image.copy(), cnts, -1, (0, 0, 255), 2)  
cv_show('img', image_contours)

# 遍历轮廓,找出最大轮廓
for c in cnts:
    # 计算轮廓周长
    perimeter = cv2.arcLength(c, True)
    # 多边形逼近
    approx = cv2.approxPolyDP(c, 0.02 * perimeter, True)
    
    if len(approx) == 4:
        screen_cnt = approx
        break

# 显示轮廓
image_contours = cv2.drawContours(image.copy(), [screen_cnt], -1, (0, 0, 255), 2)  
cv_show('img', image_contours)

def order_points(pts):
    # 创建全为0 的矩阵, 来接收找到的坐标
    rect = np.zeros((4, 2), dtype = 'float32')
    s = pts.sum(axis = 1)
    # 左上角的坐标一定是X,Y相加最小的,右下为最大的
    rect[0] = pts[np.argmin(s)]
    rect[2] = pts[np.argmax(s)]
    
    # 右上角的x,y 相减的差值一定是最小的
    # 左下角的x,y 相减,差值一定是最大的
    diff = np.diff(pts, axis = 1)
    rect[1] = pts[np.argmin(diff)]
    rect[3] = pts[np.argmax(diff)]
    return rect

def four_point_transform(image, pts):
    rect = order_points(pts)
    (tl, tr, br, bl) = rect
    
    widthA = np.sqrt((br[0] - bl[0]) ** 2 + (br[1] - bl[1]) ** 2)
    widthB = np.sqrt((tr[0] - tl[0]) ** 2 + (tr[1] - tl[1]) ** 2)
    max_width = max(int(widthA), int(widthB))
    
    heightA = np.sqrt((tr[0] - br[0]) ** 2 + (tr[1] - br[1]) ** 2)
    heightB = np.sqrt((tl[0] - bl[0]) ** 2 + (tl[1] - bl[1]) ** 2)
    max_height = max(int(heightA), int(heightB))
    
    dst = np.array([
        [0, 0],
        [max_width - 1, 0],
        [max_width -1, max_height - 1],
        [0, max_height -1]], dtype = 'float32')
    
    M = cv2.getPerspectiveTransform(rect, dst)
    warped = cv2.warpPerspective(image, M, (max_width, max_height))
    
    return warped

# 视图透视变换
# 将视图转为正对透视
warped = four_point_transform(orig, screen_cnt.reshape(4, 2) * ratio)

# 二值化处理
warped = cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
ref = cv2.threshold(warped, 120, 255, cv2.THRESH_BINARY)[1]
# print(ref.shape)
cv_show('ref', ref)

# 把处理好的图片写入文件
cv2.imwrite('./scan1.jpg', ref)
# cv_show('warp', warped)

# 调用电脑的识图转文字功能 
import pytesseract 
from PIL import Image 
# pytesseract要求的image不是OpenCV读进来的image, 而是pillow这个包, 即PIL
text = pytesseract.image_to_string(Image.open('./scan1.jpg'))

print(text)

你可能感兴趣的:(深度学习,opencv,深度学习,计算机视觉)