linux fifo python,使用命名(fifo)管道在python和c之间传输数组(图像)++

我需要通过一个名为FIFO的管道从python进程向c++进程发送一个数组(表示图像),然后以另一种方式返回(在Linux系统上)。在

当在两个Python进程之间使用命名管道时,下面的代码非常有用。它使用numpy的tostring()和fromstring()函数:

通过命名管道(Python)发送帧

在import cv2

import numpy as np

from time import sleep

##########################################################

FIFO_Images = "./../pipes/images.fifo"

videoName = "./../../videos/videoName.avi"

delim = "break"

##########################################################

def sendImage(h, w, d, pixelarray):

imageString = pixelarray.tostring()

with open(FIFO_Images, "w") as f:

f.write(str(h)+ delim + str(w)+ delim + str(d) + delim + imageString)

sleep(.01)

return

##########################################################

cap = cv2.VideoCapture(videoName)

while(cap.isOpened()):

ret, frame_rgb = cap.read()

h, w, d = frame_rgb.shape

sendImage(h, w, d, frame_rgb)

cap.release()

cv2.destroyAllWindows()

通过命名管道(Python)读取帧

^{pr2}$

但是,我无法从cpp端的管道中读取整个图像,因为它将“\n”作为自动读取的分隔符。在

我的解决方法是对“tostring()”图像进行base64编码,然后通过管道发送。这是可行的,但是另一张幻灯片上的base64解码对于实时应用程序来说太慢了(每帧大约0.2秒)。代码:

通过命名管道(Python)发送base64编码的图像

在import cv2

import numpy as np

from time import time

from time import sleep

import base64

##########################################################

FIFO_Images = "./../pipes/images.fifo"

videoName = "./../../videos/videoName.avi"

delim = ";;"

##########################################################

def sendImage(h, w, d, pixelarray):

flat = pixelarray.flatten()

imageString = base64.b64encode(pixelarray.tostring())

fullString = str(h)+ delim + str(w)+ delim + str(d)+ delim + imageString + delim + "\n"

with open(FIFO_Images, "w") as f:

f.write(fullString)

return

##########################################################

cap = cv2.VideoCapture(videoName)

count = 0

while(cap.isOpened()):

ret, frame_rgb = cap.read()

h, w, d = frame_rgb.shape

frame_gbr = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR)

sendImage(h, w, d, frame_rgb)

cap.release()

cv2.destroyAllWindows()

读取命名管道(C++)上的Base64编码图像

在#include "opencv2/opencv.hpp"

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

using namespace cv;

#define FIFO_FILE "./../../../pipes/images.fifo"

#define MAX_BUF 10000000

FILE *fp;

char readbuf[MAX_BUF + 1]; //add 1 to the expected size to accomodate the mysterious "extra byte", which I think signals the end of the line.

/************************BASE64 Decoding*********************************************/

std::string base64_encode(unsigned char const* , unsigned int len);

std::string base64_decode(std::string const& s);

static const std::string base64_chars =

"ABCDEFGHIJKLMNOPQRSTUVWXYZ"

"abcdefghijklmnopqrstuvwxyz"

"0123456789+/";

static inline bool is_base64(unsigned char c) {

return (isalnum(c) || (c == '+') || (c == '/'));

}

std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {

std::string ret;

int i = 0;

int j = 0;

unsigned char char_array_3[3];

unsigned char char_array_4[4];

while (in_len--) {

char_array_3[i++] = *(bytes_to_encode++);

if (i == 3) {

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;

char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);

char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

char_array_4[3] = char_array_3[2] & 0x3f;

for(i = 0; (i <4) ; i++)

ret += base64_chars[char_array_4[i]];

i = 0;

}

}

if (i)

{

for(j = i; j < 3; j++)

char_array_3[j] = '\0';

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;

char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);

char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

char_array_4[3] = char_array_3[2] & 0x3f;

for (j = 0; (j < i + 1); j++)

ret += base64_chars[char_array_4[j]];

while((i++ < 3))

ret += '=';

}

return ret;

}

std::string base64_decode(std::string const& encoded_string) {

int in_len = encoded_string.size();

int i = 0;

int j = 0;

int in_ = 0;

unsigned char char_array_4[4], char_array_3[3];

std::string ret;

while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {

char_array_4[i++] = encoded_string[in_]; in_++;

if (i ==4) {

for (i = 0; i <4; i++)

char_array_4[i] = base64_chars.find(char_array_4[i]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);

char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);

char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (i = 0; (i < 3); i++)

ret += char_array_3[i];

i = 0;

}

}

if (i) {

for (j = i; j <4; j++)

char_array_4[j] = 0;

for (j = 0; j <4; j++)

char_array_4[j] = base64_chars.find(char_array_4[j]);

char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);

char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);

char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

for (j = 0; (j < i - 1); j++) ret += char_array_3[j];

}

return ret;

}

/*********************************************************************/

int stringToInt(string str)

{

int num;

if (!(istringstream(str) >> num)) num = 0;

return num;

}

/*********************************************************************/

bool timerOn = 0;

clock_t timerStart;

void Timer(string process)

{

if (!timerOn)

{

timerStart = clock();

timerOn = true;

}

else if (timerOn)

{

double duration = (clock() - timerStart) / (double) CLOCKS_PER_SEC;

cout << "Time to complete: ";

printf("%.2f", duration);

cout << ": " << process << endl;

timerOn = false;

}

}

/*********************************************************************/

void getFrame()

{

string fullString;

string delimiter = ";;";

size_t pos = 0;

string token;

int h;

int w;

int d;

string imgString;

int fifo;

bool cont(true);

/***************************

Read from the pipe

www.tldp.org/LDP/lpg/node18.html

***************************/

Timer("Read from pipe");

fp = fopen(FIFO_FILE, "r");

fgets(readbuf, MAX_BUF + 1, fp); // Stops when MAX_BUF characters are read, the newline character ("\n") is read, or the EOF (end of file) is reached

string line(readbuf);

fclose(fp);

Timer("Read from pipe");

//parse the string into components

Timer("Parse string");

int counter = 0;

while ((pos = line.find(delimiter)) != string::npos)

{

token = line.substr(0,pos);

if (counter == 0)

{

h = stringToInt(token);

}

else if (counter == 1)

{

w = stringToInt(token);

}

else if (counter == 2)

{

d = stringToInt(token);

}

else if (counter == 3)

{

imgString = token;

//cout << imgString[0] << endl;

}

else

{

cout << "ERROR: Too many paramaters passed" << endl;

return;

}

line.erase(0, pos + delimiter.length());

counter ++;

}

if (counter == 3)

{

imgString = token;

}

if (counter < 3)

{

cout << "ERROR: Not enough paramaters passed: " << counter << endl;

//return;

}

Timer("Parse string");

/***************************

Convert from Base64

***************************/

Timer("Decode Base64");

std::string decoded = base64_decode(imgString);

Timer("Decode Base64");

/***************************

Convert to vector of ints

***************************/

Timer("Convert to vector of ints");

std::vector imgVector;

for (int i = 0; i < decoded.length(); i = i+1) // + 4)

{

int temp = (char(decoded[i]));

imgVector.push_back(temp);

}

Timer("Convert to vector of ints");

//convert the vector into a matrix

Mat frame = Mat(imgVector).reshape(d, h);

namedWindow("Frame", WINDOW_AUTOSIZE);

imshow("Frame", frame);

waitKey(1);

}

int main()

{

/* Create the FIFO if it does not exist */

umask(0);

mknod(FIFO_FILE, S_IFIFO|0666, 0);

while(1)

{

getFrame();

}

return 0;

}

必须有更有效的方法来实现这一点。有人能推荐吗?虽然我很高兴听到其他方法的建议,但目前我只能使用命名管道。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值