Ask Your Question
-1

Why my array had different data?

asked 2017-11-30 03:42:10 -0500

zms gravatar image

updated 2017-11-30 04:42:03 -0500

kbarni gravatar image

I'm debugging my code to get the largest and 2nd largest contour area using this code, but my output is very weird for the arrayarea. I put the data into the array which i had declared as float. The output as under the code. Which part i got it wrong?

float arrayarea[5];

// iterate through each contour.
for( int i = 0; i< contours.size(); i++ )
{
    //  Find the area of contour
    double a=contourArea( contours[i],false); 
    arrayarea[i]=a; 
    cout<<" \narea="<<a<<endl; 

    if(a>largest_area)

    {
        largest_area=a;
        // Store the index of largest contour
        largest_contour_index=i;               

        // Find the bounding rectangle for biggest contour
        //bounding_rect=boundingRect(contours[i]);
    }

}

cout<<" \nlargest_area="<<largest_area<<endl;
cerr << "\nlargest_index=" <<largest_contour_index  << endl;
std::cout << "\narray_area= " <<arrayarea<< std::endl;
waitKey(0);

first = second = INT_MIN;
for (i = 0; i < arrayarea[i] ; i ++)
{
    /* If current element is smaller than first
       then update both first and second */
    if (arrayarea[i] > first)
    {
        second = first;
        first = arrayarea[i];
    }

    /* If arr[i] is in between first and 
       second then update second  */
    else if (arrayarea[i] > second && arrayarea[i] != first)
        second = arrayarea[i];
        second_largest_contour_index=i; 


}
if (second == INT_MIN)
    printf("There is no second largest element\n");
else
    printf("The second largest element is %dn", second);
    printf("The second largest index is %dn", second_largest_contour_index);


waitKey(0);

Result:

[259.084, 55.9251] point
[143.648, 32.9001] point
area=2512.5
area=1346.5
largest_area=2512
largest_index=0
**array_area= 00007FF7D7C12A88**
The second largest element is 1346
The second largest index is 2
edit retag flag offensive close merge delete

Comments

float arrayarea[5]; -- what if there are 7 contours ?

please use a vector, and push_back(), and damn, finally READ a book on c++ !

for (i = 0; i < arrayarea[i] ; i ++) -- broken, too.

berak gravatar imageberak ( 2017-11-30 04:30:02 -0500 )edit

for (i = 0; i < arrayarea[i] ; i ++)

This line is a complete nonsense...

kbarni gravatar imagekbarni ( 2017-11-30 04:42:47 -0500 )edit

should have been contours.size() , i guess

berak gravatar imageberak ( 2017-11-30 04:44:34 -0500 )edit

To find the second largest contour, I suggest to repeat the first for loop with the moditication if((a>second_largest_area)&&(a<largest_area)){second_largest_area=a;second_largest_contour_index=i;}

kbarni gravatar imagekbarni ( 2017-11-30 04:48:24 -0500 )edit

"Which part i got it wrong?" -- all of it, sorry.

berak gravatar imageberak ( 2017-11-30 04:52:35 -0500 )edit
1

You should get this book: The C++ Programming Language (4th Edition): http://www.stroustrup.com/4th.html

sjhalayka gravatar imagesjhalayka ( 2017-11-30 13:59:03 -0500 )edit

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-11-30 10:56:35 -0500

sjhalayka gravatar image

updated 2017-11-30 11:23:38 -0500

Here is a code that gets the largest and second largest contour areas (along with their centres). Perhaps you should start over. Like mentioned above, this code uses a sorted vector to store the contour areas and centres.

#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


// For later use with the sorted vector
class double_point2d_pair
{
public:
    double area;
    Point2d centre;
};

// For later use with the sorted vector
bool operator<(const double_point2d_pair &lhs, const double_point2d_pair &rhs)
{
    return lhs.area < rhs.area;
}


int main(void)
{
    Mat frame = imread("cards.png", CV_LOAD_IMAGE_GRAYSCALE);

    if (frame.empty())
    {
        cout << "Error loading image file" << endl;
        return -1;
    }

    threshold(frame, frame, 127, 255, THRESH_BINARY);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    findContours(frame, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    if (contours.size() < 2)
    {
        cout << "Error: must have 2 or more contours." << endl;

        return 0;
    }

    Mat output = Mat::zeros(frame.size(), CV_8UC3);

    for (int i = 0; i < contours.size(); i++)
        drawContours(output, contours, i, Scalar(0, 127, 255), 1, 8, hierarchy, 0, Point());

    vector<double> areas(contours.size());

    for (int i = 0; i < contours.size(); i++)
        areas[i] = contourArea(contours[i]);

    vector<Point2d> mass_centres(contours.size());

    for (int i = 0; i < contours.size(); i++)
    {
        const Moments mu = moments(contours[i], false);
        mass_centres[i] = Point2d(mu.m10 / mu.m00, mu.m01 / mu.m00);
    }

    vector<double_point2d_pair> dpp_vec;

    for (int i = 0; i < contours.size(); i++)
    {
        double_point2d_pair dpp;
        dpp.area = areas[i];
        dpp.centre = mass_centres[i];
        dpp_vec.push_back(dpp);
    }

    sort(dpp_vec.begin(), dpp_vec.end());

    Point2d first_centre = dpp_vec[dpp_vec.size() - 1].centre;
    double first_area = dpp_vec[dpp_vec.size() - 1].area;

    Point2d second_centre = dpp_vec[dpp_vec.size() - 2].centre;
    double second_area = dpp_vec[dpp_vec.size() - 2].area;

    cout << "Largest contour area: " << first_area << endl;
    cout << "Second contour area:  " << second_area << endl;

    return 0;
}
edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-11-30 03:42:10 -0500

Seen: 132 times

Last updated: Nov 30 '17