OpenCV, cv2.approxPolyDP() 在闭合轮廓上绘制双线
OpenCV, cv2.approxPolyDP() Draws double lines on closed contour
我想用这个蒙版创建一些多边形:
图片 1 - 面具
所以我用 openCV findcontours() 创建了这些轮廓:
图片 2 - 轮廓
创建多边形时我得到这些多边形:
图片 3 - 多边形
如您所见,一些多边形是使用双线绘制的。我该如何防止这种情况?
查看我的代码:
import glob
from PIL import Image
import cv2
import numpy as np
# Let's load
image = cv2.imread(path + "BigOneEnhanced.tif")
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Find Canny edges
edged = cv2.Canny(gray, 30, 200)
# Finding Contours
contours, hierarchy = cv2.findContours(edged,
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
canvas = np.zeros(image.shape, np.uint8)
# creating polygons from contours
polygonelist = []
for cnt in contours:
# define contour approx
perimeter = cv2.arcLength(cnt,True)
epsilon = 0.005*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
polygonelist.append(approx)
cv2.drawContours(canvas, polygonelist, -1, (255, 255, 255), 3)
imgB = Image.fromarray(canvas)
imgB.save(path + "TEST4.png")
问题来源是 Canny edges 检测:
应用边缘检测后,每个原始轮廓都会得到两个轮廓 - 一个在边缘外,一个在边缘内(以及其他奇怪的东西)。
您可以通过应用 findContours
而不使用 Canny
来解决它。
代码如下:
import glob
from PIL import Image
import cv2
import numpy as np
path = ''
# Let's load
#image = cv2.imread(path + "BigOneEnhanced.tif")
image = cv2.imread("BigOneEnhanced.png")
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply threshold (just in case gray is not binary image).
ret, thresh_gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Find Canny edges
#edged = cv2.Canny(gray, 30, 200)
# Finding Contours cv2.CHAIN_APPROX_TC89_L1
#contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours, hierarchy = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
canvas = np.zeros(image.shape, np.uint8)
# creating polygons from contours
polygonelist = []
for cnt in contours:
# define contour approx
perimeter = cv2.arcLength(cnt, True)
epsilon = 0.005*perimeter #0.005*cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
polygonelist.append(approx)
cv2.drawContours(canvas, polygonelist, -1, (255, 255, 255), 3)
imgB = Image.fromarray(canvas)
imgB.save(path + "TEST4.png")
结果:
opencv findcontour 推荐结合cv2.canny 根据opencv-tutorials,使用阈值图像代替它会降低准确性。也许试试形态
我想用这个蒙版创建一些多边形:
图片 1 - 面具
所以我用 openCV findcontours() 创建了这些轮廓:
图片 2 - 轮廓
创建多边形时我得到这些多边形:
图片 3 - 多边形
如您所见,一些多边形是使用双线绘制的。我该如何防止这种情况?
查看我的代码:
import glob
from PIL import Image
import cv2
import numpy as np
# Let's load
image = cv2.imread(path + "BigOneEnhanced.tif")
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Find Canny edges
edged = cv2.Canny(gray, 30, 200)
# Finding Contours
contours, hierarchy = cv2.findContours(edged,
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_L1)
canvas = np.zeros(image.shape, np.uint8)
# creating polygons from contours
polygonelist = []
for cnt in contours:
# define contour approx
perimeter = cv2.arcLength(cnt,True)
epsilon = 0.005*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
polygonelist.append(approx)
cv2.drawContours(canvas, polygonelist, -1, (255, 255, 255), 3)
imgB = Image.fromarray(canvas)
imgB.save(path + "TEST4.png")
问题来源是 Canny edges 检测:
应用边缘检测后,每个原始轮廓都会得到两个轮廓 - 一个在边缘外,一个在边缘内(以及其他奇怪的东西)。
您可以通过应用 findContours
而不使用 Canny
来解决它。
代码如下:
import glob
from PIL import Image
import cv2
import numpy as np
path = ''
# Let's load
#image = cv2.imread(path + "BigOneEnhanced.tif")
image = cv2.imread("BigOneEnhanced.png")
# Grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Apply threshold (just in case gray is not binary image).
ret, thresh_gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Find Canny edges
#edged = cv2.Canny(gray, 30, 200)
# Finding Contours cv2.CHAIN_APPROX_TC89_L1
#contours, hierarchy = cv2.findContours(edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
contours, hierarchy = cv2.findContours(thresh_gray, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
canvas = np.zeros(image.shape, np.uint8)
# creating polygons from contours
polygonelist = []
for cnt in contours:
# define contour approx
perimeter = cv2.arcLength(cnt, True)
epsilon = 0.005*perimeter #0.005*cv2.arcLength(cnt, True)
approx = cv2.approxPolyDP(cnt, epsilon, True)
polygonelist.append(approx)
cv2.drawContours(canvas, polygonelist, -1, (255, 255, 255), 3)
imgB = Image.fromarray(canvas)
imgB.save(path + "TEST4.png")
结果:
opencv findcontour 推荐结合cv2.canny 根据opencv-tutorials,使用阈值图像代替它会降低准确性。也许试试形态