从视频中计算红色对象opencv python

时间:2017-06-25 19:19:41

标签: python opencv video

我正在尝试计算此视频中有多少红色条

tes1.mp4

这是我通过计算对象中心来计算对象的函数

def count(frame):
frame = imutils.resize(frame,640,480)
hsv=cv2.cvtColor(frame,cv2.COLOR_BGR2HSV)
mask=cv2.inRange(hsv, lower, upper)
contours,_ = cv2.findContours(mask.copy(), cv2.RETR_CCOMP,cv2.CHAIN_APPROX_TC89_L1)
center=[]

for i in range(len(contours)):
    c = max(contours, key=cv2.contourArea)
    ((x, y), radius) = cv2.minEnclosingCircle(c)
    M = cv2.moments(c)
    if M["m00"]==0:
        M["m00"]=0.6
    cx=int (M["m10"]/M["m00"])
    cy=int(M["m01"] / M["m00"])
    print "center",len(center)

    center.append((cx,cy))
    cv2.circle(frame, center[-1],3,(0,0,0),-1)

但问题是len(中心)出现超过300.任何人都可以帮助计算多少红条。任何解决方案都会有所帮助。

2 个答案:

答案 0 :(得分:1)

我是这样做的:首先,从红色通道中减去蓝色和绿色通道,找到“红色”像素。结果如下:

enter image description here

阈值在这方面表现得非常好,显然:

enter image description here

从这里我们可以找到轮廓:

enter image description here

计算它们,这就是条纹的数量。但是还有connectedComponents函数,它可以计算那些没有找到轮廓的函数。

import cv2
import numpy as np

#load a frame as int16 array to avoid overflow etc. when subtracting
img = cv2.imread("test_images/redbars.png").astype(np.int16)

#separating into blue, green and red channels
img_b = img[:, :, 0]
img_g = img[:, :, 1]
img_r = img[:, :, 2]

#for a red stripe, the red component should be much bigger than the rest
res_br = img_r - img_b
res_gr = img_r - img_g
res = np.maximum(res_br, res_gr)
res[res < 0] = 0
res = res.astype(np.uint8)  #convert back to uint8 for findContours etc.

ret, thresh = cv2.threshold(res, 50, 1, cv2.THRESH_BINARY)

#find contours and count them
im2, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

#gives the correct output of 5
print(len(contours))

#alternatively, count connected components with this:
ncomp, nimg = cv2.connectedComponents(thresh)
print(ncomp - 1)  #it counts the background as one of the components, so subtract 1

答案 1 :(得分:0)

这是一个可用于计算框架上红条数的管道:

int main(int argc, char** argv)
{
    Mat input = imread("red_lines.png");
    Mat hsv;
    cvtColor(input, hsv, CV_BGR2HSV);

    Mat mask;
    inRange(hsv, Scalar(0, 0,0), Scalar(15, 255,255), mask);

    Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));
    erode(mask, mask, kernel);
    dilate(mask, mask, kernel);

    vector<vector<Point>> contours;
    findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    cout << "objects found: " << contours.size() << endl;

    for (int i = 0; i < contours.size(); i++)
    {
        drawContours(input, contours, i, Scalar(0, 255, 0), 2);
    }

    imshow("mask", mask);
    imshow("contours", input);
    waitKey(0);

    return 0;
}

我的代码中的重要部分是 morphological operations erosion然后dilation)我应用于掩码(由inRange生成)。这样就可以删除“ mask的噪音”,从而只捕捉大红色条带。

Red strips with a green outline

为了进一步提高稳健性,我建议您检查每个轮廓的区域。如果它高于某个阈值,请将其丢弃。

P.S。这是C ++代码,但我相信你会弄清楚如何将它翻译成Python代码...... :)