在python 2.7中使用opencv 2.4查找最大连接组件
我正在使用opencv“2.4.9.1”用python 2.7.12编写代码。在python 2.7中使用opencv 2.4查找最大连接组件,python,opencv,Python,Opencv,我正在使用opencv“2.4.9.1”用python 2.7.12编写代码。 我有一个2d numpy数组,其中包含[0255]范围内的值。 我的目标是找到[x,y]范围内包含值的最大区域 我发现 解释得很好。 唯一的问题是——它是为opencv 3设计的 我可以尝试编写这种类型的函数 [伪代码] def get_component(x,y,list): append x,y to list visited[x][y]=1 if(x+1<m && visited
我有一个2d numpy数组,其中包含[0255]范围内的值。
我的目标是找到[x,y]范围内包含值的最大区域
我发现 解释得很好。 唯一的问题是——它是为opencv 3设计的 我可以尝试编写这种类型的函数
[伪代码]
def get_component(x,y,list):
append x,y to list
visited[x][y]=1
if(x+1<m && visited[x+1][y]==0)
get_component(x+1,y,list)
if(y+1<n && visited[x][y+1]==0)
get_component(x,y+1,list)
if(x+1<m)&&(y+1<n)&&visited[x+1][y+1]==0
get_component(x+1,y+1,list)
return
MAIN
biggest_component = NULL
biggest_component_size = 0
low = lowest_value_in_user_input_range
high = highest_value_in_user_input_range
matrix a = gray image of size mxn
matrix visited = all value '0' of size mxn
for x in range(m):
for y in range(n):
list=NULL
if(a[x][y]>=low) && (a[x][y]<=high) && visited[x][y]==1:
get_component(x,y,list)
if (list.size>biggest_component_size)
biggest_component = list
Get maximum x , maximum y , min x and min y from above list containing coordinates of every point of largest component to make rectangle R .
Mission accomplished !
def get_组件(x,y,list):
将x,y附加到列表
访问量[x][y]=1
如果(x+1很高兴看到我的答案被链接!事实上,connectedComponents swithstats()
甚至connectedComponents()
都是OpenCV 3+函数,所以你不能使用它们。相反,简单的方法是使用findContours()
您可以计算每个轮廓的矩()
,矩中包括轮廓的面积
重要提示:OpenCV函数findContours()
使用8路连接,而不是4路连接(即它还检查对角线连接,而不仅仅是上、下、左、右)。如果需要4路连接,则需要使用不同的方法。如果是这种情况,请告诉我,我可以更新
本着另一篇文章的精神,以下是一般方法:
使用感兴趣的阈值对图像进行二值化
运行cv2.findContours()
获取图像中每个不同组件的轮廓
对于每个轮廓,计算轮廓的cv2.moments()
,并保留最大面积轮廓(m00
,从moments()
返回的dict中是轮廓的面积)
如果需要,可以将轮廓保留为点列表,否则,如果希望将其作为遮罩,可以在新的空白图像上绘制轮廓
我今天缺乏创造力,所以你得到了我们的示例图像,因为你没有提供
import cv2
import numpy as np
img = cv2.imread('cameraman.png', cv2.IMREAD_GRAYSCALE)
现在,让我们进行二值化以获得一些分离的blob:
bin_img = cv2.inRange(img, 50, 80)
现在让我们找到轮廓线
contours = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# For OpenCV 3+ use:
# contours = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[1]
现在是主钻头;在轮廓上循环,找到最大的一个:
max_area = 0
max_contour_index = 0
for i, contour in enumerate(contours):
contour_area = cv2.moments(contour)['m00']
if contour_area > max_area:
max_area = contour_area
max_contour_index = i
因此,现在我们有了一个按区域划分的最大轮廓索引max\u contour\u index
,因此您可以通过执行轮廓[max\u contour\u index]
直接访问最大轮廓。当然,您可以按轮廓区域对轮廓列表进行排序,并获取第一个(或最后一个,取决于排序顺序)。若要制作一个组件的遮罩,可以使用
cv2.drawContours(new_blank_image, contours, max_contour_index, color=255, thickness=-1)
注-1将填充轮廓,而不是勾勒轮廓。以下是在原始图像上绘制轮廓的示例:
看起来不错
多功能一体:
def largest_component_mask(bin_img):
"""Finds the largest component in a binary image and returns the component as a mask."""
contours = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# should be [1] if OpenCV 3+
max_area = 0
max_contour_index = 0
for i, contour in enumerate(contours):
contour_area = cv2.moments(contour)['m00']
if contour_area > max_area:
max_area = contour_area
max_contour_index = i
labeled_img = np.zeros(bin_img.shape, dtype=np.uint8)
cv2.drawContours(labeled_img, contours, max_contour_index, color=255, thickness=-1)
return labeled_img
很高兴看到我的答案被链接!事实上,connectedComponents swithstats()
甚至connectedComponents()
都是OpenCV 3+函数,所以你不能使用它们。相反,简单的方法是使用findContours()
您可以计算每个轮廓的矩()
,矩中包括轮廓的面积
重要提示:OpenCV函数findContours()
使用8路连接,而不是4路连接(即它还检查对角线连接,而不仅仅是上、下、左、右)。如果需要4路连接,则需要使用不同的方法。如果是这种情况,请告诉我,我可以更新
本着另一篇文章的精神,以下是一般方法:
使用感兴趣的阈值对图像进行二值化
运行cv2.findContours()
获取图像中每个不同组件的轮廓
对于每个轮廓,计算轮廓的cv2.moments()
,并保留最大面积轮廓(m00
,从moments()
返回的dict中是轮廓的面积)
如果需要,可以将轮廓保留为点列表,否则,如果希望将其作为遮罩,可以在新的空白图像上绘制轮廓
我今天缺乏创造力,所以你得到了我们的示例图像,因为你没有提供
import cv2
import numpy as np
img = cv2.imread('cameraman.png', cv2.IMREAD_GRAYSCALE)
现在,让我们进行二值化以获得一些分离的blob:
bin_img = cv2.inRange(img, 50, 80)
现在让我们找到轮廓线
contours = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# For OpenCV 3+ use:
# contours = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[1]
现在是主钻头;在轮廓上循环,找到最大的一个:
max_area = 0
max_contour_index = 0
for i, contour in enumerate(contours):
contour_area = cv2.moments(contour)['m00']
if contour_area > max_area:
max_area = contour_area
max_contour_index = i
因此,现在我们有了一个按区域划分的最大轮廓索引max\u contour\u index
,因此您可以通过执行轮廓[max\u contour\u index]
直接访问最大轮廓。当然,您可以按轮廓区域对轮廓列表进行排序,并获取第一个(或最后一个,取决于排序顺序)。若要制作一个组件的遮罩,可以使用
cv2.drawContours(new_blank_image, contours, max_contour_index, color=255, thickness=-1)
注-1将填充轮廓,而不是勾勒轮廓。以下是在原始图像上绘制轮廓的示例:
看起来不错
多功能一体:
def largest_component_mask(bin_img):
"""Finds the largest component in a binary image and returns the component as a mask."""
contours = cv2.findContours(bin_img, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[0]
# should be [1] if OpenCV 3+
max_area = 0
max_contour_index = 0
for i, contour in enumerate(contours):
contour_area = cv2.moments(contour)['m00']
if contour_area > max_area:
max_area = contour_area
max_contour_index = i
labeled_img = np.zeros(bin_img.shape, dtype=np.uint8)
cv2.drawContours(labeled_img, contours, max_contour_index, color=255, thickness=-1)
return labeled_img
我将运行此程序并返回报告。顺便说一句,非常清晰。我可以在彩色图像上绘制此轮廓吗(实际上,灰度图像是从中派生出来的)?此外,我还打印了轮廓[max_contour_index]。形状并获得(924,1,2)。它实际上是924点的x,y坐标。我如何提取xmin,xmax,ymin,ymax,因为它将表示我感兴趣的左上和右下坐标的矩形遮罩?当然,但您需要一个3通道彩色图像来绘制。我在上面代码的第一行中以灰度形式读取图像,所以您希望读取彩色图像因此您可以使用drawContours()
和color=(b,g,r)
元组来表示您要绘制的颜色。@user1371666您也可以简单地使用boundingRect()
使用每个轮廓来查找轮廓的边界矩形。请参阅此处的更多信息:@user1371666我无法再现您的错误,可能是因为我使用的是OpenCV 3。当我在带有单个白点的图像上运行此操作时,它会按预期工作。在单点情况下,您能否编辑原始帖子以显示您的轮廓列表看起来像?另外请打印出所有其他的v