Cv2.imshow() screen turns black after a random amount of time

Hello. I am writing a program that displays a webcam feed live on the computer screen while also taking an image from that feed every 30 seconds or so to do some operation on that image (mainly slicing it up using numpy and opencv and reading numbers with Tesseract). Because I need to display the feed in a cv2.imshow() infinite loop that is uninterrupted, I have the loop in a thread so the image operation (scheduled every 30 seconds using a python scheduler) does not interrupt and freeze the display.

For some reason, the cv2.imshow() screen goes black after a random amount of time. This has happened after 15 minutes, and after 4 hours of functional operation, seemingly completely random. Not only that, but it saves an all black picture as well. The camera is on when it turns black (the light is anyway) and I have run a simple cv2.imshow() for hours to check for a hardware issue and there doesn’t seem to be one.

Below is my code. This is not the final code, but it is the smallest I can make it while keeping the same structure and reproducing the error.

import time
import gc
import cv2
import threading
import schedule
import numpy

class operator():
    def __init__(self):
        print("Start")
        
    def start_cam(self):
        is_blurry = True
        while is_blurry == True:
            print("Start of start_cam")
            self.camera = cv2.VideoCapture(0, cv2.CAP_DSHOW)                                                 # Make camera object with correct format, size, and autofocus. All of these appear to be necessary to get 4K resolution in OpenCV
            self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, 3840)  #3840
            self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 2160)  #2160
            self.camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('m','j','p','g'))
            self.camera.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter.fourcc('M','J','P','G'))                   
            self.camera.set(cv2.CAP_PROP_AUTOFOCUS, 1)
            self.camera.set(cv2.CAP_PROP_FPS, 60)

            i=10
            while i>0:                                                                                 # Takes 10 pictures and waits 1 sec in between each. This is done to make sure it has time to autofocus
                i=i-1
                cv2.waitKey(1000) #1000
                ret, self.frame = self.camera.read()
                if ret != True:
                    print("image error")                                                                # Check to make sure it actually took a picture and didn't fail
                    if ret != True and i == 1:
                        restart_loop = True
                        print("Image error, restarting loop")                                           #
                    continue
            laplace = cv2.Laplacian(self.frame, cv2.CV_64F).var()                                       # Checks if image is blurry. If it is, it restarts the camera.
            print(laplace)
            if laplace < 20:                        # Blurry
                print("Blurry image, reinitializing")
                self.camera.release()
                del(self.camera)
                cv2.destroyAllWindows()
                gc.collect()
                time.sleep(2)
            else:
                print("image not blurry")
                break


    def live_loop(self):
        loop_bool = True
        cv2.namedWindow("Live Feed", cv2.WINDOW_NORMAL)     # Creates a normal window so that the 4k image is scaled correctly for the live feed (I have a relatively small monitor)
        while loop_bool == True:
            ret, self.frame = self.camera.read()
            if ret != True:
                print("image error")
                break
            self.frame_rotate = cv2.rotate(self.frame, cv2.ROTATE_180)
            cv2.imshow("Live Feed", self.frame_rotate)
            k = cv2.waitKey(10)
        
        gc.collect()

    def data_operation(self):
        print("Start data operation")
        imgpath = "path where image is saved"
        cv2.imwrite(imgpath, self.frame)
        t = time.localtime()                                                                # If the image can't be read as a number, saves the image with a timestamp so that it can be examined later
        timestamp = time.strftime('%b-%d-%Y_%H;%M', t)
        print(timestamp)


if __name__== "__main__":
    op = operator()
    op.start_cam()
    x = threading.Thread(target=op.live_loop, daemon = True)
    x.start()
    schedule.every(30).seconds.do(op.data_operation)
    try:
        while True:
            schedule.run_pending()
            time.sleep(1)
    except KeyboardInterrupt:
        print("Ended Program")

    gc.collect()

The image operation starts by saving the image (using cv2.imwrite()) which is necessary because I need to upload the image to a google drive depending on certain variables. Interestingly, when I comment out the lines that save the image in the data_operation() function, the program seems to work without randomly turning black. However, I need to save the image as I said so I don’t know how to work around this.

Another interesting thing is that the program works fine on my laptop and never seems to go black, but the issue persists on the computer it needs to work on. I have done my best to replicate the exact conditions (external camera, same code, same python module version, etc.) and it never fails.

I realize this could be a python issue rather than an open issue, but I don’t know where else to turn. My StackOverflow question got no helpful answers, and I am totally stumped.

If there is a way to show a live webcam feed while grabbing an image from it and doing operations on that image (including saving it to the computer) without interrupting that live feed, please let me know. I don’t mind rebuilding this from the ground up if needed, I just want it to work. I am not a programmer by trade so I’ve gotten this far by Googling and problem solving, but this issue is so inconsistent that I don’t know what else to do.

Thanks in advance.