0

I'm using opencv to run color detect program that only detects the primary colors( red, green, and blue). Then I implemented an thirty second countdown to run while the camera is collecting data from color shown to the camera. When the countdown end, the program will display the percent of each color shown and what was shown the most in those thirty seconds. The problem is that camera takes too long to open and doesn't run at the same time as the countdown function. Snippet of code:

import time
import cv2
import threading

# import numpy as np
totalCount, countRed, countBlue, countGreen = 0, 0, 0, 0


def countdown(sec):
    for x in range(sec, -1, -1):
        print(f"{x:01}")
        time.sleep(1)
    return 0


def stream():
    global totalCount, countRed, countBlue, countGreen
    vid = cv2.VideoCapture(0)  # Cap is the Camera
    vid.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
    vid.set(cv2.CAP_PROP_FRAME_HEIGHT, 360)

    while vid.isOpened():
        _, imageFrame = vid.read()
        hsvFrame = cv2.cvtColor(imageFrame, cv2.COLOR_BGR2HSV)
        height, width, _ = imageFrame.shape

        cx = int(width / 2)
        cy = int(height / 2)

        # Pixel value
        pixelDot = hsvFrame[cy, cx]
        hueValue = pixelDot
        colorName = ["RED", "GREEN", "BLUE"]  # the options
        # The total count of the options being showed on screen

        if (hueValue < 15).all() and (5 > hueValue).all():
            color = colorName[0]
            countRed += 1
            totalCount += 1
        elif (hueValue < 88).all() and (78 > hueValue).all():
            color = colorName[1]
            countGreen += 1
            totalCount += 1
        elif (hueValue < 150).all() and (141 > hueValue).all():
            color = colorName[2]
            countBlue += 1
            totalCount += 1
        else:
            color = "UNDEFINED"

        cv2.putText(imageFrame, color, (10, 50), 0, 1, (255, 70, 24), 2)
        cv2.circle(imageFrame, (cx, cy), 5, (30, 25, 255), 3)
        cv2.imshow("Southern Jarvis", imageFrame)  # the name of the camera
        if ord('q') == cv2.waitKey(20) & 0xFF:
            break

    vid.release()
    cv2.destroyAllWindows()


if __name__ == '__main__':
    t1 = threading.Thread(target=countdown, args=(30,))
    t2 = threading.Thread(target=stream)
    t2.start()
    t1.start()
    t1.join()
    t2.join()
    if countRed > countGreen and countRed > countBlue:
        print("Red was shown the most")
    elif countGreen > countRed and countGreen > countBlue:
        print("Green was shown the most")
    elif countBlue > countGreen and countBlue > countRed:
        print("Blue was shown the most")
    else:
        print("All were shown equally")

I tried solving the problem by using lock object from import threading to ensure that the stream and countdown functions can run concurrently without data race conditions, and use local variables instead of global variables.

Gram
  • 1
  • Why threads in the first place? Seems like quite an overkill for what you want to accomplish, and you're trying to dig the hole even deeper. Just measure the elapsed time in the `while` loop and break out when it exceeds the desired threshold of 30 seconds. – Dan Mašek Apr 29 '23 at 18:24
  • Can you show me what you mean, please ? – Gram Apr 29 '23 at 18:27
  • https://stackoverflow.com/questions/7370801/how-do-i-measure-elapsed-time-in-python – Dan Mašek Apr 29 '23 at 18:30
  • Use vid = cv2.VideoCapture(0, cv2.CAP_DSHOW) instead of vid = cv2.VideoCapture(0) – Parthiban Marimuthu May 03 '23 at 08:37

0 Answers0