3

So i was using PiCam to get video feed, but figured i could try to get the stream to C++ for processing.

Python code:

import time
import picamera
import picamera.array
import cv2

with picamera.PiCamera() as camera:
    camera.start_preview()
    time.sleep(2)
    with picamera.array.PiRGBArray(camera) as stream:
        camera.capture(stream, format='bgr')
        # At this point the image is available as stream.array
        image = stream.array

So, what to do in my .cpp file? I've been looking into boost::python, but their documentation sucks..

Any benefits to send numpy array instead of converting to Cv.Mat directly in the Python code and then call it from C++? Like this.

Any questions? All help appreciated!

Edit: Forgot to mention, have tried this without success. Found pyopencv_to() and pyopencv_from() now, but not sure how to use? Sorry, new to this. (Would have linked the pyopencv_ above, but not allowed to post more than two links.)

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
bac
  • 93
  • 1
  • 13
  • This? [Embedding Python in Another Application](https://docs.python.org/2/extending/embedding.html) – Cong Ma Nov 23 '15 at 18:14
  • Read that, but not sure how. Doesn't my Python code get me a numpy array? Needs cv::mat in C++ to process the image. – bac Nov 23 '15 at 18:17
  • If all you can get is a numpy array, I'd say just directly yank its underlying data buffer array and convert it. Possibly need to check certain Numpy flags, such as contiguity, owndata, etc, but I guess the camera library should guarantee that you don't get a "punched-hole" array owned by something else... ? – Cong Ma Nov 23 '15 at 18:26
  • Yeah, but it is possible to convert the numpy array to a Cv.Mat using cv.fromarray() as I linked above. But not sure if that is the best way to do this? I mean, I don't know if it is a slow process for example.. – bac Nov 23 '15 at 18:31
  • I wonder if it could be slower than grabbing the data from the camera. But anyway, I'm beginning to think that embedding the functionality equivalent to a few Python lines in a C/C++ app could overkill it ... why not just talk to the camera in your C++ app directly? – Cong Ma Nov 23 '15 at 19:08
  • Mainly because I don't know how to do that in the same (or a better) way than with the Python library picamera. I get a basically latency-free image with the code above, something that is very difficult to accomplish with PiCam in other ways. Any suggestions? – bac Nov 23 '15 at 19:23

1 Answers1

3

I solved it myself by piping. Thought I should share my solution:

C++ side:

union pipe
{
    uint8_t image[height] [width] [colors];
    uint8_t data [height * width * colors];
} raw;

int main(){
    // Reads in the raw data
    fread(&raw.image, 1, sizeof(raw.data), stdin);

    // Rebuild raw data to cv::Mat
    image = Mat(height, width, CV_8UC3, *raw.image);
}

Python side: (just added this at end of code above)

sys.stdout.buffer.write(image.tostring())

Running it by typing this in terminal:

python img.py | ./img

Works really well for me!

bac
  • 93
  • 1
  • 13