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:
- Convert float vector (HWC) to cv2
Mat
type. - Change RGB to BGR, and multiply 255 (to make values 0~255)
- Convert to uint8 type
Mat
. - 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:
When you create
cv::Mat
s, 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 changeCV_32F
toCV_32FC3
andCV_8U
toCV_8UC3
.The
cv::Mat
constructor that you use expects to get the dimensions asint rows, int cols
(in that order). Therefore you need to swap the width and height you pass to the ctor.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?.