Python& OpenCV:第二大对象

时间:2014-08-28 15:37:54

标签: python opencv

我正在开发一个python脚本来隔离图像中颜色匹配的最大和第二大对象。我设法获得了最大的物体,在它周围画一个轮廓并画一个盒子。但是,我很难找到找到第二大对象的解决方案。我希望单独检测第二大对象。

import numpy as np
import cv2

font = cv2.FONT_HERSHEY_SIMPLEX
lineType = cv2.LINE_AA

im = cv2.imread('Photos/test.jpg')
im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

ball_ycrcb_mint = np.array([0, 90, 100],np.uint8)
ball_ycrcb_maxt = np.array([25, 255, 255],np.uint8)
ball_ycrcb = cv2.inRange(im_ycrcb, ball_ycrcb_mint, ball_ycrcb_maxt)
#cv2.imwrite('Photos/output2.jpg', ball_ycrcb) # Second image
areaArray = []
count = 1

_, contours, _ = cv2.findContours(ball_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    areaArray.append(area)
    areaLargest = np.argmax(areaArray)
    areaLargestMax = max(areaArray)
    areaLargestCnt = contours[areaLargest]
    x, y, w, h = cv2.boundingRect(areaLargestCnt)   
    if area == areaLargestMax and area > 10000:
        cv2.drawContours(im, contours, i, (255, 0, 0), 2)
        cv2.rectangle(im, (x, y), (x+w, y+h), (0,255,0), 2)
cv2.imwrite('Photos/output3.jpg', im)

我使用以下图片进行测试:Image of balls

感谢任何帮助!

3 个答案:

答案 0 :(得分:5)

您可以使用sorted(contours, key=cv2.contourArea, reverse=True)按区域为您提供下降轮廓列表。

答案 1 :(得分:3)

首先,首先创建轮廓和轮廓区域数组更简单,然后找到第n个最大轮廓。

import numpy as np
import cv2
im = cv2.imread('Photos/test.jpg')
im_ycrcb = cv2.cvtColor(im, cv2.COLOR_BGR2HSV)

ball_ycrcb_mint = np.array([0, 90, 100],np.uint8)
ball_ycrcb_maxt = np.array([25, 255, 255],np.uint8)
ball_ycrcb = cv2.inRange(im_ycrcb, ball_ycrcb_mint, ball_ycrcb_maxt)
#cv2.imwrite('Photos/output2.jpg', ball_ycrcb) # Second image
areaArray = []
count = 1

contours, _ = cv2.findContours(ball_ycrcb, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for i, c in enumerate(contours):
    area = cv2.contourArea(c)
    areaArray.append(area)

#first sort the array by area
sorteddata = sorted(zip(areaArray, contours), key=lambda x: x[0], reverse=True)

#find the nth largest contour [n-1][1], in this case 2
secondlargestcontour = sorteddata[1][1]

#draw it
x, y, w, h = cv2.boundingRect(secondlargestcontour)
cv2.drawContours(im, secondlargestcontour, -1, (255, 0, 0), 2)
cv2.rectangle(im, (x, y), (x+w, y+h), (0,255,0), 2)
cv2.imwrite('Photos/output3.jpg', im)

这应该基本上做你想要的。我删除了在我的opencv版本上导致崩溃的不必要的代码。

答案 2 :(得分:1)

image, cnts, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) 

cnt = sorted(cnts, key=cv2.contourArea)

cnt为您提供一个有序的轮廓列表,按顺序递增w.r.t区域。

您可以通过索引找到轮廓区域:

area = cv2.contourArea(cnt[index])

索引可以是1,2,3 ......,len(cnts)

用于访问最大区域轮廓:

cnt[reverse_index]

将reverse_index设为-1,它给出了最大的区域轮廓。

对于第二大,将reverse_index设为-2,依此类推。