Search code examples
python-2.7opencvimage-processingcontourarea

How to sum areas of contours after sorted them?


I'd like to sum areas of the largest five contours after sorted or all of them if less than five.

The robot follows the people's base on the color but sometimes people have the same color and I'd like to choose one from them using the area. I used this line for two contours but this method is not good area1 = cv2.contourArea(cnts[0]) + cv2.contourArea(cnts[1])

Full code:

import cv2
import numpy as np
from imutils.video import FPS
import time
cap = cv2.VideoCapture(0)
width = cap.get(3)  # float
height = cap.get(4)  # float
print width, height
time.sleep(2.0)
fps = FPS().start()
while (1):
    _, img = cap.read()
    if _ is True:
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
    else:
        continue
    black_lower = np.array([0,0,0], np.uint8)
    black_upper = np.array([180,255,30], np.uint8)
    black = cv2.inRange(hsv, black_lower, black_upper)
    kernal = np.ones((5, 5), "uint8")
    black = cv2.dilate(black, kernal)
    res_black = cv2.bitwise_and(img, img, mask=black)
    # Tracking black
    (_, contours, hierarchy) = cv2.findContours(black, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cnts = sorted(contours, key=cv2.contourArea, reverse=True)[:2000]  # get largest 2000 contour area
    area1 = cv2.contourArea(cnts[0]) + cv2.contourArea(cnts[1])
    # area2 = cv2.contourArea(cnts[0])
    # total = area1 +area2
    print 'area', area1,   type(cnts)
    rects = []
    print len(cnts) , type(cnts[1])
    for c in cnts:
        peri = cv2.arcLength(c, True)
        approx = cv2.approxPolyDP(c, 0.02 * peri, True)
        x, y, w, h = cv2.boundingRect(approx)
        if h >= 15:
            rect = (x, y, w, h)
            rects.append(rect)
            img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 0), 2)
            cv2.putText(img, "Black Colour", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0))
    cv2.imshow("Color Tracking", img)
    if cv2.waitKey(10) & 0xFF == ord('q'):
        cap.release()
        cv2.destroyAllWindows()
        break

Any help or suggestions would be appreciated.


Solution

  • You can sum them using list = [], but maybe you face another issue, sum of areas for all people.

    import cv2
    import numpy as np
    from imutils.video import FPS
    import time
    cap = cv2.VideoCapture(0)
    width = cap.get(3)  # float
    height = cap.get(4)  # float
    print width, height
    time.sleep(2.0)
    fps = FPS().start()
    while (1):
        _, img = cap.read()
        if _ is True:
            hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        else:
            continue
        black_lower = np.array([0,0,0], np.uint8)
        black_upper = np.array([180,255,30], np.uint8)
        black = cv2.inRange(hsv, black_lower, black_upper)
        kernal = np.ones((5, 5), "uint8")
        black = cv2.dilate(black, kernal)
        res_black = cv2.bitwise_and(img, img, mask=black)
        # Tracking black
        (_, contours, hierarchy) = cv2.findContours(black, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
        cnts = sorted(contours, key=cv2.contourArea, reverse=True)[:5]  # get largest five contour area
        areas = []
        for contour in cnts:
             area = cv2.contourArea(contour)
             if area > 300:
                  areas.append(area)
                  x, y, w, h = cv2.boundingRect(contour)
                  img = cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 0), 2)
                  cv2.putText(img, "Black Colour", (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0))
    
        a = sum(areas)
    
        print areas
        print a
    
        cv2.imshow("Color Tracking", img)
        if cv2.waitKey(10) & 0xFF == ord('q'):
             cap.release()
             cv2.destroyAllWindows()
             break