【问题标题】:count red color object from video opencv python从视频opencv python中计算红色对象
【发布时间】:2017-11-28 16:54:16
【问题描述】:

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

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(center) 出现超过 300。任何人都可以帮助计算红色条的数量。任何解决方案都会有所帮助。

【问题讨论】:

  • 你能更新下和上的值,并可能添加你得到的掩码吗?

标签: python opencv video


【解决方案1】:

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

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 operationserosion 然后dilation)我应用在面具上(来自inRange)。这允许移除“面具的噪音”,从而只捕捉大红色条带。

为了进一步提高鲁棒性,我建议你检查每个轮廓的区域。如果它高于某个阈值,则丢弃它。

附:这是 C++ 代码,但我相信您会弄清楚如何将其转换为 Python 代码... :)

【讨论】:

    【解决方案2】:

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

    显然,Threshold 在这方面效果很好:

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

    数一数,这就是条纹的数量。但也有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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-06
      • 2022-09-23
      • 2016-11-15
      • 1970-01-01
      • 1970-01-01
      • 2016-12-17
      相关资源
      最近更新 更多