【问题标题】:How to get rid of random, jagged edges with OpenCV findContours()?如何使用 OpenCV findContours() 去除随机的锯齿状边缘?
【发布时间】:2018-01-04 03:19:00
【问题描述】:

我之前发过here

我见过this post

尽管社区提供了大量信息,但我无法使用 cv2.findContours() 平滑地跟踪图像。在我之前的帖子中,我询问了如何生成样条曲线以平滑地跟踪曲线,但我现在的重点是获得对象的平滑跟踪,而不管为轮廓生成了多少点。我一直得到锯齿状边缘的结果:

我想要的输出与我在 Adob​​e Illustrator 中手动创建的类似:

我已经对模糊和阈值进行了广泛的实验,但无法获得平滑的轮廓。我正在运行 openCV 3.3.0 版。

import numpy as np
import cv2
import math
from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

print(cv2.__version__)

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

# orient the image properly                                                      
# grab the dimensions of the image and calculate the center                     
# of the image                                                                  
(h, w) = im.shape[:2]
center = (w / 2, h / 2)

# rotate the image 180 degrees                                               
M = cv2.getRotationMatrix2D(center, 180, 1.0)
rotated = cv2.warpAffine(im, M, (w, h))

# flip the image across                                                          
flippedColor = cv2.flip(rotated, 1) #for testing                                
imgray = cv2.cvtColor(rotated, cv2.COLOR_BGR2GRAY)
flipped = cv2.flip(imgray, 1)

(thresh, binRed) = cv2.threshold(flipped, 180, 255, cv2.THRESH_BINARY)

_, Rcontours, hier_r = cv2.findContours(binRed,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
r_areas = [cv2.contourArea(c) for c in Rcontours]
max_rarea = np.argmax(r_areas)
CntExternalMask = np.ones(binRed.shape[:2], dtype="uint8") * 255

contour= Rcontours[max_rarea]
cv2.drawContours(flippedColor,[contour],-1,(255,0,0),1)

【问题讨论】:

  • 我也有同样的问题。希望得到解决....
  • 请显示您获得的结果和预期的结果。请记住,一般来说,重新发布相同的问题非常糟糕

标签: python opencv


【解决方案1】:

我可以使用此代码向您展示该效果。

import cv2

img = cv2.imread(r'E:/test_opencv/images/0ub4h.jpg')
imgray = cv2.cvtColor( img, cv2.COLOR_BGR2GRAY )
ret, thresh = cv2.threshold( imgray, 220, 255, cv2.THRESH_BINARY )
cv2.imshow('1',cv2.resize(thresh,(600,400)))
_, countours, hierarchy = cv2.findContours( thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE )
cnt = sorted(countours, key=cv2.contourArea)[-1]
epsilon = 0.1 * cv2.arcLength( countours[0], True )
approx = cv2.approxPolyDP( cnt, epsilon, True )
cv2.drawContours( img, [approx],-1, (0, 255, 0), 3 )
cv2.imshow( "Contour", cv2.resize(img,(600,400)) )
cv2.imwrite(r'E:/test.jpg',img)
cv2.waitKey( 0 )
cv2.destroyAllWindows()

【讨论】:

  • 绿线还是很锯齿的
  • 修改一下,可以吗?
【解决方案2】:

这是我的结果。绿色轮廓为原始轮廓,红色轮廓为近似值,灰色点为近似点。


# find contours without approx
cnts = cv2.findContours(threshed,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)[-2]

# get the max-area contour
cnt = sorted(cnts, key=cv2.contourArea)[-1]

# calc arclentgh
arclen = cv2.arcLength(cnt, True)

# approx the contour
epsilon = arclen * 0.001
epsilon = arclen * 0.0001
approx = cv2.approxPolyDP(cnt, epsilon, True)

cv2.drawContour(img, [approx], -1, (0,0,255), 1)

cv2.imwrite("res.png", img)

更多详情参考我的另一个回答:Is there a function similar to OpenCV findContours that detects curves and replaces points with a spline?

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-27
  • 1970-01-01
  • 2019-04-30
  • 2019-07-22
相关资源
最近更新 更多