This is my third question on this topic, Instead of asking a new question in the comments I thought it would be better to start a new thread.
The full code can be found here:
C++ CvSeq Accessing arrays that are stored
And using the following code I can display the most recent vector that has been added to the RECT array(Note that this is placed inside of the for loop):
RECT& lastRect = detectBox->back();
std::cout << "Left: " << lastRect.left << std::endl;
std::cout << "Right: " << lastRect.right << std::endl;
std::cout << "Top: " << lastRect.top << std::endl;
std::cout << "Bottom: " << lastRect.bottom << std::endl;
What I am now trying to do is create a loop outside of this for loop that will display all of the vectors present in detectBox. I havent been able to determine how many vectors are actually present in the array, and therefore cannot loop through the vectors.
I tried using the following:
int i = 0;
while ((*detectBox)[i].left!=NULL)
{
std::cout << "Left: " << (*detectBox)[i].left << std::endl;
std::cout << "Right: " << (*detectBox)[i].right << std::endl;
std::cout << "Top: " << (*detectBox)[i].top << std::endl;
std::cout << "Bottom: " << (*detectBox)[i].bottom << std::endl;
i++;
}
And have also tried playing around with sizeof(*detectBox) , but only have an answer of 32 being returned...
Okay, you are using the wrong terms here. The variable detectBox is a vector (or rather a pointer to a vector it seems). There are three ways to iterate over it (I'll show them a little later). It is not an array, it is not an array of vectors. It is a pointer to a vector of RECT structures.
Now as for how to iterate over the vector. It is like you iterate over any vector.
The first way is to use the C way, by using indexes:
for (unsigned i = 0; i < detectBox->size(); ++i)
{
RECT rect = detectBox->at(i);
std::cout << "Left: " << rect.left << std::endl;
...
}
The second way is the traditional C++ way using iterators:
for (std::vector<RECT>::iterator i = detectBox->begin();
i != detectBox->end();
++i)
{
std::cout << "Left: " << i->left << std::endl;
...
}
The last way is to use range for loops introduced in the C++11 standard:
for (RECT const& rect : *detectBox)
{
std::cout << "Left: " << rect.left << std::endl;
...
}
The propblem with your attempt of the loop, with the condition (*detectBox)[i].left!=NULL is that the member variable left is not a pointer and that when you go out of bounds you are not guaranteed to have a "NULL" value (instead it will be indeterminate and will seem random).
Related
on a project I'm working on we are trying to test out the line_walk() function and work with the Line_face_circulator. Would there be a way to visualise the faces in the Line_face_circulator? The problem that I am having is figuring out how to extract information from the circulator. I've tried some of the methods below which didn't work but the documentation for the LFC is a bit difficult to maneuver around.
Delaunay::Line_face_circulator lfc = dt.line_walk(Point_2(13, 166), Point_2(42, 1761));
std::cout << "linewalk res" << std::endl;
Container container(lfc);
Iterator i = container.begin();
std::cout << typeid(i).name() << std::endl;
//std::cout << (container.begin()->vertex(0)) << std::endl;
std::cout << lfc.is_empty() << std::endl;
//std::cout << lfc->vertex(0) << std::endl;
//std::cout << *i->vertex(0)->point() << std::endl;
while (i != container.end()){
std::cout << *i << std::endl;
i++;
}
May I ask if there are particular methods to extract the faces or the vertices of the faces from the line_face_circulator?
Thank you!
Something like the following should work:
Delaunay::Line_face_circulator lfc = dt.line_walk(Point_2(13, 166), Point_2(42, 1761)), start=lfc;
std::vector<Delaunay::Face_handle> visited_faces;
if (lfc!=nullptr)
{
do{
visited_face.push_back(lfc);
} while(++lfc!=start);
}
Circulator doc is here.
#include <iostream>
#include <vector>
//#include <string>
struct Point {
Point(int _x, int _y) {
x = _x;
y = _y;
}
int x;
int y;
Point *parent;
};
int main() {
Point start(3, 4);
std::vector<Point> points;
points.push_back(start);
std::cout << points.back().x << "," << points.back().y << "\n";
Point one(4, 5);
one.parent = &points.at(0);
//std::cout << "testing: " << one.parent->x << "," << one.parent->y << "\n";
points.push_back(one);
std::cout << "One: " << points[1].x << "," << points[1].y << "\n";
std::cout << "One's parents: " << points[1].parent->x << "," << points[1].parent->y << "\n";
Point two(10, 3);
two.parent = &points.back();
points.push_back(two);
std::cout << "Two: " << points[2].x << "," << points[2].y << "\n";
std::cout << "Two's parent: " << points[2].parent->x << "," << points[2].parent->y << "\n";
Point three(12, 7);
three.parent = &points[1];
points.push_back(three);
std::cout << "Three: " << points[3].x << "," << points[3].y << "\n";
std::cout << "Three's parents: " << points[3].parent->x << "," << points[3].parent->y << "\n";
return 1;
}
I get the following results:
3,4
One: 4,5
One's parents: 0,0
Two: 10,3
Two's parent: 4,5
Three: 12,7
Three's parents: 4,5
Even though I made one's parent point to the vector's first element, the value ends up being 0,0. But, the other pointers point to the element that I want it to.
std::vector has a capacity. If you add elements beyond the vector's current capacity, vector may decide to allocate a larger block, move the existing elements, and then add the new elements. This must have happened in your case too.
You can bump the capacity of an existing vector with reserve. This will not yet add extra elements; it just prepares the vector.
While MSalters correctly explained the reason of the issue, and the possible solution for this particular case, the general practice is a bit different. Because vector may be reallocated at any moment, it's generally bad idea to store pointers to its elements.
You may use indices instead, which will be valid regardless of the re-allocation; or you may consider using different data structure, such as std::list.
Elements of std::list remain in the same location all their lifetime.
I am using a code that stores points into a Vector data type as follows:
RECT head;
head.left = pt1.x;
head.right = pt2.x;
head.top = pt1.y;
head.bottom = pt2.y;
detectBox->push_back(head);
This falls inside a function that has a for loop that stores multple instances of "head" into the detectBox. This function is delared like this:
void GetHeads(cv::Mat Img, vector<RECT>* detectBox)
Where Img is just a normal black and white image being fed in with the heads that have been extracted through other processes. My question now is how to I see the points that have been stored inside of detectBox? I would like to access them outside of the for loop to use for other things. When i try and print out the variables Ive only been able to have the addresses returned (0000004FA8F6F31821, etc)
Also, detectBox is a shade of grey in the code(not sure what that means).
Full code can be found in my other question related to the same function, here:
C++ CvSeq Accessing arrays that are stored
-----EDIT-----
Methods tried and associated errors/Outputs:
First:
std::cout << "Back : " << &detectBox->back << std::endl;
'&': illegal operation on bound member function expression
Second:
std::cout << "Back : " << detectBox->back << std::endl;
'std::vector>::back': non-standard syntax; use '&' to create a pointer to member
Third:(Note, No Error, but no useful information output)
std::cout << "Detect Box : " << detectBox << std::endl;
Detect Box : 00000062BF0FF488
Fourth:
std::cout << "Detect Box : " << &detectBox[1] << std::endl;
Detect Box : 000000CB75CFF108
First, detectBox is a pointer to the array so it needs to be dereferenced before trying to index into it.
std::cout << (*detectBox)[1]; // Outputs the 2nd RECT in the vector
// assuming an operator<< is implemented
// for RECT.
Including the address of '&' operator before it will print out the address of the 2nd RECT instance at index 1 which you do not need to do because the index operator gives you the reference.
std::cout << &(*detectBox)[1];
Without an operator<< for the RECT instance to output it to the stream you will need to access the members directly. The following should work:
std::cout << "Left: " << (*detectBox)[1].left;
std::cout << "Right: " << (*detectBox)[1].right;
std::cout << "Top: " << (*detectBox)[1].top;
std::cout << "Bottom: " << (*detectBox)[1].bottom;
This can be improved by saving off a reference to the RECT you are trying to get first and then using that:
RECT& secondRect = (*detectBox)[1];
std::cout << "Left: " << secondRect.left;
std::cout << "Right: " << secondRect.right;
std::cout << "Top: " << secondRect.top;
std::cout << "Bottom: " << secondRect.bottom;
Finally, I notice that you push the new RECT on the back of the Vector, but then you always output the 2nd RECT in the vector. Assuming you want to print the RECT you just added you could either output the head local variable or use the back() method on the vector as so:
RECT& lastRect = detectBox->back();
std::cout << "Left: " << lastRect.left;
std::cout << "Right: " << lastRect.right;
std::cout << "Top: " << lastRect.top;
std::cout << "Bottom: " << lastRect.bottom;
detectBox->push_back(head);
std::cout << &detectBox[1];
Unless you've got an overloaded operator "<<" for RECT (which you probably don't) it's going to try and match this to the best thing it can, which clearly isn't going to be what you want it to be.
Try something more like
std::cout << "L: " << &detectBox[1].left <<
"R: " << &detectBox[1].right << std::endl
I'd also be worried that you're using [1] when what you probably want is ->back()
I've been trying to use the PCA module from PCL in C++, but it's been a pain. At one point I want to switch the current indices of points that need to be operated on using the setIndices() function, but to actually make the update there is a private inherited function that one HAS to use called initCompute() or else it doesn't change them (or at least that is how I understood it). Never the less, the code as is, doesn't update the indices for some reason. This is the documentation for the class and everything works, but I have no idea how to make a workaround for this function which they intended to be used for these purposes:
http://docs.pointclouds.org/trunk/classpcl_1_1_p_c_a.html
How to deal with this? This is the error while compiling.
In function ‘void clustering(pcl::PointCloud<pcl::PointXYZ>::ConstPtr, pcl::PointCloud<pcl::PointXYZL>::Ptr, pcl::PointCloud<pcl::PointXYZRGB>::Ptr, pcl::PointCloud<pcl::PointXYZ>::Ptr, float)’:
/usr/include/pcl-1.7/pcl/common/impl/pca.hpp:64:1: error: ‘bool pcl::PCA<PointT>::initCompute() [with PointT = pcl::PointXYZ]’ is private
pcl::PCA<PointT>::initCompute ()
This is the code:
pcl::PCA<pcl::PointXYZ> cpca = new pcl::PCA<pcl::PointXYZ>;
cpca.setInputCloud(input);
std::cout << "We're now performing the cluster elimination!" << endl;
Eigen::Matrix3f pca_matrix; //serves to hold the eigenvectors, and never got updated...hence the couts for checking.
for (int i = 0; i < nclusters; ++i, n++)
{
// the next two lines had to be done so, I found that in a forum, the library just behaves a bit strange.
pcl::PointIndices::Ptr pi_ptr(new pcl::PointIndices);
pi_ptr->indices = cluster_indices[i].indices;
cout << "Current size is: " << pi_ptr->indices.size() << endl;//this shows different sizes on every turn
//now can use pi_ptr
cpca.setIndices(pi_ptr);
pca_matrix = cpca.getEigenVectors();
// but here I get the same vectors every time
std::cout << "vector " << n << " " << pca_matrix(0,0) << " " << pca_matrix(0,1) << " " << pca_matrix(0,2) << endl;
std::cout << "vector " << n << " " << pca_matrix(1,0) << " " << pca_matrix(1,1) << " " << pca_matrix(1,2) << endl;
std::cout << "vector " << n << " " << pca_matrix(2,0) << " " << pca_matrix(2,1) << " " << pca_matrix(2,2) << endl;
Anyway, I got annoyed after a while and did the following.
I created a pca object at the beginning of a for loop using a pointer, and then deleted it at the end of the loop with delete. It is some allocing and deallocing going on there which is most likely not optimal, but it did the trick. The PCA object itself was only 144 bytes large, cause it mostly uses pointers to address necessary elements.
As stated in the title, when I pass a vector to another function, its capacity becomes equal to its size at the time of the function call.
void sizeCheck(std::vector<int> test)
{
std::cout << "Size: " << test.size() << std::endl;
std::cout << "Capacity: " << test.capacity() << std::endl;
std::cout << std::endl;
}
int main()
{
std::vector<int> test;
for(int i = 0; i < 10; ++i)
{
test.push_back(i);
std::cout << "Size : " << test.size() << std::endl;
std::cout << "Capacity: " << test.capacity() << std::endl;
std::cout << std::endl;
}
test.resize(0);
for(int i = 0; i < 10; ++i)
{
test.push_back(i);
sizeCheck(test);
}
}
The above code's first series of outputs show that the vector's capacity increases how one could normally expect; however, the second series of outputs is indicating that the size is always equal to the capacity. I'm assuming this means the capacity is being pushed back by one each time.
I understand that normally it would be best to just pass by reference (const or not), but isn't there any circumstance where I would need to pass a copy of a vector and manipulate it in some way without affecting my original data? In this case, passing by value would be inefficient if every time I use push_back, it has to relocate the vector.
Something like
v2.assign(v1.first(), v1.end());
func(v2);
would work, assuming func() takes a vector by reference, but it seems strange to me that I'm allowed to pass a vector to a function by value if there are zero cases where it's the best option.
In C++ you have the choice of passing by value, by reference, or by pointer, depending on the situation.
You are passing your vector by value into the function. A copy of the vector is being made. The vector copy constructor makes the capacity of the new vector the same as the size of the vector being copied from.
If you pass your vector by reference or by pointer instead, no copy is made, you output the size/capacity of the original vector instead:
void sizeCheck(std::vector<int> &test)
{
std::cout << "Size: " << test.size() << std::endl;
std::cout << "Capacity: " << test.capacity() << std::endl;
std::cout << std::endl;
}
void sizeCheck(std::vector<int> *test)
{
std::cout << "Size: " << test->size() << std::endl;
std::cout << "Capacity: " << test->capacity() << std::endl;
std::cout << std::endl;
}