Как передать несколько изображений с помощью ZeroMQ в C ++? - PullRequest
1 голос
/ 24 октября 2019

Я хочу реализовать программу, которая может передавать несколько изображений через ZeroMQ. Я могу отобразить несколько изображений на C ++ с помощью OpenCV, но не могу как-то отобразить на Python, хотя компилятор не выводил ошибок.

Как передать несколько изображений из C ++ в Python?

C ++Код:

    Mat img0;
    Mat img1;
    Mat img2;

    img0 = imread("images.jpeg");
    img1 = imread("images1.jpeg");
    img2 = imread("image2.jpg");

    if(img0.empty()) return -1;
    if(img1.empty()) return -1;
    if(img2.empty()) return -1;
    ShowManyImages("IMAGE",3,img0,img1,img2);

// Let structure for zeroMQ
    int32_t info[3];

    info[0] = (int32_t)img0.rows;
    info[1] = (int32_t)img0.cols;
    info[2] = (int32_t)img0.type();

    info[3] = (int32_t)img1.rows;
    info[4] = (int32_t)img1.cols;
    info[5] = (int32_t)img1.type();

    info[6] = (int32_t)img2.rows;
    info[7] = (int32_t)img2.cols;
    info[8] = (int32_t)img2.type();


    zmq::context_t context (1);
    zmq::socket_t socket (context, ZMQ_REQ);
    socket.connect ("tcp://localhost:5555");

    for(i=0; i<9; i++ )
    {
        zmq::message_t msg0 ( (void*)&info[i], sizeof(int32_t), NULL  );
        socket.send(msg0, ZMQ_SNDMORE);
    }


    void* data0 = malloc(img0.total() * img0.elemSize());
    memcpy(data0, img0.data, img0.total() * img0.elemSize());

    zmq::message_t msg00(data0, img0.total() * img0.elemSize(), my_free, NULL);
    socket.send(msg00);


    void* data1 = malloc(img1.total() * img1.elemSize());
    memcpy(data1, img1.data, img1.total() * img1.elemSize());

    zmq::message_t msg11(data1, img1.total() * img1.elemSize(), my_free, NULL);
    socket.send(msg11);

    void* data2 = malloc(img2.total() * img2.elemSize());
    memcpy(data2, img2.data, img2.total() * img2.elemSize());

    zmq::message_t msg22(data2, img2.total() * img2.elemSize(), my_free, NULL);
    socket.send(msg22);

Код Python:

import zmq
import cv2
import struct
import numpy as np

# Connection String
conn_str      = "tcp://*:5555"

# Open ZMQ Connection
ctx = zmq.Context()
sock = ctx.socket(zmq.REP)
sock.bind(conn_str)


while(True):
# Receve Data from C++ Program
    byte_rows, byte_cols, byte_mat_type, data=  sock.recv_multipart()

# Convert byte to integer
    rows = struct.unpack('i', byte_rows)
    cols = struct.unpack('i', byte_cols)
    mat_type = struct.unpack('i', byte_mat_type)

    if mat_type[0] == 0:
    # Gray Scale
        image = np.frombuffer(data, dtype=np.uint8).reshape((rows[0],cols[0]))
    else:
    # BGR Color
        image = np.frombuffer(data, dtype=np.uint8).reshape((rows[0],cols[0],3))

    cv2.imshow('Python',image)
    cv2.waitKey()

С уважением,

Ответы [ 2 ]

0 голосов
/ 24 октября 2019

Я вижу несколько проблем.

  1. Вы создаете массив размером 3 дюйма и затем сохраняете в нем 9 дюймов int32_t info[3];

  2. Вы отправляете и получаете не совпадают в части сообщения.

    • Вы отправляете в этом порядке (3 данные в конце)
    • byte_rows, byte_cols, byte_mat_type, byte_rows, byte_cols, byte_mat_type,byte_rows, byte_cols, byte_mat_type, data, data, data
    • Вы получаете в этом порядке (данные после каждой мета-части)
    • byte_rows, byte_cols, byte_mat_type, data, byte_rows, byte_cols, byte_mat_type, data, byte_rows, byte_cols, byte_mat_type, data
0 голосов
/ 24 октября 2019

Q : Как передать несколько изображений из C ++ в Python?

Приведенный выше код использует REQ/REP Масштабируемый образец формального шаблона связи, но он не пытается отправить и REP -либо к любому уже доставленному REQ -эст.

Без попытки .send() a REP -ly сторона REQ никогда не сможет отправить любое следующее сообщение.

В случае, если это вашепервый опыт работы с ZeroMQ ,
, с которым вы можете в первый раз ознакомиться с " ZeroMQ Принципы менее чем за Пять секунд перед тем, как углубляться в детали


Решение?

Попробуйте использовать PUSH/PULL Архетип, где ответ не требуется.

Далее, попытайтесь решить, является ли это разумно обоснованным предположением для отправки всех метаданных только с первым изображением (я бы лучше сочинил, лучше всего, используя struct.pack()/struct.unpack() совместимый BLOB wвсе byte_rows, byte_cols, byte_mat_type, data в каждом, однокадровом, тривиальном отображении полезных сообщений).

Сторона Python просто прочитает однокадровый BLOB за один шаг, при необходимости может проверить подпись .unpack() первые несколько байтов, чтобы узнать размер изображения, .unpack() "отдых" с данными изображения, и все готово. Разве это не мило?

Также предупреждаем, что не все платформы имеют одинаковый тип Endian-ness (поэтому лучше проектируйте код на стороне c с явным байтовым порядком в "network" -индийский порядок: o) просто для того, чтобы быть в безопасности, если хостинговые устройства / платформы развиваются дальше и могут стать другими Endian-ness в следующий раз. Явное упорядочение - это то же самое явное упорядочение, которое ваш код настаивал на использовании со дня 1)


Понятно. Итак, вы говорите, что я должен использовать PUSH / PULL, верно? но я изменил свою программу с ZMQ_REQ на ZMQ_XREQ на c ++ и с zmq.REP на zmq.XREQ на python. Затем я могу смотреть три окна в Python, но отображать только img0. Я знаю, что это произошло из-за sock.recv_multipart (). Но я не знаю, как это изменить. Также я должен реализовать с помощью PUSH / PULL? - user36327 7 часов назад

Нет, я никому не говорил, что ДОЛЖЕН использовать PUSH/PULL, это был совет от парня, который используетZeroMQ начиная с v2.1 +

XREQ/XREP эффективно замкнул ступеньку dFSA теоретически бесконечной цепочки REQ.send () s-REP.recv () s-REP. send () s-REQ.recv () s-REQ ...- REP ...- REP ...- REQ ...- REQ ...-...-
[... ad-бесконечность или тупик, в зависимости от того, что наступит раньше: o)]

Проблема в том, чтобы ожидать, что вещи обязательно произойдут, что на самом деле не должно происходить так, как ожидалось:

MASK        = 'Python: The Image#{0:} was decoded to be {1:}'
order_ORDER = 0
while( True ):  # THIS WILL RUN FOREVER, WON'T IT?
    #####################################################################################
    order_ORDER += 1
    #####################################################################################
    ( byte_rows,                                  # EXPECTS ALL THIS TO .recv() EACH TIME
      byte_cols,                                  # EXPECTS ALL THIS TO .recv() EACH TIME
      byte_mat_type,                              # EXPECTS ALL THIS TO .recv() EACH TIME
      data                                        # EXPECTS ALL THIS TO .recv() EACH TIME
      )           =  sock.recv_multipart()        # in Data from C++ Program
    #####################################################################################
    rows     = struct.unpack( 'i', byte_rows)     # EXPECTS THIS TO BE CORRECT  EACH TIME
    cols     = struct.unpack( 'i', byte_cols)     # EXPECTS THIS TO BE CORRECT  EACH TIME
    mat_type = struct.unpack( 'i', byte_mat_type) # EXPECTS THIS TO BE CORRECT  EACH TIME
    #####################################################################################
    if mat_type[0] == 0:                          # IF mat_type[0] WAS == 0 ?in 2nd, 3rd?
        # # # # # # # # # # # # # # # Gray Scale: # IF mat_type[0] WAS == 0 ?in 2nd, 3rd?
        image = np.frombuffer( data,
                               dtype = np.uint8
                               ).reshape( ( rows[0],
                                            cols[0]
                                            )
                                          )
        print "IMAGE WAS of TYPE == ZERO, HAVING SHAPE OF: ", image.shape, image.dtype
        imgType = 'Grayscale'
    else:                                         # IF mat_type[0] WAS != 0 ?in 2nd, 3rd?
        # # # # # # # # # # # # # # # # BGR Color # IF mat_type[0] WAS != 0 ?in 2nd, 3rd?
        image = np.frombuffer( data,
                               dtype = np.uint8
                               ).reshape( ( rows[0],
                                            cols[0],
                                            3
                                            )
                                          )
        print "IMAGE WAS of TYPE != ZERO, HAVING SHAPE OF: ", image.shape, image.dtype
        imgType = 'Blue-Green-Red'
    ###################################################################################
    cv2.imshow( MASK.format( imgType, order_ORDER ), image )
    cv2.waitKey()
    ###################################################################################
    #   LOOP AGAIN
    ###################################################################################
...