I am using OpenCV 2.4.3 to create and reshape a matrix like this:
cv::Mat testMat = cv::Mat::zeros ( 500, 200, CV_8UC3 );
std::cout << "size of testMat: " << testMat.rows << " x " << testMat.cols << std::endl;
testMat.reshape ( 0, 1 );
std::cout << " size of reshaped testMat: " << testMat.rows << " x " << testMat.cols << std::endl;
Then from the output, I see there is no change for the reshaped testMat. I used "reshape" many times in older version of OpenCV, but with this new version, I couldn't see any changes. Is this a bug? Or am I using it incorrectly here?
reshape returns a new Mat header
cv::Mat testMat = cv::Mat::zeros ( 500, 200, CV_8UC3 );
std::cout << "size of testMat: " << testMat.rows << " x " << testMat.cols << std::endl;
cv::Mat result = testMat.reshape ( 0, 1 );
std::cout << " size of original testMat: " << testMat.rows << " x " << testMat.cols << std::endl;
std::cout << " size of reshaped testMat: " << result.rows << " x " << result.cols << std::endl;
Related
I would like to load some pictures from files to Mat-objects (OpenCV) and want to store them in a vector. Further OpenCV calls/objects need vectors (like: AlignMTB) as arguments. But after filling the vector with Mat-objects I'm only able to get access to the last element I added to the vector.
In the example I first load the images to an intermediary Mat-object and convert it to CV_32FC3. Then I print out the BGR-values of one sample-pixel. The print out is:
File 0: 13 13 157
File 1: 17 20 159
File 2: 8 8 152
Then I add this intermediary Mat to the Mat-vector images.
Afterwards I'm trying to print out the sample-pixel values of the first and second image but always I get the values of the third image:
File 0: 8 8 152
File 1: 8 8 152
What I'm making wrong during accessing the vector data?
I was trying it with this routine:
vector<Mat> images;
images.reserve(3);
Mat img;
for (int i = 0; i < 3; i++)
{
imread("F:/Test/file" + to_string(i) + ".jpg").convertTo(img, CV_32FC3);
cout << "File " << i << ": " << img.at<Vec3f>(800, 800)[0] << " " << img.at<Vec3f>(800, 800)[1] << " " << img.at<Vec3f>(800, 800)[2] << endl;
images.push_back(img);
}
cout << endl;
cout << "File " << 0 << ": " << images[0].at<Vec3f>(800, 800)[0] << " " << images[0].at<Vec3f>(800, 800)[1] << " " << images[0].at<Vec3f>(800, 800)[2] << endl;
cout << "File " << 1 << ": " << images[1].at<Vec3f>(800, 800)[0] << " " << images[1].at<Vec3f>(800, 800)[1] << " " << images[1].at<Vec3f>(800, 800)[2] << endl;
The problem is not vector::push_back, because it will construct a copy of the given element. However, the problem is the copy constructor of Mat which does not copy the associated data:
No data is copied by these constructors. Instead, the header pointing to m data or its sub-array is constructed and associated with it.
What you can do to solve the problem is either an explicit Mat::clone operation which also copies the data or to move the matrix declaration in the for loop.
vector<Mat> images;
images.reserve(3);
Mat img;
for (int i = 0; i < 3; i++)
{
imread("F:/Test/file" + to_string(i) + ".jpg").convertTo(img, CV_32FC3);
cout << "File " << i << ": " << img.at<Vec3f>(800, 800)[0] << " " << img.at<Vec3f>(800, 800)[1] << " " << img.at<Vec3f>(800, 800)[2] << endl;
images.push_back(img.clone());
}
cout << endl;
cout << "File " << 0 << ": " << images[0].at<Vec3f>(800, 800)[0] << " " << images[0].at<Vec3f>(800, 800)[1] << " " << images[0].at<Vec3f>(800, 800)[2] << endl;
cout << "File " << 1 << ": " << images[1].at<Vec3f>(800, 800)[0] << " " << images[1].at<Vec3f>(800, 800)[1] << " " << images[1].at<Vec3f>(800, 800)[2] << endl;
I am working on the latest revision of the C++ programming language (think it's 5) and run into a problem with g++ version 5.2.
My code is a variation of Small_size template from chap 24.
#include <iostream>
template<int N>
bool is_small ()
{
std::cerr << sizeof(N) << std::endl;
std::cerr << N << std::endl;
return N <= 255;
}
bool ism (int i_n)
{
return i_n <= 255;
}
int main ()
{
std::cout << "hallo welt" << std::endl;
std::cout << 0 << " " << is_small<0> << std::endl;
std::cout << 255 << " " <<is_small<255> << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000> << std::endl;
std::cout << 256 << " " << is_small<256> << std::endl;
std::cout << 256 << " " << ism(256) << std::endl;
std::cout << 256 << " " << (256 <= 255) << std::endl;
}
When I compile it, it's ok. But when I run the thing, it simply seems to be broken.
[cpp11#hydra src]$ cat ~/bin/g14
#!/bin/bash
g++-52 -std=c++14 "${1}.C" -L$LIBPATH -o "$1"
[cpp11#hydra src]$ g14 konzept_small
[cpp11#hydra src]$ ./konzept_small
hallo welt
0 1
255 1
-4100000000 1
256 1 //1
256 0
256 0
[cpp11#hydra src]$
My problem is that:
the result for 256 and higher is wrong. See comment //1
there is no output of the template code on cerr
I started with a version without the cerr, but got only the wrong template result.
I removed a constexpr from the template, but no change.
So I added as last step the cerr to see whats wrong.
Any ideas?
You are not calling is_small<N>, but just printing out its address. You need to change your code to
std::cout << 0 << " " << is_small<0>() << std::endl;
std::cout << 255 << " " <<is_small<255>() << std::endl;
std::cout << -4100000000 << " " << is_small<-4100000000>() << std::endl;
std::cout << 256 << " " << is_small<256>() << std::endl;
Note the added (). Not sure why you are getting the output you are though, are you sure you are running the same code you posted?
is_small is a function you should add the parenthesis :
change
std::cout << 0 << " " << is_small<0> << std::endl;
to this
std::cout << 0 << " " << is_small<0>() << std::endl;
It worked fine for me with this change
While copying one Mat into the region of interest of another I came accross an error I've never seen before. Googling it didn't turn up many results and none of them seems to be relevant.
I have included a screenshot of the error as well as some properties of the Mat's.
This is the code:
std::cout << "size height,width: " << size.height << ", " << size.width << std::endl;
cv::Mat tempResult(size.width, size.height, result.type());
std::cout << "tempResult cols,rows: " << tempResult.cols << ", " << tempResult.rows << std::endl;
std::cout << "tempResult type: " << tempResult.type() << std::endl;
std::cout << "tempResult channels: " << tempResult.channels() << std::endl;
std::cout << "result cols,rows: " << result.cols << ", " << result.rows << std::endl;
std::cout << "result type: " << result.type() << std::endl;
std::cout << "result channels: " << result.channels() << std::endl;
cv::Rect rect(0, 0, result.cols-1, result.rows-1);
std::cout << "rect size: " << rect.size() << std::endl;
result.copyTo(tempResult(rect));
The cv::Mat::operator(cv::Rect roi) method extract a submatrix with the same size of the cv::Rect roi.
But you defined a cv::Rect object with 1 row and 1 col missing, so the output matrix returned by tempResult(rect) is smaller the the matrix result. cv::Mat::CopyTo launch an exception because the input to copy is smaller than the output argument.
To fix this :
cv::Rect rect(0, 0, result.cols, result.rows);
For cv::Rect, its format is (x, y, width, height), not (x1, y1, x2, y2). That's why, in my opinion, you get the error.
If yes, you will need to change rect to:
cv::Rect rect(0, 0, result.cols, result.rows);
If not (i.e. you really means rect(x, y, width-1, height-1)), you can do like this:
result(rect).copyTo(tempResult(rect));
I am using HOG descriptor for feature extraction. I am using visual studio 2012 and opencv 2.4.9 version. I am getting run time error in hog.compute function.
int main()
{
Mat img_raw = imread("p1.jpg", 1); // load as color image.
Mat img;
cvtColor(img_raw, img, CV_RGB2GRAY);
HOGDescriptor hog;
vector<float> descriptor;
vector<Point>locations;
hog.compute(img, descriptor,Size(32,32),Size(0,0),locations);
cout << "HOG descriptor size is " << hog.getDescriptorSize() << endl;
cout << "img dimensions: " << img.cols << " width x " << img.rows << "height" << endl;
cout << "Found " << descriptor.size() << " descriptor values" << endl;
cout << "Nr of locations specified : " << locations.size() << endl;
return 0;
}
I'm a beginner to C++ and I'm having a problem with this code, which is supposed to display the scores during the Superbowl final:
#include <iostream>
enum POINTS { EXTRA_POINT = 1, SAFETY = 2, FIELD_GOAL = 3, TOUCHDOWN =6 };
unsigned short giantsScore = 0, patriotsScore = 0;
int main()
{
std::cout << " Giants: " << giantsScore << "\n";
std::cout << " Patriots: " << patriotsScore << "\n\n";
std::cout << " Giants: " << giantsScore = giantsScore + SAFETY << "\n";
std::cout << " Patriots: " << patriotsScore << "\n\n";
std::cout << " Giants: " << giantsScore = giantsScore + TOUCHDOWN + EXTRA_POINT << "\n";
std::cout << " Patriots: " << patriotsScore << "\n\n";
std::cout << " Giants: " << giantsScore << "\n";
std::cout << " Patriots: " << patriotsScore = patriotsScore + FIELD_GOAL << "\n\n";
std::cout << " Giants: " << giantsScore << "\n";
std::cout << " Patriots: " << patriotsScore = patriotsScore + TOUCHDOWN + EXTRA_POINT << "\n\n";
std::cout << " Giants: " << giantsScore << "\n";
std::cout << " Patriots: " << patriotsScore = patriotsScore + TOUCHDOWN + EXTRA_POINT << "\n\n";
std::cout << " Giants: " << giantsScore = giantsScore + FIELD_GOAL << "\n";
std::cout << " Patriots: " << patriotsScore << "\n\n";
std::cout << " Giants: " << giantsScore = giantsScore + FIELD_GOAL << "\n";
std::cout << " Patriots: " << patriotsScore << "\n\n";
std::cout << " Giants: " << giantsScore << "\n";
std::cout << " Patriots: " << patriotsScore = patriotsScore + FIELD_GOAL + EXTRA_POINT << "\n\n";
return 0;
}
Ignoring that this is quite inelegant, when I run this through the compiler, G++, I get the error message
error: invalid operands of types 'int' and 'const char [2]' to binary 'operator<<'
If I remove the constants and add them in before each std::cout, then it runs fine. I just wanted to know why I can't add the constants during each output line?
Your error message states: int << char, which of course is an odd operation.
It is because of operator priorities.
Each operator has a priority meaning it will evaluate before or after the other operators are evaluated.
+ evaluates before =
and << should be evaluated after = had cout<<"stuff" been its original purpose.
<< is originally the bit-shift operator (still is), so that is why you are experiencing this odd behaviour. Add parentheses and you'll be good.
Check http://cs.smu.ca/~porter/csc/ref/cpp_operators.html for an overview of the priority rules of operators. When you write this:
std::cout << " Patriots: " << patriotsScore = patriotsScore + FIELD_GOAL + EXTRA_POINT << "\n\n";
Then according to the priority rules, the + operator will be executed first, giving you this:
std::cout << " Patriots: " << patriotsScore = result << "\n\n";
Then the << operator is executed, which means also `result << "\n\n". But this operator is not defined between int and char[2].
To solve your problem, put parenthesis around the assignment operation, like this:
std::cout << " Patriots: " << (patriotsScore = patriotsScore + FIELD_GOAL + EXTRA_POINT) << "\n\n";