身份证并包装身份证明

时间:2018-12-06 11:44:35

标签: python opencv image-processing computer-vision

我有以下ID,并且我想检测它并变形。 主要问题

  1. 该方法不适用于所有图像数据集,我找不到最佳轮廓,请提出更好的预处理方法?

  2. 我得到两个轮廓,一个用于背景,一个用于ID,我只想过滤其他东西并得到ID。

enter image description here

结果:

enter image description here

document_img = cv2.imread(dataset + imfile)
document_img = imutils.resize(document_img, width=460)

src = imutils.resize(document_img, width=460)
gray = cv2.cvtColor(document_img,cv2.COLOR_BGR2GRAY)

document_type = document_types.ID_front.value
equ = cv2.medianBlur(gray, 1)

fil = cv2.bilateralFilter(equ, 9, 11, 17)

thresh = cv2.adaptiveThreshold(fil, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, \
                           cv2.THRESH_BINARY, 11, 2)

cv2.imshow('canny', thresh)
cv2.waitKey()
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(contours, key=cv2.contourArea, reverse=True)[:5]
screenCnt = None
# loop over our contours
for c in cnts:
    # approximate the contour
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.015 * peri, True)

    # if our approximated contour has four points, then
    # we can assume that we have found our screen
    if len(approx) == 4:
        screenCnt = approx
        break

cv2.drawContours(src, cnts, -1, (0, 255, 0), 3)
cv2.imshow('contours', src)
cv2.waitKey()

# cv2.drawContours(im, appr, -1, (0,255,0), 3)
points_list = [[i[0][0], i[0][1]] for i in screenCnt]

left = sorted(points_list, key=lambda p: p[0])[0:2]
right = sorted(points_list, key=lambda p: p[0])[2:4]

print("l " + str(left))
print("r " + str(right))

lu = sorted(left, key=lambda p: p[1])[0]
ld = sorted(left, key=lambda p: p[1])[1]

ru = sorted(right, key=lambda p: p[1])[0]
rd = sorted(right, key=lambda p: p[1])[1]

print("lu " + str(lu))
print("ld " + str(ld))
print("ru " + str(ru))
print("rd " + str(rd))

lu_ = [(lu[0] + ld[0]) / 2, (lu[1] + ru[1]) / 2]
ld_ = [(lu[0] + ld[0]) / 2, (ld[1] + rd[1]) / 2]
ru_ = [(ru[0] + rd[0]) / 2, (lu[1] + ru[1]) / 2]
rd_ = [(ru[0] + rd[0]) / 2, (ld[1] + rd[1]) / 2]

print("lu_ " + str(lu_))
print("ld_ " + str(ld_))
print("ru_ " + str(ru_))
print("rd_ " + str(rd_))

src_pts = np.float32(np.array([lu, ru, rd, ld]))
dst_pts = np.float32(np.array([lu_, ru_, rd_, ld_]))

h, w, b = src.shape
H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

print("H" + str(H))

imw = cv2.warpPerspective(src, H, (w, h))
im =  imw[int(lu_[1]):int(rd_[1]), int(lu_[0]):int(rd_[0])]  # cropping image

cv2.imshow('ff', im)
cv2.waitKey()

2 个答案:

答案 0 :(得分:1)

您可以使用霍夫变换来检测i.d的矩形。 您首先需要使用一些边缘检测运算符(我看到您已经在使用Canny)。然后对边缘图像上的线运行霍夫变换。然后只需绘制变换已找到的最上面的线。您得到了围绕i.d的线条,很容易获得其中包含的矩形区域,并随心所欲地进行操作。

我下载了您的图片,并习惯于遵循以下代码来获得以下结果(仅用它播放了几分钟,我确定可以更好地调整参数):

 import cv2
 import numpy as np

 img = cv2.imread(folder + 'image.jpg')
 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 kernel = np.ones((5,5),np.float32)/25
 gray = cv2.filter2D(gray,-1,kernel)
 edges = cv2.Canny(gray,400,600,apertureSize = 5)
 cv2.imshow('image',edges)
 cv2.waitKey(0)

 lines = cv2.HoughLines(edges,1,np.pi/180,15)
 for i in range(8):
      for rho,theta in lines[i]:
           a = np.cos(theta)
           b = np.sin(theta)
           x0 = a*rho
           y0 = b*rho
           x1 = int(x0 + 1000*(-b))
           y1 = int(y0 + 1000*(a))
           x2 = int(x0 - 1000*(-b))
           y2 = int(y0 - 1000*(a))
      cv2.line(img,(x1,y1),(x2,y2),(0,0,255),2)

 cv2.imshow('image',img)
 cv2.waitKey(0)

边缘图像: enter image description here

霍夫变换的结果: enter image description here

答案 1 :(得分:0)

您还可以使用预先训练的模型来识别图像中的身份证,然后对其进行裁剪!

enter image description here

检查此仓库,其中有贡献者: https://github.com/mesutpiskin/id-card-detector

相关问题