1

I have written a python code. It gets the video from the camera at 30 fps. Now I have found a very good C++ open source code library that takes the image and perform my desired function. As it is open source code. SO i have its code.

The Problem is it is in C++ and i am writing my code in Python. I need to send an image to that C++ code , process it there and send back the processed image to Python.

I have read numerous questions on stackoverflow and youtube. All answers require some background knowledge of how to send data from C++ to python and vice versa.

As i dont know how to send a data between C++ and python. Could anyone can explain how to send images between them from step 1.

6
  • A simple HACK(meant for dev use only) would be: Write the images you recieve from the webcam and read the same image in C++, you can do this by calling the cpp executable with image_file_path as param. Once you are sure it is working as required then you may invest your time in integrating the native code to your python script Commented Feb 8, 2017 at 7:23
  • Actually i am getting a real time video. Video may be atleast 5-6 min duration. As i am getting 30 frames per second . So ithink it wouldn't be appropiate to save 30 images per second and do it for like 5-6 min atleast Commented Feb 8, 2017 at 7:26
  • I suggested the HACK for validating your assumptions about the C++ script, if you are sure that the cpp code is working as expected then, here is thread with all possibilities: stackoverflow.com/questions/1153577/integrate-python-and-c Commented Feb 8, 2017 at 7:28
  • Possible duplicate of Integrate Python And C++ Commented Feb 8, 2017 at 7:28
  • Maybe you don't need to send the image at all stackoverflow.com/a/145436/2836621 Commented Feb 8, 2017 at 7:42

1 Answer 1

1

Its weird nobody sought to solve this problem even 4.9 years later. Here's how I did it using ZMQ. I used PUSH/PULL architecture to send image (.ppm) file from a Python3 client (PUSH) to C++ server (PULL).

The process requires manually obtaining the length/size of the image-encoded-into-base64-string, printed in my python program. This size is then used to determine the buffer size required by the C++ server before it can receive the data.

client.py

import time
import zmq
import base64

def producer():
    # setup socket
    context = zmq.Context()
    zmq_socket = context.socket(zmq.PUSH)
    zmq_socket.bind("tcp://127.0.0.1:5557")

    # Read file content
    f = open("/home/virus/Desktop/optimisation/test.ppm",'rb')
    bytes = bytearray(f.read())

    # Encode to send
    strng = base64.b64encode(bytes)
    print("Sending file over")
    print("\n\nEncoded message size: ",len(strng)) # 4194328 in my case
    zmq_socket.send(strng)
    f.close()

producer()

server.cpp

#include <zmq.h>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fstream> // for writing files
#include <iostream>

typedef unsigned char uchar;

using namespace std;

static string base64_decode(const string &in) {
    // Ref: https://stackoverflow.com/a/34571089/9625777
    string out;
    vector<int> T(256,-1);
    for (int i=0; i<64; i++)
        T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;

    int val=0, valb=-8;
    for (uchar c : in) {
        if (T[c] == -1) break;
        val = (val << 6) + T[c];
        valb += 6;
        if (valb >= 0) {
            out.push_back(char((val>>valb)&0xFF));
            valb -= 8;
        }
    }
    return out;
}

int main ()
{
    while(1)
    {
      // Create socket
      void *context = zmq_ctx_new ()
      void *requester = zmq_socket (context, ZMQ_PULL)
      if(zmq_connect (requester, "tcp://localhost:5557")!=0)
      {
        // The zmq_connect() function returns zero if successful.
        // Otherwise it returns -1
        cout << "No connection found\n";
        continue;
      }
      cout << "Got a connectopn\n";

      // Receive data
      char buffer [4194328];
      zmq_recv (requester, buffer, 4194328, 0)
      //cout << buffer;

      // decode data
      auto decodedData = base64_decode(buffer);

      // write results to a file
      ofstream myFile("res.ppm");
      myFile << decodedData;
      myFile.close();

      // Close socket
      zmq_close (requester);
      zmq_ctx_destroy (context);
    }
    return 0;
}


As an option, PUSH/PULL can also be substituted with REQ/REP

client.py

import time
import zmq
import base64

def producer():
    context = zmq.Context()
    zmq_socket = context.socket(zmq.REQ)
    zmq_socket.connect("tcp://127.0.0.1:5556")
    # Start your result manager and workers before you start your producers

    f = open("/home/virus/Desktop/optimisation/test.ppm",'rb')
    #data = f.read
    bytes = bytearray(f.read());#print('\n \t bytes: ',bytes)
    print("bytes len",len(bytes))
    strng = base64.b64encode(bytes)
    #serializedImage = { 'data' : strng }
    #print("sending string: ",strng);
    print("\n\n size: ",len(strng));
    #request = zmq_socket.recv();
    zmq_socket.send(strng)
    print("sent\n")
    result = zmq_socket.recv();
    m = memoryview(result)
    print("\n\nreceived: ",len(result))
    f.close()
    zmq_socket.close()

producer()

server.cpp

#include <zmq.h>
#include <assert.h>
#include <vector>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fstream> // for writing files
#include <iostream>

typedef unsigned char uchar;

using namespace std;
vector<pair<int,int>> arr;

static std::string base64_encode(const std::string &in) {

    std::string out;

    int val = 0, valb = -6;
    for (uchar c : in) {
        val = (val << 8) + c;
        valb += 8;
        while (valb >= 0) {
            out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val>>valb)&0x3F]);
            valb -= 6;
        }
    }
    if (valb>-6) out.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val<<8)>>(valb+8))&0x3F]);
    while (out.size()%4) out.push_back('=');
    return out;
}

static string base64_decode(const string &in) {
    // Ref: https://stackoverflow.com/a/34571089/9625777
    string out;
    vector<int> T(256,-1);
    for (int i=0; i<64; i++)
        T["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i]] = i;

    int val=0, valb=-8;
    for (uchar c : in) {
        if (T[c] == -1) break;
        val = (val << 6) + T[c];
        valb += 6;
        if (valb >= 0) {
            out.push_back(char((val>>valb)&0xFF));
            valb -= 8;
        }
    }
    return out;
}

int main ()
{
    while(1)
    {
      // Create socket
      void *context = zmq_ctx_new ();
      void *responder = zmq_socket (context, ZMQ_REP);
      int rc = zmq_bind(responder, "tcp://*:5556");
      assert (rc == 0);
      //{
        // The zmq_connect() function returns zero if successful.
        // Otherwise it returns -1
      //}
      cout << "Got a connectopn\n";

      // Send Request
      //int rc = zmq_send(responder, "ABC", 3,ZMQ_DONTWAIT);
      //assert(rc != -1);

      // Receive data/Request
      char buffer [4194328];
      auto nbytes = zmq_recv (responder, buffer, 4194328, 0);assert (nbytes != -1);
      cout << "Got a request";
      // Generate data/results/ dummy data rn
      /*for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            arr.push_back(i);
        }
      }*/

      int a[2];a[0]=3;a[1]=5;
      // Send Result/Response
      rc = zmq_send(responder, a, sizeof(a),0);
      assert(rc != -1);

      // decode data
      auto decodedData = base64_decode(buffer);

      // write results to a file
      ofstream myFile("res.ppm");
      myFile << decodedData;
      myFile.close();

      // Close socket
      zmq_close (responder);
      zmq_ctx_destroy (context);
    }
    return 0;
}

Run as

gcc -Wall -g server.cpp -lzmq -lstdc++ -o s

Hope it helps 🤠.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.