获取Opencv Python内的面积?

获取Opencv Python内的面积?,python,opencv,image-processing,opencv-contour,Python,Opencv,Image Processing,Opencv Contour,我使用自适应阈值技术创建了一幅如下所示的图片: 我使用的代码是: image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0) 然后,我使用此代码获得轮廓: cnt = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0] 我的目标是使用外部轮廓内的所有像素生成遮

我使用自适应阈值技术创建了一幅如下所示的图片:

我使用的代码是:

image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)
然后,我使用此代码获得轮廓:

cnt = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
我的目标是使用外部轮廓内的所有像素生成遮罩,因此我希望填充对象内的所有像素,使其为白色。我该怎么做

我已经尝试了下面的代码来创建一个遮罩,但是生成的遮罩似乎与应用自适应阈值后的图像没有什么不同

mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)

你所说的几乎是正确的。如果查看阈值图像,它不起作用的原因是因为鞋对象在图像中有间隙。具体来说,您所追求的是,您希望鞋子的周长是所有连接的。如果发生这种情况,那么如果提取最外部的轮廓(代码就是这样做的),那么应该只有一个轮廓表示对象的外部周长。一旦你填充了轮廓,那么你的鞋子应该是完全坚固的

由于鞋的周长不完整且不完整,因此会导致断开的白色区域。如果使用
findContours
查找所有轮廓,它将只查找每个白色形状的轮廓,而不是最外层的周长。因此,如果您尝试使用
findContours
,它将提供与原始图像相同的结果,因为您只需找到图像中每个白色区域的周长,然后用
findContours
填充这些区域


您需要做的是确保图像完全关闭。我建议您将所有断开连接的区域一起关闭,然后在此新图像上运行
findContours
调用。具体来说,执行二元形态闭合。这样做的目的是,它需要相邻的断开连接的白色区域,并确保它们相互连接。使用形态闭合,或者使用类似7 x 7正方形的结构元素来闭合鞋子。这个结构元素可以看作是白色区域之间的最小分离,把它们看作是连接的。 因此,请执行以下操作:

import numpy as np
import cv2 
image = cv2.imread('...') # Load your image in here
# Your code to threshold
image = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 45, 0)    

# Perform morphology
se = np.ones((7,7), dtype='uint8')
image_close = cv2.morphologyEx(image, cv2.MORPH_CLOSE, se)

# Your code now applied to the closed image
cnt = cv2.findContours(image_close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
mask = np.zeros(image.shape[:2], np.uint8)
cv2.drawContours(mask, cnt, -1, 255, -1)

这段代码实质上是获取阈值图像,并对该图像应用形态学逼近。之后,我们找到图像的外部轮廓,并用白色填充它们。FWIW,我下载了你的阈值图像,并尝试在我自己。这就是我从你的形象中得到的:


一个简单的方法是关闭前景中的孔,形成一个带有和
cv2的单一轮廓。变形关闭

现在外部轮廓已填充,我们可以使用
cv2.findContours()
查找外部轮廓并使用白色填充所有像素


这太棒了,我真不敢相信这能奏效!在一个下午,我能够模糊图像的背景。Opencv非常酷。@emschorsch-谢谢你的投票:)是的,Opencv是一个很棒的平台。我每天都用它来工作。学习愉快@rayryeng我尝试了这段代码,但在最后一行,它抛出了以下错误
drawing.cpp:2380:error:(-215)npoints>0在函数cv::drawcourts
-我使用的是OpenCV 3.1和Python 2.7。有什么想法吗?@g491。这意味着没有轮廓可以画。哇,很好很简单!然而,今天(2020年)
thickness=cv2.FILLED
在您已经隔离了单个轮廓的情况下就不能这样工作了。在这种情况下,我们必须将该轮廓作为
…drawContours(…,[cnt]…)
传递,以使其再次成为数组。看见
import cv2

# Load in image, convert to grayscale, and threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]

# Close contour
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
close = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=1)

# Find outer contour and fill with white
cnts = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cv2.fillPoly(close, cnts, [255,255,255])

cv2.imshow('close', close)
cv2.waitKey()