Hey
Fairly new here, going over the docs currently. But before I start climbing the wall... can any1 clear up some things for me?
- I have a HDR 32 bit per channel, 3 channels. As far as I can tell that is "CV_32FC3" ?
- How can I print-text stuff like mat.type() ? I get a number, but I don't know where to look at to figure out what it is.
- How can I control gamma, is there dedicated function or do I just get bits and run a loop function over the array? - feels a bit slow if I have to do it on cpu... does openCV offer any openGL/etc option for it?
I've created a Mat using this command > cv::Mat img(FreeImage_GetHeight(hdrImage), FreeImage_GetWidth(hdrImage), CV_32FC4, FreeImage_GetBits(hdrImage), FreeImage_GetPitch(hdrImage));
Now when I do qDebug() << "Type type ? : " << CV_32FC4;
I get a number 29, but when I do qDebug()<<img.type()
I get something like 21. - what did I miss understand here?
- I messed up conversion cvtColor(img, img, COLOR_BGRA2RGBA);
I'm now getting proper type!
And then when trying to do img.convertTo(img, CV_8SC4/CV_8UC4);
I get lots of bad stuff/crashes. I want to convert here from 32 bit per channel image rgba to 8 bit or uchar per channel. How can I accomplish it properly?
Am I even calling the things I want to do correctly?
So far thats it, I'll update the topic as I solve the issues. So far its exciting stuff :- )
TIA
Got stuck with more conversions.. I have the given CV_32FC4 image that come from freeImage that is EXR. I then want to convert it to 8 bit for QImage but all I get is zip. I tried convertTo(CV8/16/U/S/C4)
etc/etc but no luck.
raw9 = QImage((const uchar *) img.data, img.cols, img.rows, img.step, QImage::Format_RGBA8888); // no luck
raw9 = QImage((const uchar *) img.data, img.cols, img.rows, img.step, QImage::Format_RGBA64); // no luck
Any helps would be amazing, I'm getting lost with these bits/bytes/channels... :- C
I had some luck via accessing img.data directly and converting to what I need... like :
auto imgData = reinterpret_cast<float *>(img.data);
for (int a = 0; a < data.size(); a = a + img.channels()) {
data[a] = imgData[a] * 255;
data[a + 1] = imgData[a + 1] * 255;
data[a + 2] = imgData[a + 2] * 255;
data[a + 3] = imgData[a + 3] * 255;
}
But I get some bad red/yellow pixels > Bad Pixels - How to bite/solve it?
Above issues got solved magically by img.convertTo(img,CV_8U,255) < the 255 "scale factor" does something magical! Thank you barek for help!
Ok moving on... we solved the bit depth conversion... Now.. gamma! :D
As far as I can tell this "works"
cv::pow(img, 1.0f / 2.2f, img);
img.convertTo(img, CV_8U, 255);
But as I have RGBA the alpha gets also gamma corrected which is not desired...
Does it mean that then correct workflow is this ? >
Mat1f alpha;
extractChannel(img, alpha, 3); // get alpha?
cvtColor(img, img, COLOR_RGBA2RGB);
cv::pow(img, 1.0f / 2.2f, img); // gamma correct
img = img*2; // exposure change?
Mat1f rgb[3];
split(img,rgb);
Mat1f rgba[4]= {rgb[0],rgb[1],rgb[2],alpha};
merge(rgba,4,img); // put alpha back in ?
To properly gamma correct image & change exposure without changing alpha?
TIA! :- )
Issue above solved - thanks Berak!
Another question... saving to exr - I take this would be compressed format ?
std::vector<uchar> buff;//buffer for coding
std::vector<int> param(2);
param[0] = cv::IMWRITE_EXR_TYPE;
param[1] = cv::IMWRITE_EXR_TYPE_HALF;
cv::imencode(".exr", mImage, buff, param);
stream<<buff;
I want to serialize that into my own object wrapper and then deserialize latter. But still, have the benefit of exr compression/lossless/etc. Would this produce that result?
TIA!