从身份证中提取人脸矩形

Dan*_*pov 1 opencv image-processing

我\xe2\x80\x99m 研究了从身份证中提取信息的主题,并找到了一种合适的算法来定位正面的面部。事实上,OpenCV 有 Haar 级联,但我\xe2\x80\x99m 不确定可以用什么来提取人所在的完整矩形,而不仅仅是脸部(如https://github.com中所做的那样) /deepc94/照片-id-ocr)。我\xe2\x80\x99m 尚未测试的几个想法是:

\n\n
    \n
  1. 找到包含面部矩形的卡片内的第二大矩形 \xe2\x80\x99s
  2. \n
  3. 对面矩形执行 \xe2\x80\x9cexplode\xe2\x80\x9d 直到到达边界
  4. \n
  5. 使用滤镜看看能看到什么
  6. \n
\n\n

这里还有什么可以推荐尝试的?任何想法、想法甚至现有的例子都可以。

\n

Ha *_*Bom 7

正常做法:

import cv2
import numpy as np
import matplotlib.pyplot as plt

image = cv2.imread("a.jpg")

gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,128,255,cv2.THRESH_BINARY)
cv2.imshow("thresh",thresh)

thresh = cv2.bitwise_not(thresh)

element = cv2.getStructuringElement(shape=cv2.MORPH_RECT, ksize=(7, 7))

dilate = cv2.dilate(thresh,element,6)
cv2.imshow("dilate",dilate)
erode = cv2.erode(dilate,element,6)
cv2.imshow("erode",erode)

morph_img = thresh.copy()
cv2.morphologyEx(src=erode, op=cv2.MORPH_CLOSE, kernel=element, dst=morph_img)
cv2.imshow("morph_img",morph_img)

_,contours,_ = cv2.findContours(morph_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

areas = [cv2.contourArea(c) for c in contours]

sorted_areas = np.sort(areas)
cnt=contours[areas.index(sorted_areas[-3])] #the third biggest contour is the face
r = cv2.boundingRect(cnt)
cv2.rectangle(image,(r[0],r[1]),(r[0]+r[2],r[1]+r[3]),(0,0,255),2)

cv2.imshow("img",image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

我发现前两个最大的轮廓是边界,第三大的轮廓是脸部。结果:

在此输入图像描述

还有另一种研究图像的方法,即使用各轴像素值的总和:

x_hist = np.sum(morph_img,axis=0).tolist() 
plt.plot(x_hist)
plt.ylabel('sum of pixel values by X-axis')
plt.show()

y_hist = np.sum(morph_img,axis=1).tolist()
plt.plot(y_hist)
plt.ylabel('sum of pixel values by Y-axis')
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述 在此输入图像描述

基于 2 个轴上的像素总和,您可以通过设置阈值来裁剪所需的区域。


San*_*ker 5

Haarcascades 方法(最简单)

# Using cascade Classifiers
import numpy as np
import cv2

# We point OpenCV's CascadeClassifier function to where our 
# classifier (XML file format) is stored
face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

# Load our image then convert it to grayscale
image = cv2.imread('./your/image/path.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

cv2.imshow('Original image', image)

# Our classifier returns the ROI of the detected face as a tuple
# It stores the top left coordinate and the bottom right coordiantes
faces = face_classifier.detectMultiScale(gray, 1.3, 5)

# When no faces detected, face_classifier returns and empty tuple
if faces is ():
    print("No faces found")

# We iterate through our faces array and draw a rectangle
# over each face in faces
for (x, y, w, h) in faces:
    x = x - 25 # Padding trick to take the whole face not just Haarcascades points
    y = y - 40 # Same here...
    cv2.rectangle(image, (x, y), (x + w + 50, y + h + 70), (27, 200, 10), 2)
    cv2.imshow('Face Detection', image)
    cv2.waitKey(0)

cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

卡片

脸

链接到haarcascade_frontalface_default 文件


小智 5

更新到@Sanix 较暗的代码,

# Using cascade Classifiers
import numpy as np
import cv2

img = cv2.imread('link_to_your_image')
face_classifier = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')

scale_percent = 60 # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
  
# resize image
image = cv2.resize(img, dim, interpolation = cv2.INTER_AREA)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# face classifier
faces = face_classifier.detectMultiScale(gray, 1.3, 5)
# When no faces detected, face_classifier returns and empty tuple
if faces is ():
    print("No faces found")

# We iterate through our faces array and draw a rectangle
# over each face in faces
for (x, y, w, h) in faces:
    x = x - 25 # Padding trick to take the whole face not just Haarcascades points
    y = y - 40 # Same here...
    cv2.rectangle(image, (x, y), (x + w + 50, y + h + 70), (27, 200, 10), 2)
    cv2.imshow('Face Detection', image)
    cv2.waitKey(0)

cv2.destroyAllWindows()
# if you want to crop the face use below code
for (x, y, width, height) in faces:
    roi = image[y:y+height, x:x+width]
    cv2.imwrite("face.png", roi)
Run Code Online (Sandbox Code Playgroud)