2

I am completely new to OpenCV and I'm trying to initialize two cv::Mat matrices from two different type of data. One is simple one-channel array of uint16_t gray values, second should hold RGB values from array of uint8_t values holding RGB 565 (each pixel occupy 2 uint8_t, so it's basically array of uint16_t). I'd like to have one single-chanell matrix, and one 3-chanell matrix (which will probably be converted to one chanelly sometime... but I'm not quite there yet.

function(uint16_t *oneChanell, int oneChanellWidth, int oneChanellHeight, uint8_t *rgb, int rgbWidth, int rgbHeight){
...
    cv::Mat M1 = cv::Mat(oneChanellHeight, oneChanellWidth, CV_16UC1, oneChanell);
    cv::Mat M2 = cv::Mat(rgbHeight, rgbWidth, CV_16UC3, rgb);
...
}

Now, I am aware that the second initialization is wrong. So that is one part of my question, how to best convert array of rgb565values to cv::Mat. In my understanding however, the first initialization should work. When tested with cv::imwrite(), the first yields just blank white picture of correct size, the second three partially overlapping silhouettes of the same (correct) picture, but not in RGB. Any advice would be appreciated.

Joel Bodenmann
  • 2,152
  • 2
  • 17
  • 44
kochy
  • 51
  • 9

1 Answers1

3

use cv::cvtColor to convert the mat M2 from RGB565 to RGB format.

...

cv::Mat M2 = cv::Mat(rgbHeight, rgbWidth, CV_16UC1, rgb);
// M2.depth()    = 2 # CV_16U
// M2.channels() = 1 # single channel with each element having 16 bit



//convert mat format from bgr565 to rgb
cv::Mat M2_rgb;
cv::cvtColor(M2, M2_rgb, COLOR_BGR5652RGB);

...
nayab
  • 2,332
  • 1
  • 20
  • 34
  • Thank you. I tried what you suggested, however in the last last line the app crashed and I get an `terminate called after throwing an instance of 'cv::Exception' what(): OpenCV(3.4.2) ...opencv3-3.4.2/modules/imgproc/src/color.hpp:253: error: (-215:Assertion failed) VScn::contains(scn) && VDcn::contains(dcn) && VDepth::contains(depth) in function 'CvtHelper'` – kochy Jun 08 '20 at 07:11
  • can you share the picture which you are trying to convert? – nayab Jun 08 '20 at 07:51
  • As I said, at the time of the conversion the picture is just array of uint16 values as read from FPGA. I can share what the OpenCV thinks the picture is, or save it in different format, maybe. What I found so far from debug-printing whatever I thought relevant is: M2.depth() = 2, M2.channels() = 1 - why 1, even when I try initialize with CV_16UC3 instead of CV_16UC1? – kochy Jun 08 '20 at 08:43
  • [edit] was printing sth else, sorry. It's as it is supposed to be, M2.channels() = 3 even with CV_16UC1. Which confuses me a bit, I thought the number is CV_typeUCnumberOfChannels. – kochy Jun 08 '20 at 09:11
  • can you check height and width of M2 matrix ? – nayab Jun 08 '20 at 10:42
  • That was rgbWidth rgbHeight (so OK) the whole time. I managed to get it running just now with these temporary fixes: the RGB656 values are fisrstly recalculated to BGR888 via for-cyclus (basically [ link] (https://stackoverflow.com/questions/8687739/opencv-with-rgb-16bits) ) and the one-Channel is dept-downscaled from 16 to 8bits as well. This seems to do the trick, however it is incredibly wastful :( – kochy Jun 08 '20 at 11:41
  • Can you try with cv::cvtColor(M2, M2_rgb, COLOR_BGR5652RGB, 3); It specifies that output mat must contain 3 channels. – nayab Jun 08 '20 at 12:39
  • OK, sorry for the long silence. I abandonened this attempt for now for other reasons. Solution described in my last comment was actually doing the trick though ;) – kochy Jun 22 '20 at 13:27