有没有更好的方法来命名管道`cv::mat`变量

Posted

技术标签:

【中文标题】有没有更好的方法来命名管道`cv::mat`变量【英文标题】:Is there a better way to named pipe a `cv::mat` variable 【发布时间】:2019-07-28 10:50:34 【问题描述】:

我正在尝试将cv::mat 变量从一个 C 程序传递到另一个它们彼此独立。

我已经创建了来自论坛和搜索的基本代码,我有 2 个程序,writer.creader.c

writer.c 中有一个 cv::mat img 变量,我需要通过管道将它传递给 reader.c cv::mat img 以显示 imshow()

我正在合并来自多个来源的代码,希望这能奏效,因为我可以找到一个工作示例

我的消息来源:

https://***.com/a/2789967/11632453

https://***.com/a/30274548/11632453

https://unix.stackexchange.com/questions/222075/pipe-named-fifo

https://***.com/a/36080965/11632453

这是我到现在为止的演变:

来自文件writer.c的代码

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include "opencv2/imgproc/imgproc.hpp"


using namespace cv;
using namespace std;

int main()

    Mat img;
    img = imread("/home/filipe/Documentos/QT_Projects/FIFO_Writer/download.jpeg", CV_LOAD_IMAGE_COLOR);   // Read the file

    if(! img.data )                              // Check for invalid input
    
        cout <<  "Could not open or find the image" << std::endl ;
        return -1;
    

    namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
    imshow( "Display window", img );
    //waitKey(0); // Wait for a keystroke in the window
    //return 0;




    int fd;
    char * myfifo = "/tmp/myfifo";

    // create the FIFO (named pipe)
    mkfifo(myfifo, 0666);

    // write "Hi" to the FIFO
    fd = open(myfifo, O_WRONLY);
    //write(fd, "Hi", sizeof("Hi"));
    write(fd, img.data, sizeof(img.data));
    close(fd);

    // remove the FIFO
    unlink(myfifo);

    return 0;

来自reader.c的代码

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include "opencv2/imgproc/imgproc.hpp"

using namespace cv;
using namespace std;

#define MAX_BUF 1024

int main()

    int fd;
    char * myfifo = "/tmp/myfifo";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open(myfifo, O_RDONLY);
    read(fd, buf, MAX_BUF);
    printf("Received: %s\n", buf);
    close(fd);

    Mat img(177, 284, CV_8UC3, Scalar(0, 0, 0));

    img.data= ((unsigned char*) (buf));
    namedWindow( "Display window", WINDOW_AUTOSIZE );// Create a window for display.
    imshow( "Display window", img );

    waitKey(0); // Wait for a keystroke in the window
    return 0;

我没有从这段代码中得到任何错误,但是,我没有得到 Image ether 没有要创建的窗口来显示图像。

有什么帮助吗? 有什么可以帮助我通过吗? 有什么方向吗?

谢谢

解决于https://answers.opencv.org/question/216274/is-there-a-better-way-to-named-pipe-a-cvmat-variable/

【问题讨论】:

printf("收到:%s\n", buf);恕我直言,这是未定义的行为,除非您确定 buf 是零终止的。其次,您是否在缓冲区内看到了什么,如果是,那么问题是您如何创建图像,否则问题出在传输中。 Lasty(并且可能与您的问题无关),不会分配 img.data= ((unsigned char*) (buf));制造泄漏?我不是 OpenCV 专家,但我希望数据在分配之前已经指向缓冲区。 嗨,谢谢你的帮助,对不起,我没有听从你的解释,你说的太技术性了,我是 C、opencv 和所有 linux 编程的傻瓜。 . 无论如何... 我明白你说问题不在管道上,而是关于如何分解图像并重新组装它,所以我在answers.opencv.org/question/216274/… 上创建了这篇文章的副本 我说的是您应该尝试找出问题是管道还是图像创建。一种方法是在传输和接收时打印缓冲区的内容。我会避免使用 %s 因为缓冲区可能没有 0 作为最后一个元素。您可以对前 100 个元素进行循环,然后在发送和接收时一个接一个地打印它们。 你说得对,我的管道有问题,我在两个程序上添加printf("%u\n",img.data); 并运行它们,我得到不同的输出 已解决answers.opencv.org/question/216274/… 是缓冲区大小的问题 【参考方案1】:

已解决Here

只需根据图像大小更改缓冲区大小

【讨论】:

以上是关于有没有更好的方法来命名管道`cv::mat`变量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 窗体应用程序中显示 cv::Mat?

编写接受 cv::Mat 或 cv::UMat 类型输入的模板函数

如何在openCV中修改cv::Mat的像素数据?

Uchar 到 cv::Mat 的向量

通过 openCV 创建矩形蒙版的更好方法

获取 cv::Mat 的黑色像素列表