我正在尝试检测身份证的轮廓,但是它永远无法正常工作; 我尝试了four_point_transform,boundingrect,boundries,active_contours,hough变换以及相同的结果,该轮廓用于仅扫描身份证。 id看起来像这样:here 代码是这样的:
from trans import four_point_transform
from skimage.filters import threshold_local
import numpy as np
import cv2
import imutils
def edgeDetection(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(image, (5, 5), 0)
edged = cv2.Canny(gray, 200,150 )
return edged
def detectrectarrondi(image,edged):
orig = image.copy()
gray = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
edged = cv2.Canny(gray, 50, 40)
orig_edged = edged.copy()
(_,contours, _) = cv2.findContours(orig_edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
contours = sorted(contours, key=cv2.contourArea, reverse=True)
for contour in contours:
c = max(contours, key = cv2.contourArea)
(x,y,w,h) = cv2.boundingRect(c)
screen = cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)
return screen
def scan(screen,image):
ratio = image.shape[0] / 500.0
warped = four_point_transform(image, screen.reshape(4, 2) * ratio)
warped= cv2.cvtColor(warped, cv2.COLOR_BGR2GRAY)
T = threshold_local(warped, 11, offset = 10, method = "gaussian")
warped = (warped > T).astype("uint8") * 255
return warped
答案 0 :(得分:0)
由于我没有50个声誉,因此我无法发表评论,因此,我将在此处提供一些步骤: 1 /使用cvtColor将图像转换为灰度。
2 /应用高斯模糊以降低噪声。
3 /应用Canny边缘检测器,您需要使用较高和较低的阈值才能获得最佳结果
4 /此步骤不是必需的,但可能会有所帮助,请使用MORPH_CLOSE参数应用形态学操作来闭合不完整的轮廓。
5 /使用findContours查找轮廓
6 /在找到的轮廓中循环并绘制具有最大面积的粘合矩形。
希望对您有所帮助,告诉我是否要查看一些代码。
编辑:
Imgproc.cvtColor(origMat, mGray, Imgproc.COLOR_BGR2GRAY);
Imgproc.GaussianBlur(mGray, mGray, new Size(5, 5), 5);
Imgproc.Canny(mGray, mGray, 30, 80, 3, false);
Mat kernell = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(9,9));
Imgproc.morphologyEx(mGray, mGray, Imgproc.MORPH_CLOSE, kernell);
Imgproc.dilate(mGray, mGray, Imgproc.getStructuringElement(Imgproc.MORPH_CROSS, new Size(3, 3)));
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
Mat hierarchy = new Mat();
Imgproc.findContours(mGray, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
MatOfPoint2f approxCurve = new MatOfPoint2f();
double largest_area=0;
int largest_contour_index=0;
Rect rect = new Rect();
for (int idx = 0; idx < contours.size() ; idx++) {
double a = Imgproc.contourArea(contours.get(idx)); //Find the area of contour
if (a > largest_area) {
largest_area = a;
largest_contour_index = idx;
rect = Imgproc.boundingRect(contours.get(idx));
}
}
Imgproc.rectangle(origMat, rect.tl(), rect.br(), new Scalar(0, 255, 0));
return origMat;
您可以看看这个好答案,以使用图像的中值自动设置Canny阈值