Understanding how to deploy python code to pop up balloons

672 views Asked by At

I'm a newbie in programming and I need to write code to detect balloon on the fixed background using numpy and openCV in live video and to return the centre of the object [balloon].

Sorry about the ignorance of the questions.

Since I'm new, I had troubles with thinking about the logic of doing it, I don't have the resources to "teach the machine" and creating cascade XML to detect balloons so I thought about 1 possible solution : Using cv2.createBackgroundSubtractorMOG2() to detect motion with the same background and once there is some object [balloon], count all the white pixels in the live video and return the centre of it, with the right threshold amount of white pixels.

The problem is, I don't know how to get the value of the pixel from 0-255 to know if it's white or black and shows the video at the same time, I think that there is a much easier way that I couldn't find guides for it.

import numpy as np

import cv2

cap = cv2.VideoCapture(0)

fgbg = cv2.createBackgroundSubtractorMOG2()

while(1):

    ret, frame = cap.read()
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    fgmask = fgbg.apply(gray)
    img_arr = np.array(fgmask)
    cv2.imshow('frame',fgmask)
    for i in fgmask:
        for j in i:
            print(fgmask)
    k = cv2.waitKey(30) & 0xff
    if k == 27:
        break
cap.release()
cv2.destroyAllWindows()

I'm getting fray video on the output and lots of values that I don't know how to understand them on the output.

1

There are 1 answers

11
furas On BEST ANSWER

I would use

changes = (fgmask>200).sum()

to compare all pixels with almost white value (>200) and count these pixels.

And then I can compare result with some value to treat it as move.

import numpy as np

import cv2

cap = cv2.VideoCapture(0)

fgbg = cv2.createBackgroundSubtractorMOG2()

while True:

    ret, frame = cap.read()

    if frame is None:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    fgmask = fgbg.apply(gray)

    #changes = sum(sum(fgmask>200))
    changes = (fgmask>200).sum() 
    is_moving = (changes > 10000)
    print(changes, is_moving)

    cv2.imshow('frame', fgmask)

    k = cv2.waitKey(10) & 0xff
    if k == 27:
        break

cv2.destroyAllWindows()
cap.release()

print() needs some time to display text so printing all pixels (many times in loop) can slow down program. So I skip this. I don't have to know values of all pixels.


EDIT: Using answer in how to detect region of large # of white pixels using opencv? and add code which can find white regions and draw rectangle. Program opens two window - one with grayscale fgmask and other with RGB frame and they can be hidden one behind another. You have to move one window to see another.

EDIT: I added code which use cv2.contourArea(cnt) and (x,y,w,h) = cv2.boundingRect(cnt) to create list with items (area,x,y,w,h) for all counturs and then get max(items) to get contour with the biggest area. And then it use (x + w//2, y + h//2) as center for red circle.

import numpy as np

import cv2

cap = cv2.VideoCapture(0)

fgbg = cv2.createBackgroundSubtractorMOG2()

while True:

    ret, frame = cap.read()

    if frame is None:
        break

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    fgmask = fgbg.apply(gray)

    #changes = sum(sum(fgmask>200))
    changes = (fgmask>200).sum() #
    is_moving = (changes > 10000)
    print(changes, is_moving)


    items = []

    contours, hier = cv2.findContours(fgmask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    for cnt in contours:
        area = cv2.contourArea(cnt)
        if 200 < area:
            (x,y,w,h) = cv2.boundingRect(cnt)
            cv2.rectangle(fgmask, (x,y),(x+w,y+h),255, 2)
            cv2.rectangle(frame, (x,y),(x+w,y+h),(0,255,0), 2)
            items.append( (area, x, y, w, h) )

    if items:
        main_item = max(items)
        area, x, y, w, h = main_item
        if w > h:
            r = w//2
        else:
            r = h//2
        cv2.circle(frame, (x+w//2, y+h//2), r, (0,0,255), 2)

    cv2.imshow('fgmask', fgmask)
    cv2.imshow('frame', frame)

    k = cv2.waitKey(10) & 0xff
    if k == 27:
        break

cv2.destroyAllWindows()
cap.release()

enter image description here