如何使用OpenCV findConteurs()去除随机的锯齿状边缘?

2024-04-19 17:23:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我以前发过here

我看过this post

尽管社区提供了大量信息,但我无法使用cv2.findContours()顺利跟踪图像。在上一篇文章中,我询问了如何生成样条曲线以平滑地跟踪曲线,我现在的重点是获得对象的平滑跟踪,而不管为轮廓生成了多少个点。我总是得到边缘参差不齐的结果:

enter image description here

我想要的输出与此类似,这是我在Adobe Illustrator中手动创建的:

enter image description here

我做过大量的模糊和阈值化实验,但一直无法得到一个平滑的轮廓。我运行的是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)

Tags: thefromimageimportnpcv2曲线轮廓
2条回答

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

enter image description here


# 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?

enter image description here

我可以用这个代码向你展示这种效果。在

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()

enter image description here

相关问题 更多 >