提问人:chase 提问时间:6/11/2016 最后编辑:Communitychase 更新时间:12/19/2019 访问量:507
从曲率上限和下限阈值进行点/特征检测 - 曲线四边形形状检测算法
Point/Feature detection from upper and lower threshold of curvature - Curvilinear Quadrilateral Shape Detection algorithm
问:
是否可以从沿粗曲率线的一组点创建多边形,以便在两个曲率值之间选择点?
我正在尝试使用 python 的 opencv 包 () 从给定图像中检索近似的曲线四边形形状。cv2
例如: 给定边缘检测后的图像,如下所示:
在使用 cv2.findContours 找到轮廓后,如下所示:
(旁注:如果这实际上能给出一个方形的形状而不是绕线走,那就太好了 - 还需要一种算法来缩小这张图像右侧形状的间隙。扩张/侵蚀可能会起作用,但可能会消除某些可能需要保留的特征。)
之后,我们可以在轮廓上使用 polyDPApprox,如下所示:
然而,这与曲率无关 - 它只是通过使用与线的最大偏差来近似。如果我们想省略一些细节(这个想法是这些细节可能来自错误)并保留曲率较小的点(宽形状) - 我们可以使用一个函数来提供这样的东西吗?
(红色填充仅表示形状将闭合为曲线四边形。)
相关问题:在 OpenCV 中是否可以将局部曲率绘制为表示对象“尖度”的热图?
以下是用于分析输入图像的函数,以防有人需要它:
# input binary image
def find_feature_points(img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.namedWindow('img', WINDOW_NORMAL)
cv2.imshow("img", gray)
cv2.waitKey(0)
contours, hierarchy = cv2.findContours(gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Draw contours to image
print contours
copy = img.copy()
# img - Image.
# pts - Array of polygonal curves.
# npts - Array of polygon vertex counters.
# ncontours - Number of curves.
# isClosed - Flag indicating whether the drawn polylines are closed or not. If they are closed, the function draws a line from the last vertex of each curve to its first vertex.
# color - Polyline color.
# thickness - Thickness of the polyline edges.
# lineType - Type of the line segments. See the line() description.
# shift - Number of fractional bits in the vertex coordinates.
cv2.polylines(img=copy, pts=contours, isClosed=1, color=(0,0,255), thickness=3)
cv2.namedWindow('contour', WINDOW_NORMAL)
cv2.imshow("contour", copy)
cv2.waitKey(0)
# Find approximation to contours
approx_conts = []
for c in contours:
curve = c
epsilon = 200
closed = True
approx_conts.append(cv2.approxPolyDP(curve, epsilon, closed))
# draw them
cv2.drawContours(img, approx_conts, -1, (0, 255, 0), 3)
cv2.namedWindow('approx', WINDOW_NORMAL)
cv2.imshow("approx", img)
cv2.waitKey(0)
return
答:
0赞
nathancy
12/19/2019
#1
这是一个可能的解决方案。这个想法是:
- 获取二进制图像。加载图像、转换为灰度和 Otsu 的阈值
- 找到凸包。确定对象的周围周长并将其绘制到蒙版上
- 执行形态学操作。使用变形填充小孔以连接轮廓
- 绘制轮廓。找到蒙版的外部轮廓并绘制到图像上
输入图像结果->
法典
import cv2
import numpy as np
# Load image, convert to grayscale, threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
# Find convex hull and draw onto a mask
mask = np.zeros(image.shape, dtype=np.uint8)
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnt = cnts[0]
hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
cv2.line(mask,start,end,[255,255,255],3)
# Morph close to fill small holes
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=2)
# Draw outline around input image
close = cv2.cvtColor(close, cv2.COLOR_BGR2GRAY)
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cv2.drawContours(image,cnts,0,(36,255,12),1)
cv2.imshow('image', image)
cv2.waitKey()
评论