0

I want to encode a descriptor in order to send them later through a TCP socket. The descriptor is saved as a cv::Mat.

...
surf->detectWithDescriptors(gpu_img1, cuda::GpuMat(), keypoints1GPU, descriptors1GPU);
Mat dsc;
descriptors1GPU.download(dsc);
vector<int> compressionsparam;
vector<uchar> encoded;
compressionsparam.push_back(IMWRITE_EXR_TYPE_FLOAT);
compressionsparam.push_back(80);
imencode(".exr", dsc, encoded);
send(socket,(char*)&encoded[0],dsc.elemSize()*dsc.total(),0); 

on the other side I want to decode it

recv(socket,buf,bufsize,0);
Mat matImg = cv::imdecode(Mat(1, bufsize, CV_32F, buf), IMREAD_ANYDEPTH);

Unfortunately that doesn't work. I receive for matImg an [0x0] Mat.

  • Why are you setting size of data to send to `dsc.elemSize()*dsc.total()`? The payload is the contents of `encoded` vector, so the size should also be the size of `encoded`. | Similarly, why the `CV_32F` on the decoding side? You encoded into a vector of bytes, so why turn it into floats before decoding on the other side? – Dan Mašek Mar 16 '21 at 12:41
  • CV_32F because descriptors are floats with values between 0 and 1. – HtownUser Mar 16 '21 at 12:58
  • Sure, but you have to decode the EXR encoded data first. Right now you're reinterpreting the compressed EXR stream as a bunch of floats, which doesn't make any sense. And as the documentation of `imdecode` says, "If the buffer is too short or contains invalid data, the function returns an empty matrix" – Dan Mašek Mar 16 '21 at 15:51
  • Oh ok. Do you have any idea what to use instead of CV_32F? – HtownUser Mar 16 '21 at 16:13
  • I would read the data from the socket into a `std::vector`, and pass that vector directly to `imdecode`. | Another problem you will run into is that the receiver currently no way to know how much data to read. You should first send the size of `encoded`, for example as 4 bytes (32bit integer), and then send the payload. The receiver will then first read the 4 bytes representing size, allocate the buffer, and then read exactly `size` bytes into the buffer (it might require multiple reads). Once it has the full payload, it will pass it to `imdecode`. – Dan Mašek Mar 16 '21 at 16:27
  • Can't I just take the number of bytes I received by the command int bytes= recv(...)? – HtownUser Mar 16 '21 at 17:37
  • See https://stackoverflow.com/questions/10250666/socket-programming-issue-with-recv-receiving-partial-messages – Dan Mašek Mar 16 '21 at 17:58
  • Thank you very much :) – HtownUser Mar 16 '21 at 18:38

0 Answers0