在使用python使用threading、os、cv2进行多线程文件的图像的获取存储、读取、删除的过程中,遇到了一些无法解决的问题

在使用python使用threading、os、cv2进行多线程文件的图像的获取存储、读取、删除的过程中,遇到了一些无法解决的问题:
代码如下:

import cv2
import  time
import  threading
import os

#从电脑摄像头获取图片并存储
def cunchu():
 cap = cv2.VideoCapture(0)
 success,x_img=cap.read()
 cv2.imwrite(os.path.join('C:\\Users\\10605\\Desktop\\wjj','1.png'), x_img)

#读取图片
def duqv():
     img = cv2.imread('C:\\Users\\10605\\Desktop\\wjj\\1.png')
     cv2.imshow("img", img)
     cv2.waitKey(1)

#删除图片
def shanchu():
    os.remove('C:\\Users\\10605\\Desktop\\wjj\\1.png')

if __name__== '__main__':

    cunchu1 = threading.Thread(target=cunchu)
    duqv1 = threading.Thread(target=duqv)
    shanchu1 = threading.Thread(target=shanchu)

    cunchu1.start()
    time.sleep(1)
    print("1")
    duqv1.start()
    time.sleep(2)
    print("2")
    shanchu1.start()
    time.sleep(1)
    print("3")

报错如下

C:\Users\10605\Desktop\venv\Scripts\python.exe C:/Users/10605/Desktop/venv/图片实验.py 
1
[ WARN:0@1.422] global D:\a\opencv-python\opencv-python\opencv\modules\imgcodecs\src\loadsave.cpp (239) cv::findDecoder imread_('C:\Users\10605\Desktop\wjj\1.png'): can't open/read file: check file path/integrity
Exception in thread Thread-2 (duqv):
Traceback (most recent call last):
  File "C:\Users\10605\AppData\Local\Programs\Python\Python310\lib\threading.py", line 1009, in _bootstrap_inner
    self.run()
  File "C:\Users\10605\AppData\Local\Programs\Python\Python310\lib\threading.py", line 946, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\10605\Desktop\venv\图片实验.py", line 15, in duqv
    cv2.imshow("img", img)
cv2.error: OpenCV(4.6.0) D:\a\opencv-python\opencv-python\opencv\modules\highgui\src\window.cpp:967: error: (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'

2
3

进程已结束,退出代码0

以下内容部分参考ChatGPT模型:


问题分析:在多线程操作中,由于线程间的并发执行,可能会导致某些操作的顺序出现问题,比如在duqv线程中读取图片时,可能会出现文件不存在的情况,因为cunchu线程还没有完成图片的存储就被duqv线程读取了。另外,在删除图片时也需要注意,可能会出现文件不存在的情况,因为shanchu线程可能会先于cunchu线程执行,导致文件还没有创建就被删除了。

解决思路:可以使用线程同步的方式来解决这个问题,比如使用锁来保证cunchu线程完成图片存储后再执行duqv线程,使用条件变量来保证cunchu线程完成图片存储后再执行shanchu线程。另外,可以使用异常处理来捕获文件不存在等异常情况。

代码如下:

import cv2
import time
import threading
import os


#从电脑摄像头获取图片并存储
def cunchu(lock, event):
    cap = cv2.VideoCapture(0)
    success, x_img = cap.read()
    cv2.imwrite(os.path.join('C:\\Users\\10605\\Desktop\\wjj','1.png'), x_img)
    event.set()
    lock.release()


#读取图片
def duqv(lock, event):
    event.wait()
    lock.acquire()
    try:
        img = cv2.imread('C:\\Users\\10605\\Desktop\\wjj\\1.png')
        cv2.imshow("img", img)
        cv2.waitKey(0)
    except Exception as e:
        print(e)
    finally:
        lock.release()


#删除图片
def shanchu(lock, event):
    event.wait()
    lock.acquire()
    try:
        os.remove('C:\\Users\\10605\\Desktop\\wjj\\1.png')
    except Exception as e:
        print(e)
    finally:
        lock.release()


if __name__ == '__main__':
    lock = threading.Lock()
    event = threading.Event()

    cunchu1 = threading.Thread(target=cunchu, args=(lock, event))
    duqv1 = threading.Thread(target=duqv, args=(lock, event))
    shanchu1 = threading.Thread(target=shanchu, args=(lock, event))

    lock.acquire()
    cunchu1.start()
    duqv1.start()
    shanchu1.start()

在这个例子中,我们使用了线程同步的方式来保证cunchu线程完成图片存储后再执行duqv线程和shanchu线程,具体的方法是使用锁和条件变量。首先,我们创建了一个锁和一个条件变量,然后在cunchu线程中,当图片存储完成后,我们使用event.set()来设置条件变量,表示图片已经存储完成;然后使用lock.release()来释放锁。在duqv线程和shanchu线程中,我们先使用event.wait()来等待条件变量被设置,表示图片已经存储完成;然后使用lock.acquire()来获取锁,保证线程同步。在读取图片和删除图片时,我们使用了异常处理来避免文件不存在等异常情况。


如果我的建议对您有帮助、请点击采纳、祝您生活愉快

以下回答结合了ChatGPT:

  • 图片路径错误:在cunchu()函数中,将图片存储到了'C:\Users\10605\Desktop\wjj'文件夹下,但在duqv()函数中读取图片时使用了'C:\Users\10605\Desktop\wjj\1.png'路径,因此读取不到图片。您可以在duqv()函数中使用os.path.join('C:\Users\10605\Desktop\wjj', '1.png')来构造图片路径,确保路径正确。
  • 图片读取错误:在duqv()函数中,使用cv2.imread()读取图片时可能会出现读取错误的情况。可以尝试打印读取的图片是否为空,或者使用try...except语句捕捉错误并打印错误信息,方便排查问题。

根据你提供的错误信息来看,是在调用cv2.imshow("img", img)方法时,内部方法在判断图片的大小size.width>0 && size.height>0时报错了,说明你的图片应该是没有读取成功,导致判断大小时失败了。因为是使用了线程,而线程是并发执行的,有可能在你还没有把图片存储下来,另一个线程就去读取了,从而导致图片没有读取成功,建议你把存储图片和读取图片之间的休眠时间设置长一点看看。

这个代码对于调用函数的返回值没有判断哈,中间如果有错误就会出问题
先可以看下 cunchu 产生1.png文件是否成功了
然后在 duqv 函数,用os模块里面的函数先判断一下文件1.png是否存在, 还需判断img是否为None等

既然说了并发,要考虑下 读取和删除方式 获取文件失败场景,其次也要考虑保存方法 文件路径是否存在

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^