如何将OpenCV读取的摄像头帧在Python脚本间传递?
解决OpenCV帧跨Python脚本传递的错误
错误expected str, bytes or os.PathLike object, not ndarray的核心原因是:subprocess.call的命令行参数只能是字符串、字节或路径类对象,而OpenCV读取的frame是numpy数组(ndarray),无法直接作为命令行参数传递。以下是三种可行的解决方法:
方案1:临时文件中转(最易实现)
通过临时文件把帧写入磁盘,再将文件路径传给test2.py,test2.py读取路径加载帧。
修改test1.py的循环部分:
try: camera = camera() while True: frame = camera.read()[1] # 创建临时文件路径 temp_path = "/tmp/camera_temp.jpg" cv2.imwrite(temp_path, frame) # 传递临时文件路径给test2.py subprocess.call(["python", "/home/user/test2.py", temp_path]) time.sleep(5)
修改test2.py的读取逻辑:
try: # 直接接收临时文件路径,读取帧 frame = cv2.imread(sys.argv[1]) if frame is None: raise ValueError("无法读取传入的帧文件") server = "/net/192.168.4.51/mnt/LAN4Storage/EC/Camera/" cv2.imwrite(server + "temp.jpg", frame) timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") cv2.imwrite(server + timestamp + ".jpg", frame)
方案2:通过标准输入输出传递二进制数据
无需写入临时文件,直接将帧编码为二进制数据,通过subprocess的标准输入输出传递。
修改test1.py:
import numpy as np # ... 其他导入不变 try: camera = camera() while True: frame = camera.read()[1] # 将帧编码为JPEG二进制 _, img_encoded = cv2.imencode('.jpg', frame) # 启动子进程,通过stdin传递数据 proc = subprocess.Popen(["python", "/home/user/test2.py"], stdin=subprocess.PIPE) # 写入二进制数据 proc.communicate(input=img_encoded.tobytes()) time.sleep(5)
修改test2.py:
import numpy as np # ... 其他导入不变 try: # 从stdin读取二进制数据 data = sys.stdin.read() # 转换为numpy数组并解码为帧 nparr = np.frombuffer(data, np.uint8) frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR) if frame is None: raise ValueError("无法解码传入的帧数据") server = "/net/192.168.4.51/mnt/LAN4Storage/EC/Camera/" cv2.imwrite(server + "temp.jpg", frame) timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") cv2.imwrite(server + timestamp + ".jpg", frame)
方案3:直接调用函数(避免跨脚本进程通信)
将test2.py的逻辑封装为函数,在test1.py中直接导入调用,效率最高。
修改test2.py,封装逻辑为函数:
#!/usr/bin/env python import cv2 import datetime def save_frame(frame): server = "/net/192.168.4.51/mnt/LAN4Storage/EC/Camera/" cv2.imwrite(server + "temp.jpg", frame) timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") cv2.imwrite(server + timestamp + ".jpg", frame) # 保留命令行调用入口 if __name__ == "__main__": import sys try: frame = cv2.imread(sys.argv[1]) if frame is None: raise ValueError("无法读取传入的帧文件") save_frame(frame) except Exception as error: print(error)
修改test1.py,导入并调用函数:
#!/usr/bin/python import cv2 import time import datetime from test2 import save_frame # 导入test2的函数 def camera(): # ... 原camera函数逻辑不变 try: camera = camera() while True: frame = camera.read()[1] save_frame(frame) # 直接调用函数,无需subprocess time.sleep(5) # ... 原异常处理和finally逻辑不变
内容的提问来源于stack exchange,提问作者unformatted
相关产品推荐
相关产品推荐

