Opencv Write an image with two channel - opencv

How write a cv::Mat which the type is CV_32FC2.
Is it possible to write the two channels in TIFF file ? or write each channel separately ?

if you can live with a (large!) textfile, use the FileStorage:
Mat m; // your CV_32FC2
FileStorage fs("my.yml",FileStorage::WRITE);
fs << "mat1" << m; // key, value store
fs.release(); // flush.
FileStorage fs1("my.yml",FileStorage::READ);
fs1["mat1"] >> m;

Related

How could I create an opencv matrix with separate rgb channel data

Suppose I have three char arrays r[1024], g[1024], b[1024] which contains the rgb data of one image. How could I create a cv::Mat with these channel data ?
Something like this:
// Create three single channel Mats
cv::Mat R(rows,cols,CV_8UC1,&r[0]);
cv::Mat G(rows,cols,CV_8UC1,&g[0]);
cv::Mat B(rows,cols,CV_8UC1,&b[0]);
Then merge into single image:
// Now merge the 3 individual channels into 3-band bad boy
auto channels = std::vector<cv::Mat>{B, G, R};
cv::Mat ThreeBandBoy;
cv::merge(channels, ThreeBandBoy);

Save vector <DMatch> in FileStorage

I want to write a vector<DMatch> in a file. I checked that it’s possible write some vector of classes like Keypoints, Mat, etc, but it’s not possible with it. Anyone knows how can I do it? The section of code is the following:
Mat ImDescriptors;
Vector<KeyPoints> ImKeypoints;
FileStorage fs(Name, cv::FileStorage::WRITE);
fs <<” C” << "{";
fs << "Descriptors" << ImDescriptors;
fs << "Keypoints" << ImKeypoints;
fs << “}”;
It works ok, but when I add to this code the element:
Vector<DMatch> good_matches;
fs << “GoodMatches” << good_matches;
I get the following error:
c:\opencv248\build\include\opencv2\core\operations.hpp(2713): error C2665: 'cv::write' : any of the 9 overloads could convert all the argument types.

OpenCV FaceRecognizer wrong shapes for given matrices

I'm trying to make a FisherFaceRecognizer's predict() method work, but I keep getting an error
Bad argument (Wrong shapes for given matrices. Was size(src) =
(1,108000), size(W) = (36000,1).) in subspaceProject, file
/tmp/opencv-DCb7/OpenCV-2.4.3/modules/contrib/src/lda.cpp, line 187
This is similar to a question that was asked at Wrong shapes for given matrices in OPENCV
but in my case, both source and training images are the same data type, full color.
My code is adapted from the tutorial at http://docs.opencv.org/modules/contrib/doc/facerec/facerec_tutorial.html#fisherfaces
however, my test image is larger than the training images, so I needed to work on a region of interest (ROI) of the right size.
Here's how I read the images and converted sizes. I cloned the ROI matrix because an
earlier error message told me the target matrix must be contiguous:
vector<Mat> images;
images.push_back( cvLoadImage( trainingList[i].c_str()));
IplImage* img;
img = cvLoadImage( imgName.c_str() );
// take ROI and clone into a new Mat
Mat testSample1(img, Rect( xLoc, yLoc, images[0].cols, images[0].rows));
Mat testSample = testSample1.clone();
// Create a FisherFaceRecognizer in OpenCV
Ptr<FaceRecognizer> FFR = createFisherFaceRecognizer(0,DBL_MAX);
model->train(images, labels);
cout << " check of data type testSample is " << testSample.type() << " images is " << images[0].type() << endl;
int predictedLabel = model->predict(testSample);
//
I get an exception message at the predict statement.
The cout statement tells me both matrices have type 16, yet somehow it still doesn't believe the matrices are the same size and data type...
You should ensure the shapes, not types
Try
cout << testSample.rows << testSample.cols << images[0].rows << images[0].cols ;
Also
ensure that both ,training img & test img, are in the same color space
If not, Try
cvtColor(testSample, testSample_inSameSpaceOfTraining, CV_BGR2***); // default opencv colors "BGR"
I found out that the FisherFaceRecognizer requires grayscale images, so I should have loaded both training and test images like this:
trainingImages.push_back( imread( trainingList[i].c_str(), CV_LOAD_IMAGE_GRAYSCALE));
and
Mat img;
img = imread( imgName.c_str(), CV_LOAD_IMAGE_GRAYSCALE );
(also reconciled the type of img for consistency). The grayscale-only requirement is documented in the OpenCV reference manual (pdf available online) but apparently not in any of the online tutorials or other documents for FisherFaceRecognizer.

get matrix of image in opencv

//Open the image
Mat img_rgb = imread("sudoku2.png", CV_LOAD_IMAGE_GRAYSCALE);
if (img_rgb.empty())
{
cout<<"Cannot open the image"<<endl;
return;
}
Mat img_bw = img_rgb > 128;
imwrite("image_bw.jpg", img_bw);
Now, I want to get all pixels of img_bw and save it into a matrix M (int[img_bw.rows][img_bw.cols]). How to do it in C++.
What format ?
The raw byte data in cv::Mat is available from the .ptr() function, ie img_bw.ptr().
Opencv also has an xml and json read and write functions for matrices, just by using the << operator - see opencv tutorial on xml and yaml i/o
EDIT: In c++ you can access pixels with the .at operator.
Use img_data.at<uchar>(x,y) for an unsigned char (CV_8U) pixel and img_data.at<float>(x,y) for a CV_32F image.

Can not convert with cvMerge,DFT

I am trying to make the dft of one single channeled image, and as cvDft is expecting complex values, I was adviced to merge the original image with another image with all 0's so this last one will be considered as imaginary part.
My problem comes when using cvmerge function,
Mat tmp = imread(filename,0);
if( tmp.empty() )
{cout << "Usage: dft <image_name>" << endl;
return -1;}
Mat Result(tmp.rows,tmp.cols,CV_64F,2);
Mat tmp1(tmp.rows,tmp.cols,CV_64F, 0);
Mat image(tmp.rows,tmp.cols,CV_64F,2);
cvMerge(tmp,tmp1,image);`
It gives me the next error: can not convert cvMAt to cvArr
Anyone could help me? thanks!
1) it seems like you're mixing up 2 different styles of opencv code
cv::Mat (- Mat) is a c++ class from the new version of opencv, cvMerge is a c function from the old version of opencv.
instead of using cvmerge use merge
2) you're trying to merge a matrix (tmp) of type CV_8U (probably) with a CV_64F
use convertTo to get tmp as CV_64F
3) why is your Result & image mats (the destination mat) are initializes to cv::Scalar(2)? i think you're misusing the constractor parameters. see here for more info.
4) you're image mat is a single channel mat and you wanted it as a 2 channel mat (as mentioned in the question), change the declaration to
Mat image(tmp.rows,tmp.cols,CV_64FC2);

Resources