I need to implement a function that receives a string containing the bytes of an image (received via boost socket connection) and converts the info into an OpenCV cv::Mat.
I also know the width and height of the image and its size in bytes. My function looks like this:
void createImageFromBytes(const std::string& name, std::pair<int,int> dimensions, const std::string& data)
{
int width,height;
width = dimensions.first;
height = dimensions.second;
//convert data to cv::Mat image
std::string filepng = DATA_PATH"/" + name +".png";
imwrite(filepng, image);
}
Which is the best method for doing this? Does OpenCV has a constructor for Mat from a string?
OpenCV Mat has a constructor from vector<byte>
, but this is not so intuitive. You need to convert from string to vector this way first:
std::vector<byte> vectordata(data.begin(),data.end());
Then you can create a cv::Mat from the vector:
cv::Mat data_mat(vectordata,true);
You also need to decode the image (check documentation for which types are allowed, png, jpg, depending on the OpenCV version)
cv::Mat image(cv::imdecode(data_mat,1)); //put 0 if you want greyscale
Now you can check if the resulting size of the image is the same as the one you sent:
cout<<"Height: " << image.rows <<" Width: "<<image.cols<<endl;
Easy to trip here as the image may have null characters and any c function handling string will see null as string end
Read the image
cv::Mat image;
image = cv::imread("../test/image.png", CV_LOAD_IMAGE_COLOR);
Convert to Bytes (this is just working code, not checked for leaks)
int dataSize = image.total() * image.elemSize();
//convert to bytes
std::vector<char> vec(dataSize);
memcpy(&vec[0], reinterpret_cast<char *>(image.data), dataSize);
std::string test2(vec.begin(), vec.end());
Test and see if conversion works
//test
cv::Mat data_mat(height,width,CV_8UC3,const_cast<char*>(test2.c_str()));
imwrite("out2.png", data_mat);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With