#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
tuple<size_t, size_t> getTheTwoLargestContours(const vector<vector<Point>>& contours)
{
size_t largestLoc = 0, secondLargestLoc = 0;
double largestArea = 0, secondLargestArea = 0;
for(size_t index = 0; index < contours.size(); ++index)
{
double area = contourArea(contours[index]);
if(area > largestArea)
{
largestArea = area;
largestLoc = index;
}
else if(area > secondLargestArea)
{
secondLargestArea = area;
secondLargestLoc = index;
}
}
return make_tuple(largestLoc, secondLargestLoc);
}
int main(void)
{
Mat frame = imread("cards.png", IMREAD_GRAYSCALE);
threshold(frame, frame, 127, 255, THRESH_BINARY);
imshow("f", frame);
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;
}
tuple<size_t, size_t> locations = getTheTwoLargestContours(contours);
Moments mu = moments(contours[get<0>(locations)], false);
Point2d largestMassCenter = Point2d(mu.m10 / mu.m00, mu.m01 / mu.m00);
mu = moments(contours[get<1>(locations)], false);
Point2d secondLargestMassCenter = Point2d(mu.m10 / mu.m00, mu.m01 / mu.m00);
double distance = norm(largestMassCenter - secondLargestMassCenter);
cout << "Distance (in pixels): " << distance << endl;
Mat output ...