I would like to create a 16bit PNG-image with OpenCV by setting pixel values manually for noise generation. I tried the following:
cv::Mat img16(WINDOW_Y, WINDOW_X, CV_16UC3); // create 16 bit mat
float val, new_value;
float noise = 3.1343; // actually randomly generated by randomizer in (0..255)
for (int x = 0; x < WINDOW_X; x++) {
for (int y = 0; y < WINDOW_Y; y++) {
for (int i = 0; i < 3; i++) {
// get value from another CV_8UC3-mat
val = img.at<cv::Vec3b>(y,x)[i];
// add up noise and scale to 16bit
new_value = (val + noise)*255;
// avoid overflow at 2^16-1
if (new_value > 65535) {
new_value = 65535;
}
// set the value to 16bit mat
img16.at<cv::Vec3s>(y,x)[i] = (short) new_value;
}
}
}
// write to PNG file, since PNG supports 16 bit
cv::imwrite(file + ".png", img16);
What I get as output seems to be 16 bit:
$ identify output.png
output.png PNG 128x128 128x128+0+0 16-bit PseudoClass 65536c
But it shows up monotone grey (#808080) while I expect a heterogeneous image. What's wrong with it?
whenever you see yourself writing per-pixel loops in opencv, - hold on, and try to find something builtin instead.
Mat ocv=Mat(200,200,CV_16UC3); // as you can only save 16bit *unsigned* as png or tif
theRNG().fill(ocv,RNG::UNIFORM,0,65535);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.