how to convert cv::Mat::data into a std::vector ?

asked 2018-03-23 17:03:04 -0500

Hello

I've been struggling with this problem for a few days. I have a jpeg image stored in a cv::Mat object

it was created thusly:

jpg = cv::Mat(h, w, CV_8UC3, (uint8_t *) image.GetBuffer());

I can write to a file using cv::imwrite so I know the jpg object contains valid data.

I am now attempting to extract/convert/massage the cv::Mat::data into a form that will be compatible with the Node.js Nan::NewBuffer function:

Nan::MaybeLocal<v8::Object> Nan::NewBuffer(char* data, uint32_t size)

My strategy has been to make an intermediate std:vector object but am having no luck. Something along the lines of:

std::vector<unsigned char>  * pImg;

if(jpg.isContinuous())
{
    pImg->assign((uchar*)jpg.datastart, (uchar*)jpg.dataend);
    pImg->assign(jpg.begin<uchar>(),jpg.end<uchar>());
    // and lots of variation on the above
}

then use it to contstruct the NewBuffer:

Local<Object> jpegData =
            NewBuffer((char*)pImg->data(),
            pImg->size(),
            buffer_delete_callback,
            pImg).ToLocalChecked();

Any advice would be greatly appreciated.

In general I can get the code to compile, but it appears to crash silently during the vector->assign operation.

Thanks

edit retag flag offensive close merge delete

Comments

there are 2 problems here:

jpg = cv::Mat(h, w, CV_8UC3, (uint8_t *) image.GetBuffer()); <-- this is taking a shallow copy only of whatever image.GetBuffer() points to. never let it go out of scope ! (or use a clone())

std::vector<unsigned char> * pImg; <-- that's only an uninitialized pointer, you cannot "assign" anything.. ( missing new ? why a pointer, even ?)

berak gravatar imageberak ( 2018-03-23 19:54:50 -0500 )edit

why the vector, even ? seems entirely redundant. what about:

Nan::MaybeLocal<v8::Object> Nan::NewBuffer buffer(mat.data, mat.total() * mat.elemSize());

??

berak gravatar imageberak ( 2018-03-23 20:31:00 -0500 )edit

Thank you for the questions and suggestions. I'm not a programer by training so I'm struggling through this project. I don't fully understand "shallow copy" and other c++ stuff, but so you have a bit more context, my goal is to interface a Basler high speed USB3 camera with a node,js webapp that will serve images on request. I have written the node.js portion of the code and it can successfully send premade jpeg images that reside on disk. My C++ code is also successful in grabbing an image from the camera, using opencv to convert it to a jpeg, and writing it to disk. However, I'd like to avoid writing a file to disk and then reading it back into memory to send to the client. Therefore, I'm attempting to write a native C++ extension for node.js. The Nan::NewBuffer is ...(more)

the dood gravatar imagethe dood ( 2018-03-27 16:28:34 -0500 )edit

send buffer stuff from C++ land to node land. The documentation states that I need to pass the buffer data in as a char* std::vector. That's why I've been trying to convert from Mat::data into Nan::NewBuffer as char*

here is the "Signature" of the Nan::NewBuffer

Nan::MaybeLocal<v8::Object> Nan::NewBuffer(uint32_t size)
Nan::MaybeLocal<v8::Object> Nan::NewBuffer(char* data, uint32_t size)
Nan::MaybeLocal<v8::Object> Nan::NewBuffer(char *data,
                                       size_t length,
                                       Nan::FreeCallback callback,
                                       void *hint)
the dood gravatar imagethe dood ( 2018-03-27 16:31:57 -0500 )edit