Opencv screen turning off when switching between cameras

hello everyone, it might be an easy question but I couldn’t find a solution. I am using 4 usb cameras. I am taking images from 4 cameras at the same time and I have a code blog where I switch between these cameras.

For example; if the user wants to switch to the 1st camera, he presses “esc” and presses 1. If the user wants to switch to the 2nd camera, he presses “esc” and presses 2. and meanwhile the imshow screen is closed and reopened. I don’t think it’s very effective.

Now my question is:
1- Instead of pressing “esc” and pressing the number, the user can directly press the number and switch between the cameras. I searched for this but couldn’t find any results.
2-How do I prevent the imshow screen from turning off when switching between cameras?

I would be very grateful if you could help me. I can put the code here for understanding.

import cv2
import os
import imutils


def select_camera(last_index):
    number = 0
    hint = "Select a camera (0 to " + str(last_index) + "): "
    try:
        number = int(input(hint))
    except Exception ,e:
        print("It's not a number!")
        return select_camera(last_index)

    if number > last_index:
        print("Invalid number! Retry!")
        return select_camera(last_index)

    return number

def open_camera(index):
    cap = cv2.VideoCapture(index)
    return cap


def main():
    # Get camera list
    device_list = ["Camera_1","-------","Camera_2","-------",
                   "Camera_3","-------","Camera_4","-------"]
    index = 0

    for name in device_list:
        print(str(index) + ': ' + name)
        index += 1
    
    last_index = index - 1

    if last_index < 0:
        print("No device is connected")
        return

    # Select a camera
    camera_number = select_camera(last_index)
    
    # Open camera
    cap = open_camera(camera_number)
    

    if cap.isOpened():
        width = cap.get(3) # Frame Width
        height = cap.get(4) # Frame Height
        print('Default width: ' + str(width) + ', height: ' + str(height))

        while True:

            ret, frame = cap.read();
            cv2.imshow("frame", frame)

            # key: 'ESC' 
            key = cv2.waitKey(20)
            if key == 27:
                break

        cap.release() 
        cv2.destroyAllWindows() 

if __name__ == "__main__":
    while True:
        main()

that’s a basic programming issue.

do you notice that you have while True: main()?

you’re restarting your main() function each time you want to change the camera, and this destroys all existing windows (last line of your code)

yea, better just do that instead:

def main():

    cap = cv2.VideoCapture(0) 
    if not cap.isOpened():
        raise Exception("cap 0 failed")
    while True:
         ret, frame = cap.read();
         if not ret:
             print("read fail")
             break

         cv2.imshow("frame", frame)
         key = cv2.waitKey(20)
         if key == 27:
             break
         if key == '0': 
             cap = VideoCapture(0)
             break
         if key == '1': 
             cap = VideoCapture(1)
             break
         # ... etc. for 2,3

      cap.release() 
      cv2.destroyAllWindows() 

if __name__ == "__main__":
        main()
1 Like

thank you for your answer worked for me. I want to ask another think. It works with python2 but when i try for python3, i get an error. Do you have any idea what could be the reason for this ?

error message:

{WARN:0]  global /tmp/pip-req-build-8gn937y7/opencv/modules/videoio/src/cap_v4l.cpp (1004) tryIoctl VIDEOIO(V4L2:/dev/video0): select() timeout.

It works for my logitec usb camera in python3, but not for the kurokesu c1 usb webcam model.