1

我想用线段链来近似平滑线。

OpenCV 3.4中的cv2.approxPolyDP在闭合曲线的情况下取得了不错的效果。

原点闭合曲线: 原点闭合曲线 近似闭合曲线: 近似闭合曲线

但是在开曲线的情况下,cv2.approxPolyDP并没有达到预期的效果。

原点开放曲线: 原点开放曲线 近似开放曲线: 近似开放曲线

我想要的结果应该是一条线段链,而不是一个封闭的多边形,像这样(这张图片是由Photoshop而不是Python程序创建的): 在此处输入图像描述

有没有办法使用 cv2.approxPolyDP 来近似开放曲线?

我的 Python 程序如下:

import cv2

img = cv2.imread('1.jpg')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

cv2.imshow("gray", gray)
cv2.waitKey(0)

_, binary = cv2.threshold(gray, 10, 255, cv2.THRESH_BINARY)

# cv2.imshow("binary", binary)
# cv2.waitKey(0)

_, contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:
    epsilon = 0.009 * cv2.arcLength(contour, True)
    approx = cv2.approxPolyDP(contour, epsilon, closed=True)
    cv2.drawContours(img, [approx], -1, (0, 255, 255), 1)

cv2.imshow("approx", img)
cv2.waitKey(0)

cv2.destroyAllWindows()

我的程序中使用的原始照片如下。

关闭曲线照片 打开曲线照片

4

3 回答 3

1

根据文档approxPolyDP(),您可以简单地使用closed=False

closed - 如果为真,则近似曲线是闭合的(它的第一个和最后一个顶点是连接的)。否则,它不会关闭。

所以你应该能够做到:

approx = cv2.approxPolyDP(contour, epsilon, closed=False)
于 2018-10-12T22:28:38.493 回答
1

这是使用 cv2.approxPolyDP 在 Python/OpenCV 中执行此操作的方法

输入(裁剪屏幕快照标题栏)

在此处输入图像描述

import numpy as np
import cv2

# read input
img = cv2.imread('curve.png')
hh, ww = img.shape[:2]

# convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# threshold
thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)[1]

# get points
points = np.column_stack(np.where(thresh.transpose() != 0))

# list points
for pt in points:
    ptx = pt[0]
    pty = pt[1]
    print(ptx,pty)

# approximate polygon
poly = cv2.approxPolyDP(points, 0.02 * ww, False)

# list polygon points
for p in poly:
    px = p[0]
    py = p[0]
    print(px,py)

# draw polygon on copy of input
result = img.copy()
cv2.polylines(result, [poly], False, (0,0,255), 1)

# save results
cv2.imwrite('curve_polygon.png', result)

cv2.imshow("thresh", thresh)
cv2.imshow("result", result)
cv2.waitKey(0)

在此处输入图像描述

于 2020-09-22T21:13:23.997 回答
0

最后还是没找到可以直接在OpenCV中使用的方法。但我找到了一种算法(名为 Ramer–Douglas–Peucker 算法),只需一点代码即可逼近曲线。

https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm

https://www.sciencedirect.com/science/article/abs/pii/0167865594900027

于 2020-09-22T18:22:02.027 回答