Пример IP C между двумя процессами с opencv (объект cv :: Mat) c ++ в качестве сервера и python в качестве клиента - PullRequest
2 голосов
/ 01 апреля 2020

Я пытаюсь создать приложение. где видео с веб-камеры захватывается приложением c ++. И я создаю инструмент анализа (который использует python), должен получить доступ к этому указанному c кадру из видеопотока, полученного из приложения c ++, и должен выполнить анализ для определенного c кадра.

Во время поиска в Google и мои друзья предлагают мне использовать IP C, где вы рассматриваете код C ++ как сервер и python как клиент. Я нашел какой-то ссылочный код в Интернете, но нашел несколько, но очень трудный для понимания процесса. Может ли кто-нибудь объяснить

  1. Как я могу сделать это с IP C (совместно используемая память или с сообщениями)?
  2. Любой пример или справочный код был бы очень полезен.
  3. Также будет полезна любая полезная ссылка на кикстарт таких нубов, как я.

Заранее спасибо.

1 Ответ

2 голосов
/ 01 апреля 2020

Вот очень простой пример использования 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);
}

Нет, это не код производственного качества, и да, я мог бы передать ширину, высоту и количество каналов и байт для выборки, но я хотел сделайте его красивым, простым и очевидным.


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 .

...