python - OpenCV 从图像和变换中检索形状轮廓
问题描述
我正在尝试使用 OpenCV 和 python 检索图像的矩形部分(文档、护照照片或类似的东西)。axis = normalize_axis_index(axis, nd)
numpy.core._internal.AxisError: axis 1 is out of bounds for array of dimension 1
它有效,但并非在每个图像上都有效,并且在以下代码块上失败并出现错误:
for cnt in contours:
perimeter = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.03 * perimeter, True)
if (len(approx) == 4 and
cv2.isContourConvex(approx) and
maxAreaFound < cv2.contourArea(approx) < MAX_COUNTOUR_AREA):
maxAreaFound = cv2.contourArea(approx)
pageContour = approx
完整代码:
import numpy as np
import cv2
def resize(img, height=800):
""" Resize image to given height """
rat = height / img.shape[0]
return cv2.resize(img, (int(rat * img.shape[1]), height))
def fourCornersSort(pts):
diff = np.diff(pts, axis=1)
summ = pts.sum(axis=1)
return np.array(
[pts[np.argmin(summ)], pts[np.argmax(diff)], pts[np.argmax(summ)],
pts[np.argmin(diff)]])
def contourOffset(cnt, offset):
""" Offset contour, by 5px border """
# Matrix addition
cnt += offset
# if value < 0 => replace it by 0
cnt[cnt < 0] = 0
return cnt
image = cv2.cvtColor(cv2.imread("9.jpg"), cv2.COLOR_BGR2RGB)
img = cv2.cvtColor(resize(image), cv2.COLOR_BGR2GRAY)
img = cv2.bilateralFilter(img, 9, 75, 75)
img = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 115, 4)
img = cv2.medianBlur(img, 11)
img = cv2.copyMakeBorder(img, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=[0, 0, 0])
edges = cv2.Canny(img, 200, 250)
im2, contours, hierarchy = cv2.findContours(edges, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
height = edges.shape[0]
width = edges.shape[1]
MAX_COUNTOUR_AREA = (width - 10) * (height - 10)
maxAreaFound = MAX_COUNTOUR_AREA * 0.5
pageContour = np.array([[5, 5], [5, height-5], [width-5, height-5],
[width-5, 5]])
for cnt in contours:
perimeter = cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, 0.03 * perimeter, True)
if (len(approx) == 4 and
cv2.isContourConvex(approx) and
maxAreaFound < cv2.contourArea(approx) < MAX_COUNTOUR_AREA):
maxAreaFound = cv2.contourArea(approx)
pageContour = approx
pageContour = fourCornersSort(pageContour[:, 0])
pageContour = contourOffset(pageContour, (-5, -5))
sPoints = pageContour.dot(image.shape[0] / 800)
height = max(np.linalg.norm(sPoints[0] - sPoints[1]),
np.linalg.norm(sPoints[2] - sPoints[3]))
width = max(np.linalg.norm(sPoints[1] - sPoints[2]),
np.linalg.norm(sPoints[3] - sPoints[0]))
tPoints = np.array([[0, 0],
[0, height],
[width, height],
[width, 0]], np.float32)
if sPoints.dtype != np.float32:
sPoints = sPoints.astype(np.float32)
M = cv2.getPerspectiveTransform(sPoints, tPoints)
newImage = cv2.warpPerspective(image, M, (int(width), int(height)))
cv2.imwrite("resultImage.jpg", cv2.cvtColor(newImage, cv2.COLOR_BGR2RGB))
为什么会这样?
解决方案
import cv2
img = cv2.imread('img.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv, (40, 0, 80), (255, 255, 255)) # set to the color you want to detect
blur = cv2.blur(mask, (5, 5))
ret, thresh = cv2.threshold(blur, 50, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)
_, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnt = contours[0]
cnts = cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
cv2.imshow('blur', blur)
cv2.imshow('thresh', thresh)
cv2.imshow('cnts', cnts)
cv2.waitKey(0)
您只需保存带有或不带有图像的轮廓..
推荐阅读
- sas - 使用子集数据集在 SAS 中生成自定义表
- python - 具有多重共线性问题的 statsmodel 中的聚类标准误差
- xml - 在 xslt 2.0 中动态创建 xpath
- c++ - 顶部带有搜索框的组合框
- c++ - 如何从内存转储中解码 Lua 5.3 调用堆栈?
- android - 设置root模拟器android
- java - 尝试在 RSelenium 中下载缓存的图片
- deep-learning - 深度 Q 学习代理找到解决方案然后再次发散
- hybris - Spartacus 店面未在 hybris 1905 上加载
- elasticsearch - 在 Kibana 中使用脚本字段作为时间变量