我想将图像(字符串格式的numpy.ndarray)发送到另一个脚本。第二个脚本用图像做一些事情并等待另一个图像。
第一个脚本有以下循环:
while True:
out = os.fdopen(sys.stdout.fileno(), 'w')
[here some code]
img = cv2.imencode('.jpg', ndarray)[1].tostring()
out.write(img)
第二个:
while True:
data = sys.stdin.read()
[here some code]
用法:
$ python script1.py | python script2.py
第一次迭代没问题。第二个脚本获取图像并做一些事情。然后是第二次迭代和以下错误:
out.write(img)
IOError: [Errno 9] Bad file descriptor
close failed in file object destructor:
IOError: [Errno 9] Bad file descriptor
然后第二个脚本中的data
var为空。这段代码有什么问题?
如果我在循环上方有out = os.fdopen(sys.stdout.fileno(), 'w')
,则在第二个脚本中,行data = sys.stdin.read()
是无限的。
答案 0 :(得分:1)
不是读取EOF,而是将长度作为单独的字段发送,并且只读取那么多字节。
在写作方面:
while True:
# [here some code]
img = cv2.imencode('.jpg', ndarray)[1].tostring()
sys.stdout.write(str(len(img)) + '\n')
sys.stdout.write(img)
在阅读方面,就个人而言,我建议使用发电机:
def inputStream():
while True:
header_line = sys.stdin.readline()
if header_line == '': # file was closed on the input side
raise StopIteration()
len = int(header_line.strip())
img = sys.stdin.read(len)
yield img
for image in inputStream():
pass # do something with "image" here
答案 1 :(得分:0)
您正在查看这些错误,因为在第一个脚本(读取图像数据)中,正在循环中创建文件描述符。
它在第一次迭代中工作,但在循环的第二次迭代中,变量out
引用的文件对象超出范围(被新文件对象替换),而文件对象是被破坏后,底层文件描述符将被关闭。
因此,新文件对象(第二次变量out
已填充)不再是有效的文件描述符。
我假设使用2个单独脚本的原因(代码分为2个不同的模块)可能是:
代码结构:然后我建议使用定义良好的模块,并在第一个(正在运行的应用程序)中导入处理器。因此,您不需要在不同进程之间传递信息并处理IO,可以使用函数调用和传递参数。
多处理:如果你需要使用不同的脚本才能让多个进程协作,那么我建议使用标准库multiprocessing,它提供了良好的进程间通信机制,所以你赢了需要处理文件对象,描述符,stdout / stdin等。我会使用多处理Queue
,第一个脚本填充队列(put
),第二个脚本消耗(get
)