我之前发布了here
我已经看过this post
尽管社区提供了很好的信息,但我无法使用cv2.findContours()平滑地追踪图像。在我上一篇文章中,我询问了生成样条曲线以平滑地追踪曲线,现在我的重点是获得物体的平滑轨迹,无论轮廓生成多少个点。我一直得到锯齿状边缘的结果:
我想要的输出与此类似,我在Adobe 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)
答案 0 :(得分:2)
我可以使用此代码向您展示该效果。
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()
答案 1 :(得分:1)
这是我的结果。绿色轮廓是原始轮廓,红色轮廓近似,灰色点是近似点。
# 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?