Home > front end >  How to get cv2 Mat from C vector?
How to get cv2 Mat from C vector?

Time:01-19

I'm trying to get a sequence of image from float vector (N, H, W, C), where each channel have float values in the range 0..1.

What I'm trying to do for each image is:

  1. Convert float vector (HWC) to cv2 Mat type.
  2. Change RGB to BGR, and multiply 255 (to make values 0~255)
  3. Convert to uint8 type Mat.
  4. Get image. (imwrite)

So I tried this in this way below. This code doesn't make error. but isn't working. Please let me know how to do this!

vector<float> output(batch_size * orig_height * orig_width*3); //N H W C

for(int bat=0; bat < batch_size; bat  ){
    Mat result(width, height, CV_32F, (void*)(output.data()  bat*height*width*3));
    cv::cvtColor(result, result, cv::COLOR_RGB2BGR);
    result = result * 255.0;
    result.convertTo(result, CV_8U);
    
    cv::imwrite(file_name, result);
}

CodePudding user response:

There are several issues in your code:

  1. When you create cv::Mats, the element data type also includes the number of channels.
    This is mentioned in the documentation.
    Since you have 3 channel images, you need to change CV_32F to CV_32FC3 and CV_8U to CV_8UC3.

  2. The cv::Mat constructor that you use expects to get the dimensions as int rows, int cols (in that order). Therefore you need to swap the width and height you pass to the ctor.

  3. Color conversion RGB->BGR should be done after converting to a uint8 image.

Fixed version:

std::vector<float> output(batch_size * orig_height * orig_width * 3, 0.5); //N H W C

for (int bat = 0; bat < batch_size; bat  ) {
    cv::Mat result(orig_height, orig_width, CV_32FC3, (void*)(output.data()   bat * orig_height * orig_width * 3));
    result = result * 255.0;
    result.convertTo(result, CV_8UC3);
    cv::cvtColor(result, result, cv::COLOR_RGB2BGR);
    cv::imwrite(file_name, result);
}

A side note: better to avoid using namespace std; - see here: Why is "using namespace std;" considered bad practice?.

  • Related