python - 两个进程之间的IPC示例,opencv(cv::Mat对象)c++作为服务器,python作为客户端

标签 python c++ multithreading opencv ipc

我正在尝试构建一个应用程序。其中网络摄像头视频源由 C++ 应用程序捕获。
我正在构建一个分析工具(使用 python),需要从视频源访问该特定帧,从 C++ 应用程序捕获,并需要对特定帧进行分析。

在谷歌搜索期间,我的 friend 建议我使用 IPC,您将 C++ 代码视为服务器,将 python 视为客户端。我确实在网上找到了一些引用代码,发现很少但很难理解过程。有人可以解释一下

  • 如何使用 IPC(共享内存或消息)来实现?
  • 任何示例或引用代码都会有很大帮助。
  • 此外,任何像我这样的菜鸟启动的有用链接都将非常有用。

  • 提前致谢。

    最佳答案

    这是一个非常简单的例子,使用 Redis 将图像从 C++ 服务器发送到 Python 或命令行客户端。

    因此,服务器(使用 hiredis )看起来像这样:

    #include <iostream>
    #include <opencv2/opencv.hpp>
    #include <cstdio>
    #include <hiredis.h>
    
    int
    main(int argc,char*argv[])
    {
       const int width = 640;
       const int height= 480;
       cv::Mat img(width,height, CV_8UC3, cvScalar(0,255,255));
    
       // Redis setup
       redisContext *c;
       redisReply *reply;
       const char *hostname = "localhost";
       int port = 6379;
    
       struct timeval timeout = { 2, 0 }; // 2 seconds
       c = redisConnectWithTimeout(hostname, port, timeout);
       if (c == NULL || c->err) {
           std::cerr << "Something bad happened" << std::endl;
           exit(1);
       }
    
       // Store Mat in Redis
       reply = (redisReply*)redisCommand(c,"SET image %b",(char*)img.data,height*width*3);
       freeReplyObject(reply);
    }
    

    不,它不是生产质量的代码,是的,我可以传输宽度和高度以及 channel 和字节数的数量,但我想保持它的美观、简单和明显。

    A python 读取该图像并显示它的客户端如下所示:
    #!/usr/bin/env python3
    
    import cv2
    import redis
    import numpy as np
    
    if __name__ == '__main__':
        # Redis connection
        r = redis.Redis(host='localhost', port=6379)
    
        data = r.get('image')
        img = np.frombuffer(data, dtype=np.uint8).reshape(480,640,3)
    
        print(f'Received image')
        cv2.imshow('image', img)
        key = cv2.waitKey(0)
    

    enter image description here

    如果您想从 中获取图像Redis 在终端中,您可以执行以下操作:
    redis-cli get image > image.raw
    

    或者您可以抓取它并转换为 PNG 并使用 轻松显示它ImageMagick :
    redis-cli get image | convert -depth 8 -size 640x480 bgr:- result.png
    

    当然,所有这些也可以跨网络工作,因此您可以向网络上任何位置的 Redis 实例发送和接收数据,只需指定 IP 地址即可。在终端中:
    redis-cli -h x.x.x.x get image
    

    您还可以在发送之前对图像进行 JPEG 编码或 PNG 编码,以节省网络带宽和 Redis 内存。

    您还可以设置图像的到期时间或生存时间,以便在特定时间后将其删除。

    您还可以保留最新的列表 N例如,视频的图像。

    您还可以在 Ruby、swift、C#、Java、PHP、Perl 中实现客户端和/或服务器......请参阅 Redis bindings .

    关于python - 两个进程之间的IPC示例,opencv(cv::Mat对象)c++作为服务器,python作为客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60966568/

    相关文章:

    c++ - OpenCL 因大输入数组而崩溃

    c++ - 浮点乘积扩展等价

    multithreading - 为多线程编程设计一个赋值

    java - 尝试在不使用 Java 中的任何库的情况下解决竞争条件

    python - pip 安装后错误 "no module named six"

    python - 对象属性的 Numpy 数组

    python - 访问 json 值

    c++ - 参数前的 const 与函数名后的 const C++

    java - 如何向数据库中插入百万条数据

    python - 使用 memcached.sock 路径连接到 python-memcached