python - 身份证轮廓
问题描述
我正在尝试检测身份证的轮廓,但它从来没有用过;我尝试了four_point_transform、boundingrect、boundries、active_contours、hough 变换以及相同的结果,用于扫描身份证的轮廓。id 看起来像这样:这里 是代码的样子:
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
解决方案
因为我没有 50 名声望,所以我无法写评论,我将在此处为您提供一些步骤: 1/ 使用 cvtColor 将您的图像转换为灰度。
2/ 应用 GaussianBlur 来减少噪音。
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 阈值
推荐阅读
- android - GridView 中缺少图像
- ruby-on-rails - 具有多个属性的 Searchkick 自动完成功能
- java - 将数据从片段发送到另一个活动时不调用 OnActivityResult
- selenium - selenium 控制浏览器的功能在哪里?
- sql-server - 如何使用 ASP.NET Core 读取 SQL Server 文件流
- python - Pandas - 根据索引结果返回 pandas 中的相邻列
- javascript - 努力使用 POSTJavascript
- c++ - 如何使用数组的值初始化 unordered_map
- php - onchange 事件不起作用。选择来自控制器的下拉菜单
- kde - Autokey 不会在 Fedora 29 上启动