繁体   English   中英

从子流程实时捕获标准输出和摄像机帧

[英]Catching stdout and camera frames in realtime from subprocess

我有一个无线传感器节点,可以无线传输到与计算机相连的接收器。 我使用此命令实时查看数据

sudo stdbuf -o0 ./pip_sense.v2 l l | stdbuf -o0 grep -P "TX:03(376|004)

我是Python的新手,但是我能够开发出如下所示的代码来捕获标准输出,并从连接到同一台计算机的相机拍摄帧。 就是说,当接收到一个数据包(数据)时,将在该时间戳处捕获一个帧。

它运行正常,但运行缓慢。 我以10 Hz的频率运行传感器(每0.1秒发送一次),但是代码以较低的速度运行。 我知道那是因为我正在使用cv2.imwrite() (我注释掉了这一部分,这有助于减少延迟)。 而且,在这个讨论 ,使用其说(据我所知) shell=True可以调用额外的shell进程,从而增加延迟。

同样,看这个Popen()似乎也引起了延迟。 第二个链接中提出了一个解决方案,但是我真的不明白如何修改它以适合我。

#!/usr/bin/env python

from subprocess import Popen, PIPE
import time
import sys
import cv2
import os
import csv
import argparse
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from collections import OrderedDict
from datetime import datetime

PIP_CMD = 'sudo stdbuf -o0 ./pip_sense.v2 l l | stdbuf -o0 grep -P "TX:03(376|004)"'

def run(command):
    process = Popen(command, stdout=PIPE, shell=True)
    while True:
        line = process.stdout.readline().rstrip()
        if not line:
            break
        yield line
print ('Starting...')

def createFolder(directory):
    try:
        if not os.path.exists(directory):
            os.makedirs(directory)
    except OSError:
    print ('Error: Creating directory. ' + directory)

createFolder('/home/piptag/pip-test/capture_webcam/EXPERIMENTS')
file1 = open('/home/piptag/pip-test/capture_webcam/EXPERIMENTS/3376.txt','w')
file1.write("Time Stamp  \t TX ID \t RSSI  \tSEQ NO \tCAP  \tX-Axis \tY-Axis \tZ-Axis \t  X  \t  Y  \t Z \n")  # Header line 
file1.write("-------------------------------------------------------------------------------------------------------------------------------------\n")  

file2 = open('/home/piptag/pip-test/capture_webcam/EXPERIMENTS/3004.txt','w')
file2.write("Time Stamp  \t TX ID \t RSSI  \tSEQ NO  \tX-Axis \tY-Axis \tZ-Axis \t  X  \t  Y  \t Z \n")  # Header line 
file2.write("-------------------------------------------------------------------------------------------------------------------------------------\n") 

dirname = "/home/piptag/pip-test/capture_webcam/EXPERIMENTS/"

def save_webcam(dirname):
    cam = cv2.VideoCapture(-1) # was getting error (V4L: can't open camera by index 0), thus changes it to -1
    jpg_quality = 75
    frame_number = 0

    if cam.isOpened():
    ret_val, img = cam.read()
    else:
    ret_val = False

    timestamp = int(TS)

    path =  dirname + str(tx) + str("-") + str(timestamp) + ".jpg"

    cv2.imwrite(path, img, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])
    frame_number = frame_number + 1

##this is the end of the camera program 

def twos_comp(val, bits):
    """compute the 2's compliment of int value val"""
    if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255
        val = val - (1 << bits)        # compute negative value
    return val                         # return positive value as is


#########################################MAIN###################################

if __name__ == "__main__":
     for line in run(PIP_CMD):
    raw_data = line.split('\t')
        if len(raw_data) > 1:
            TS = raw_data[0][3:]
            tx = raw_data[3].split(':')[-1]
            rssi = float(raw_data[4][5:])
        crc_ok = True if (raw_data[5] != b'BAD CRC') else False
        no_drop = True if (raw_data[1] == b'Drop:0') else False

            # If CRC check is ok and no drop, process the packet
        if crc_ok and no_drop:
              data = raw_data[-1].split(':')[-1].split()
              cat = ""
              for i in data:
                   cat += str(i)

                  if tx == '03376':
              save_webcam(dirname)
                      print data
              CapStatus=data[1]
                      if CapStatus == '50':
                  Cap='0'
              elif CapStatus == '51':
                  Cap='1'
              SEQNO1=str(int((data[2]),16))
                      x_axis1=data[3]+data[4]
                      y_axis1=data[5]+data[6]
                      z_axis1=data[7]+data[8]
              TX1=tx
                      x1 = twos_comp(int(x_axis1,16), 16) * 0.0039 #* 9.80665  #the value is multiplied by 0.004 as the ADXL345                                    reports data as 4mg per 1lsb
                      y1 = twos_comp(int(y_axis1,16), 16) * 0.0039 #* 9.80665  #the value is multiplied by 0.004 as the ADXL345                                        reports data as 4mg per 1lsb
                      z1 = twos_comp(int(z_axis1,16), 16) * 0.0039 #* 9.80665  #the value is multiplied by 0.004 as the ADXL345                                    reports data as 4mg per 1lsb
              st1 = str(TS) + "\t "+ "{:<5}".format(str (TX1)) + "\t" + "{:<10}".format(str (rssi)) +                  "{:<5}".format(SEQNO1) + "\t" + "{:<5}".format(str (Cap)) + "\t" + "{:<5}".format(str (x_axis1)) +                  "\t" + "{:<5}".format(str (y_axis1)) + "\t"+ "{:<5}".format(str(z_axis1)) + "\t" + "{:<5}".format(str(x1))                  + "\t" + "{:<5}".format(str(y1)) + "\t" + "{:<5}".format(str(z1)) +"\n"
              file1.write(st1)

                  elif tx == '03004':
                save_webcam(dirname)
                    print data
                SEQNO2=str(int((data[1]),16))
                    x_axis2=data[2]+data[3]
                    y_axis2=data[4]+data[5]
                    z_axis2=data[6]+data[7]
            TX2=tx
            x2 = twos_comp(int(x_axis2,16), 16) * 0.0039 #* 9.80665  #the value is multiplied by 0.004 as the ADXL345                           reports dataas  4mg per 1lsb
                    y2 = twos_comp(int(y_axis2,16), 16) * 0.0039 #* 9.80665  #the value is multiplied by 0.004 as the ADXL345                           reports data as 4mg per 1lsb
                    z2 = twos_comp(int(z_axis2,16), 16) * 0.0039 #* 9.80665  #the value is multiplied by 0.004 as the ADXL345                           reports data as 4mg per 1lsb

            st2 = str(TS) + "\t "+ "{:<5}".format(str (TX2)) +"\t "+ "{:<10}".format(str (rssi)) +                  "{:<5}".format(SEQNO2) + "\t" + "{:<5}".format(str (x_axis2)) + "\t"+ "{:<5}".format(str (y_axis2)) +                   "\t"+ "{:<5}".format(str(z_axis2))+ "\t"+"{:<5}".format(str(x2)) + "\t" + "{:<5}".format(str(y2))+                  "\t"+ "{:<5}".format(str(z2)) +"\n"
            file2.write(st2)              
file1.close()
file2.close()

感谢您的帮助

谢谢

更新:我从朋友那里得到了建议,并且有效。

在save_webcam函数之外(作为全局变量)调用cam = cv2.VideoCapture(-1)可以大大减少延迟。

在这种情况下,将打开相机一次,然后每次调用save_webcam都会捕获图像...因此,打开和关闭相机会减慢该过程。

但是 ,我想进一步增强该程序,因为它有时会卡住。 因此,任何人都知道这篇文章中的内容以及应该如何修改我的stdout部分,然后请在此处评论。 我很欣赏这个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM