1 | initial version |
Here is a code that gets the largest and second largest contour areas (along with their centres). Perhaps you should start over. This code uses a multiset to sort the areas. Like mentioned above, you could also use a vector and then just use the sort function.
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <map>
#include <set>
using namespace std;
// For later use with multiset
class double_point2d_pair
{
public:
double area;
Point2d centre;
};
// For later use with multiset
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);
Mat flt_frame(frame.rows, frame.cols, CV_32F);
for (int j = 0; j < frame.rows; j++)
for (int i = 0; i < frame.cols; i++)
flt_frame.at<float>(j, i) = frame.at<unsigned char>(j, i) / 255.0f;
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(flt_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);
}
multiset<double_point2d_pair> dpp_set;
for (int i = 0; i < contours.size(); i++)
{
double_point2d_pair dpp;
dpp.area = areas[i];
dpp.centre = mass_centres[i];
dpp_set.insert(dpp);
}
int count = 0;
Point2d first_centre, second_centre;
double first_area, second_area;
// Get the two largest contour areas
for (multiset<double_point2d_pair>::const_reverse_iterator cri = dpp_set.rbegin(); cri != dpp_set.rend(); cri++)
{
if (count == 0)
{
first_centre = cri->centre;
first_area = cri->area;
count++;
}
else
{
second_centre = cri->centre;
second_area = cri->area;
break;
}
}
cout << "Largest contour area: " << first_area << endl;
cout << "Second contour area: " << second_area << endl;
return 0;
}
2 | No.2 Revision |
Here is a code that gets the largest and second largest contour areas (along with their centres). Perhaps you should start over. This code uses a multiset to sort the areas. Like mentioned above, you could also use a vector and then just use the sort function.
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <map>
#include <set>
using namespace std;
// For later use with multiset
class double_point2d_pair
{
public:
double area;
Point2d centre;
};
// For later use with multiset
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);
Mat flt_frame(frame.rows, frame.cols, CV_32F);
for (int j = 0; j < frame.rows; j++)
for (int i = 0; i < frame.cols; i++)
flt_frame.at<float>(j, i) = frame.at<unsigned char>(j, i) / 255.0f;
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(flt_frame.size(), 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);
}
multiset<double_point2d_pair> dpp_set;
for (int i = 0; i < contours.size(); i++)
{
double_point2d_pair dpp;
dpp.area = areas[i];
dpp.centre = mass_centres[i];
dpp_set.insert(dpp);
}
int count = 0;
Point2d first_centre, second_centre;
double first_area, second_area;
// Get the two largest contour areas
for (multiset<double_point2d_pair>::const_reverse_iterator cri = dpp_set.rbegin(); cri != dpp_set.rend(); cri++)
{
if (count == 0)
{
first_centre = cri->centre;
first_area = cri->area;
count++;
}
else
{
second_centre = cri->centre;
second_area = cri->area;
break;
}
}
cout << "Largest contour area: " << first_area << endl;
cout << "Second contour area: " << second_area << endl;
return 0;
}
3 | No.3 Revision |
Here is a code that gets the largest and second largest contour areas (along with their centres). Perhaps you should start over. This Like mentioned above, this code uses a multiset sorted vector to sort store the areas. Like mentioned above, you could also use a vector contour areas and then just use the sort function.centres.
#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")
#include <iostream>
#include <map>
#include <set>
using namespace std;
// For later use with multiset
class double_point2d_pair
{
public:
double area;
Point2d centre;
};
// For later use with multiset
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);
}
multiset<double_point2d_pair> dpp_set;
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_set.insert(dpp);
dpp_vec.push_back(dpp);
}
int count = 0;
sort(dpp_vec.begin(), dpp_vec.end());
Point2d first_centre, second_centre;
first_centre = dpp_vec[dpp_vec.size() - 1].centre;
double first_area, second_area;
// Get the two largest contour areas
for (multiset<double_point2d_pair>::const_reverse_iterator cri = dpp_set.rbegin(); cri != dpp_set.rend(); cri++)
{
if (count == 0)
{
first_centre = cri->centre;
first_area = cri->area;
count++;
}
else
{
dpp_vec[dpp_vec.size() - 1].area;
Point2d second_centre = cri->centre;
dpp_vec[dpp_vec.size() - 2].centre;
double second_area = cri->area;
break;
}
}
dpp_vec[dpp_vec.size() - 2].area;
cout << "Largest contour area: " << first_area << endl;
cout << "Second contour area: " << second_area << endl;
return 0;
}
4 | No.4 Revision |
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 <map>
#include <set>
using namespace std;
// For later use with multiset
class double_point2d_pair
{
public:
double area;
Point2d centre;
};
// For later use with multiset
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;
}
5 | No.5 Revision |
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 <map>
<vector>
#include <set>
<algorithm>
using namespace std;
// For later use with multiset
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;
}
6 | No.6 Revision |
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 multiset
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;
}