0

I have a video with a moving red ball in the middle and I want the program to return the position of that object throughout the video. I've read many examples online but I am not so sure what's the best way to do it in opencv.

enter image description here

import cv2
import numpy as np


coords = []

# Open the video
cap = cv2.VideoCapture('video-4.mp4')

# Initialize frame counter
while(1):
    
    # Take each frame
    _, frame = cap.read()

    # Convert BGR to HSV

    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # define range of blue color in HSV 
    lower_red = np.array([100, 150, 0])
    upper_red = np.array([140, 255, 255])

    imgThreshHigh = cv2.inRange(hsv, lower_red, upper_red)
    thresh = imgThreshHigh.copy()

    countours,_ = cv2.findContours(thresh, cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

    for cnt in countours:
        area = cv2.contourArea(cnt)
        best_cnt = cnt

    M = cv2.moments(best_cnt)
    cx,cy = int(M['m10']/M['m00']), int(M['m01']/M['m00'])
    coord = cx, cy 
    
    print(coord)

    cv2.imshow('frame',frame)
    cv2.imshow('Object',thresh)
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break
cv2.destroyAllWindows()

I am not sure why, but it only processes a few frames of the videos, not all.

4
  • 1
    Read the video frame by frame. For each frame detect the red dot (centroid of the red color cluster) Commented Feb 7, 2021 at 7:32
  • @Epsi95 thank you but which exact method should I use, should I use cv2.moment or something Commented Feb 7, 2021 at 8:27
  • 1
    check this blog pyimagesearch.com/2014/07/21/… Commented Feb 7, 2021 at 8:31
  • Do you want to just "track" or "detect+track"? If coordinates in first frame are detected manually then it becomes a much easy problem. If you want automatic detection also... plz update the question ... Commented Feb 7, 2021 at 10:45

1 Answer 1

1

It is not clear to me how the best_cnt contour is selected. Right now it is just selecting the last one. I think it was intended to filter by size to ensure the small red circle was selected, but it is not doing that. Maybe the dropped frames happen because the last contour in the list is not the red circle. I would try to filter by size and keep the contour smaller than a given max area.

Also, it looks like the red color filter range is off. I could only detect the ball changing the red filter values to:

lower_red = np.array([170, 0, 190])
upper_red = np.array([179, 255, 255])

To do this, I calculated the min and max values in the small area around the red circle:

plt.imshow(hsv[255:275, 170:190, :])

Red circle region

np.min(hsv[255:275, 170:190, :], axis=0)

Red color min values

np.max(hsv[255:275, 170:190, :], axis=0)

Red color max values

And chose min and max values to give some wiggle room for the red to change in different frames. This will need fine tuning using all the frames in your video to make sure no shade of red is left out using those limits.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.