是否存在类似于OpenCV findContours的功能,该功能可检测曲线并用样条线替换点? [英] Is there a function similar to OpenCV findContours that detects curves and replaces points with a spline?
问题描述
我正在尝试拍摄以下图像,描绘出白色形状,然后将生成的路径导出为pdf.我的问题是,findContours似乎只能沿着形状的边缘找到点.是否存在类似于findContours的解决方案,该解决方案可以检测形状中的曲线,并在有曲线的地方用样条线替换其点?如果我使用scipy.interpolate,它将忽略直线并将整个轮廓变成一个大的弯曲形状,这也不是一件好事.我需要可以同时做这两种事情的东西.
I am trying to take the below image, trace the white shape, and export the resulting path to pdf. The problem I have is that findContours seeming only finds points along the edge of the shape. Is there a solution out there, similar to findContours, that detects curves in a shape and replaces its points with a spline wherever there is a curve? If I use scipy.interpolate it ignores straight lines and turns the entire contour into one big curved shape, which is no good either. I need something that does both things.
import numpy as np
import cv2
from scipy.interpolate import splprep, splev
from pyx import *
import matplotlib.pyplot as plt
#read in image file
original = cv2.imread('test.jpg')
#blur the image to smooth edges
im = cv2.medianBlur(original,5)
#threshold the image
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,170,255,cv2.THRESH_BINARY)
#findContours
im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_\
APPROX_SIMPLE)
#drawContours
cv2.drawContours(original, [approx], -1, (0,255,0), 3)
cv2.imshow("Imageee", original)
cv2.waitKey(0)
推荐答案
除了使用带有标志cv2.CHAIN_APPROX_SIMPLE
的cv2.findContours
逼近轮廓外,我们可以手动进行.
Except using cv2.findContours
with flag cv2.CHAIN_APPROX_SIMPLE
to approx the contours, we can do it manually.
- 使用带有标志
cv2.CHAIN_APPROX_NONE
的cv2.findContours
查找轮廓. - 使用
cv2.arcLength
计算轮廓长度. - 使用
cv2.approxPoolyDP
和epsilon = eps * arclen
手动逼近轮廓.
- use
cv2.findContours
with flagcv2.CHAIN_APPROX_NONE
to find contours. - use
cv2.arcLength
to calculate the contour length. - use
cv2.approxPoolyDP
to approx the contour manually withepsilon = eps * arclen
.
这是eps=0.005
时的结果之一:
Here is one of the results when eps=0.005
:
更多结果:
#!/usr/bin/python3
# 2018.01.04 13:01:24 CST
# 2018.01.04 14:42:58 CST
import cv2
import numpy as np
import os
img = cv2.imread("test.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,threshed = cv2.threshold(gray,170,255,cv2.THRESH_BINARY)
# find contours without approx
cnts = cv2.findContours(threshed,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)[-2]
# get the max-area contour
cnt = sorted(cnts, key=cv2.contourArea)[-1]
# calc arclentgh
arclen = cv2.arcLength(cnt, True)
# do approx
eps = 0.0005
epsilon = arclen * eps
approx = cv2.approxPolyDP(cnt, epsilon, True)
# draw the result
canvas = img.copy()
for pt in approx:
cv2.circle(canvas, (pt[0][0], pt[0][1]), 7, (0,255,0), -1)
cv2.drawContours(canvas, [approx], -1, (0,0,255), 2, cv2.LINE_AA)
# save
cv2.imwrite("result.png", canvas)
这篇关于是否存在类似于OpenCV findContours的功能,该功能可检测曲线并用样条线替换点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!