When does imwrite() fails - c++

Does imwrite fails when the pixel values are of type CV_32FC1. I am trying to write an image in a jpg file but this is not working-:
make_response_mat(hr_lrt,response);
if (!response.data) // Checks input
{
cout << "Could not open or find the image" << std::endl;
return -1;
}
while (!imwrite("response.jpg", response))
{
cout << "Hari" << response.size() << "\n" << response.at<float>(456954, 4);
}
Here response has the pixel value of type float.

Only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with 'BGR' channel order). You can use Mat::convertTo to convert the image data type.
e.g.
Mat res;
response.convertTo(res, CV_8UC*)
* refer to image channel(1, 2, 3)

Related

converting from unsigned char to uchar4

i'm learning CUDA and i came across a course that is helping even though the code is very old and i'm having problems running it i'm trying to understand it, so he reads images using openCV imread which gives a Mat obj i guess but the data is saved as a uchar*
cv::Mat image = cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR);
but after i was stuck in converting uchar to uchar4 and i was reading the code from the teacher and he wrote .
cv::Mat image = cv::imread(filename.c_str(), CV_LOAD_IMAGE_COLOR);
if (image.empty()) {
std::cerr << "Couldn't open file: " << filename << std::endl;
exit(1);
}
cv::cvtColor(image, imageInputRGBA, CV_BGR2RGBA);
//allocate memory for the output
imageOutputRGBA.create(image.rows, image.cols, CV_8UC4);
//This shouldn't ever happen given the way the images are created
//at least based upon my limited understanding of OpenCV, but better to check
if (!imageInputRGBA.isContinuous() || !imageOutputRGBA.isContinuous()) {
std::cerr << "Images aren't continuous!! Exiting." << std::endl;
exit(1);
}
*h_inputImageRGBA = (uchar4 *)imageInputRGBA.ptr<unsigned char>(0);
*h_outputImageRGBA = (uchar4 *)imageOutputRGBA.ptr<unsigned char>(0);
are the two last lines the ones where he subtly converts from uchar to uchar4 ...
h_inputImageRGBA
h_outputImageRGBA
are both uchar4**
can somebody help me understand the code
here is the link to the source
function name : Preprocess

Machine Vision 8bit Bayer RGGB to RGB in Open CV

I am currently trying to convert an 8bit Raw color image to 8 bit RGB.
i get a channel error it expect the Bayer to be 1 channel.
i am using the following code.
if (convertBayerChckBox->Checked)
{
try{
cv::Mat temp(imgOriginal.rows, imgOriginal.cols, CV_8UC3);
imgOriginal.copyTo(temp);
cv::cvtColor(temp, imgOriginal, CV_BayerRG2BGR);
}
catch (const cv::Exception& ex)
{
std::cout << "EXCEPTION: " << ex.what() << std::endl;
errLog << "EXCEPTION: " << ex.what() << std::endl;
}
}
then i am getting the following exception:
EXCEPTION: ......\modules\imgproc\src\color.cpp:4194: error: (-215) scn == 1 && dcn == 3 in function cv::cvtColor
I am not sure how else to convert from Bayer to RGB
You need to set the data pointer of your input Mat to your destination pointer.
Here is a sample program to convert your bayer image to RGB. Here I've used buffer from a file. You can use your camera frame buffer. Hope this helps!
Mat mSource_Bayer(Size(m_IWidth,m_IHeight),CV_8UC1);
Mat mSource_Bgr(Size(m_IWidth,m_IHeight),CV_8UC3);
FILE *fp = NULL;
uchar *imagedata = NULL;
int framesize = m_IWidth * m_IHeight;
//Open raw Bayer image.
fp = fopen(FileName_S.c_str(), "rb");
//Memory allocation for bayer image data buffer.
imagedata = (uchar*) malloc (sizeof(uchar ) * framesize);
//Read image data and store in buffer.
fread(imagedata, sizeof(uchar ), framesize, fp);
mSource_Bayer.data= imagedata;
fclose(fp);
int Selection= m_BayerFormat.GetCurSel();
if(Selection==0)
cvtColor(mSource_Bayer, mSource_Bgr, CV_BayerBG2BGR);//Perform demosaicing process
else if(Selection==1)
cvtColor(mSource_Bayer, mSource_Bgr, CV_BayerGB2BGR);//Perform demosaicing process
else if(Selection==2)
cvtColor(mSource_Bayer, mSource_Bgr, CV_BayerRG2BGR);//Perform demosaicing process
else if(Selection==3)
cvtColor(mSource_Bayer, mSource_Bgr, CV_BayerGR2BGR);//Perform demosaicing process
imshow("mSource_Bgr",mSource_Bgr);
Also in order to perform BAYER to RGB conversion I would recommend to use function SimdBayerToBgr from Simd Library. It seems that it function is faster than its analogue from OpenCV (it uses AVX2 and AVX-512).

Loading Multiband tiff image into OpenCV C++

I tried loading a 8 band tiff image into OpenCV C++ but when I checked the dimensions of the image it gives me 3 bands of 1500 by 0 pixels. The image is 1500 by 1500 pixles with 8 bands. Is there a place I am going wrong? My code is as below:
int main(int argc, char** argv)
{
Mat Image, Normalized, ImageCopy;
if (argc != 2){
cout << "Define Image location" << endl;
}
else{
Image = imread(argv[1], CV_LOAD_IMAGE_UNCHANGED|CV_LOAD_IMAGE_ANYDEPTH);
}
cout <<" Number of bands \t: " << Image.channels() << "\t Image size\t"<< Image.size() << endl;
//Checking image validity
if(!Image.data){
cout << "Invalid image" <<endl;
return -1;
}
waitKey(0);
return 0;
}
I think you are out of luck, in TiffDecoder::readHeader() there is this:
m_type = CV_MAKETYPE(CV_8U, photometric > 1 ? 3 : 1);
That is, it is using the PHOTOMETRIC tag to set the number of channels to 1 or 3.
For your code to work, you would need it to set the number of channels based on the SAMPLESPERPIXEL tag, but is doesn't. The whole decoder seems to be peppered with the assumption that an image is either grayscale or RGB. Even an RGBA image has its alpha channel discarded.
You could use libtiff directly, using the OpenCV source in grfmt_tiff.cpp as a guide.

save image buffer as bitmap image

I have a image buffer stored as a linear array[640*480] of unsigned integer type, and I want to save this array as a bitmap image which can be viewed. I have captured an image from my camera and retrieved its image buffer from a GigE cable using in c++ code. So please tell me how to write an integer array of RGB values to Bitmap in C++ along with the header files required. I have stream buffer as
if (Result.Succeeded())
{
// Grabbing was successful, process image
cout << "Image #" << n << " acquired!" << endl;
cout << "Size: " << Result.GetSizeX() << " x "
<< Result.GetSizeY() << endl;
// Get the pointer to the image buffer
const unsigned int *pImageBuffer = (int *) Result.Buffer();
the pImagebuffer is the image Buffer and please ignore the Functions as they belong to a custom compiler. I just want to convert the RGB values to bitmap image and then save it
also the pImageBuffer is giving me the R=G=B as photo is mono chrome.
Save the pixel data together with a simple BMP-file header, appropriately initialized. See the format description here.

OpenCV2.1, map function? accessing each pixel?

I have a function that I would like to apply to each pixel in a YUN image (call it src). I would like the output to be saved to a separate image, call it (dst).
I know I can achieve this through pointer arithmetic and accessing the underlying matrix of the image. I was wondering if there was a easier way, say a predefined "map" function that allows me to map a function to all the pixels?
Thanks,
Since I don't know what a YUN image is, I'll assume you know how to convert RGB to that format.
I'm not aware of an easy way to do the map function you mentioned. Anyway, OpenCV has a few predefined functions to do image conversion, including
cvCvtColor(color_frame, gray_frame, CV_BGR2GRAY);
which you might want to take a closer look.
If you would like to do your own, you would need to access each pixel of the image individually, and this code shows you how to do it (the code below skips all kinds of error and return checks for the sake of simplicity):
// Loading src image
IplImage* src_img = cvLoadImage("input.png", CV_LOAD_IMAGE_UNCHANGED);
int width = src_img->width;
int height = src_img->height;
int bpp = src_img->nChannels;
// Temporary buffer to save the modified image
char* buff = new char[width * height * bpp];
// Loop to iterate over each pixel of the original img
for (int i=0; i < width*height*bpp; i+=bpp)
{
/* Perform pixel operation inside this loop */
if (!(i % (width*bpp))) // printing empty line for better readability
std::cout << std::endl;
std::cout << std::dec << "R:" << (int) src_img->imageData[i] <<
" G:" << (int) src_img->imageData[i+1] <<
" B:" << (int) src_img->imageData[i+2] << " ";
/* Let's say you wanted to do a lazy grayscale conversion */
char gray = (src_img->imageData[i] + src_img->imageData[i+1] + src_img->imageData[i+2]) / 3;
buff[i] = gray;
buff[i+1] = gray;
buff[i+2] = gray;
}
IplImage* dst_img = cvCreateImage(cvSize(width, height), src_img->depth, bpp);
dst_img->imageData = buff;
if (!cvSaveImage("output.png", dst_img))
{
std::cout << "ERROR: Failed cvSaveImage" << std::endl;
}
Basically, the code loads a RGB image from the hard disk and performs a grayscale conversion on each pixel of the image, saving it to a temporary buffer. Later, it will create another IplImage with the grayscale data and then it will save it to a file on the disk.