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()
Related
I'm currently having an issue with a function call of get_set() for a doubly-linked list class I am making. The function returns a vector of all the elements within the list from position_from to position_to. For the tests I am sending
dll_UT->get_set( dll_UT->size()/2+1 , dll_UT->size()-1)
however, the value of dll_UT->size() somehow doubles within the call. When called directly before in my COUT statement, it shows the correct value of 100, but when inside the function this turns to 200. I've left console logs below as well as screenshots of the test.cpp and doubly_linked_list.cpp.
Any help on this is greatly appreciated as I've never seen this type of behavior before and would like to understand why such a thing is occuring.
Doubly_linked_list get_set(unsigned position_from, unsigned_position to){
std::cout << "\n\t__NEW TEST__\nSize of size/2+1 = " << this->size()/2+1 << "\nSize of size()-1 = " << this->size()-1 << std::endl;
std::cout << "position_from = " << position_from << "\nposition_to = " << position_to << std::endl;
//value of position_from == 200, should be == this->size()/2+1 which = 100
std::vector<int> temp;
temp.reserve(position_to - position_from);
while(position_from < position_to){
temp.push_back( this->get_data(position_from) );
position_from++;
}
temp.push_back(this->get_data(position_to));
std::cout << "Size of position_from = " << position_from << "\nSize of position_to = " << position_to << "\n\t__END TEST__" << std::endl;
return temp;```
}
Test.cpp {
```std::cout << "\nTEST.cpp::: dll_UT-size() = " << dll_UT->size() <<
"\nTEST.cpp::: dll_UT-size()/2+1 = " << dll_UT->size()/2+1 << std::endl;
//assuring dll_UT->size()/2+1 = 100
std::cout << "\nTEST.cpp::: expected_set.size() = " << expected_set.size() <<
"\nTEST.cpp::: expected_set.begin()+expected_set.size()/2+1 = " << expected_set.size()/2+1 << std::endl;
ASSERT_EQ(std::vector<int> (expected_set.begin()+expected_set.size()/2+1,expected_set.end()),
dll_UT->get_set( dll_UT->size()/2+1 , dll_UT->size()-1));//second half of data
// ^first operand doubled, ^second operand fine
//actually value sent is 200. dll_UT->size() is somehow doubling and equaling 400 but only for first operand of get_set(unsigned, unsigned)
Updated Caputre
I'm working on a project that needs some buttons done with SFML. We're using version 2.4.2. I've managed to accomplish everything but the text alignment, and I'm very confused as to what the problem is.
In order to set the text's alignment, I know that I must set its origin and position properly. Since people may change a button's text, I decided to put the alignment feature into the setString function.
For debugging purposes, I've added a couple of console outputs to show me some of my data. Here's what the function looks like:
void rgf::Button::setString(const sf::String & str)
{
text.setString(str);
std::cout << "Original Origin: " << text.getOrigin().x << ", " << text.getOrigin().y << std::endl;
std::cout << "Original Position: " << text.getPosition().x << ", " << text.getPosition().y << std::endl;
std::cout << "Original LocalBounds: " << text.getLocalBounds().width << ", " << text.getLocalBounds().height << std::endl;
auto textRect = text.getLocalBounds();
auto btnRect = body.getLocalBounds();
text.setOrigin(textRect.left + textRect.width / 2, textRect.height + textRect.height / 2);
text.setPosition(btnRect.left + btnRect.width / 2, btnRect.top + btnRect.height / 2);
std::cout << "New Origin: " << text.getOrigin().x << ", " << text.getOrigin().y << std::endl;
std::cout << "New Position: " << text.getPosition().x << ", " << text.getPosition().y << std::endl;
std::cout << "New LocalBounds: " << text.getLocalBounds().width << ", " << text.getLocalBounds().height << std::endl;
}
The console outputs all positons, new and old, as 0 (except new position which returns the expected coords of 50 and 25).
According to what I've found online, as soon as I set the text's string, my text object's localBounds should change. This doesn't happen unless the text has been drawn once already in an sf::RenderWindow.
I made it so that the button's function would set the string to another value, this had the effect of setting the origin and position properly. Setting the string's value in a container's constructor (before it is drawn) doesn't set the origin properly.
I've spent a day on this and I don't understand what I'm missing. Any help would be greatly appreciated.
The setFont() function was called after the setString() function, which meant that the localBounds were still 0, since there was no font to indicate a width or a height.
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).
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;
}