#! /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)