有没有一种方法可以使用cv2.approxPolyDP来近似打开曲线?

时间:2018-10-12 15:08:06

标签: python python-3.x opencv opencv3.2

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

在闭合曲线的情况下,

OpenCV 3.4中的cv2.approxPolyDP取得了不错的结果。

原点闭合曲线: Origin close curve 近似闭合曲线: Approximated close curve

但是在开放曲线的情况下,cv2.approxPolyDP无法达到预期的效果。

原点开放曲线: Origin open curve 近似开放曲线: Approximated open curve

我想要的结果应该是一串线段,而不是闭合的多边形,像这样(此图片是由Photoshop创建的,而不是Python程序创建的): enter image description here

是否可以使用cv2.approxPolyDP来近似打开曲线?

我的Python程序如下:

<!doctype html>
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link rel="stylesheet" href="photo_filter.css" type="text/css">
</head>

<body>
  <div class="search">Search:
    <input type="text" id="searchBar">
  </div>
  <div id="results">
    <p>some text is here</p>
    <p>other kinds</p>
    <p>even more</p>
  </div>
</body>

</html>

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

Close curve photo Open curve photo

3 个答案:

答案 0 :(得分:1)

根据docs for approxPolyDP(),您只需使用closed=False

  

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

所以您应该可以:

approx = cv2.approxPolyDP(contour, epsilon, closed=False)

答案 1 :(得分: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

答案 2 :(得分:0)

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

输入(从屏幕快照标题栏剪切掉)

enter image description here

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)

enter image description here