hi, can anybody explain me this code: this code is for counting number of finger. this is the input image
// feature extraction.cpp : Defines the entry point for the console application.
//
//--------------------------------------In the name of GOD
//-------------------------------BOW+SVM by Mohammad Reza Mostajabi
//#include "stdafx.h"
#include <opencv\cv.h>
#include <opencv\highgui.h>
//#include <opencv\ml.h>
#include <stdio.h>
#include <iostream>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2\ml\ml.hpp>
#include <vector>
using namespace cv;
using namespace std;
using std::cout;
using std::cerr;
using std::endl;
using std::vector;
RNG rnga(12345);
inline void mix_channels(cv::Mat const &src, cv::Mat &dst, std::initializer_list<int> from_to)
{
cv::mixChannels(&src, 1, &dst, 1, std::begin(from_to), from_to.size() / 2);
}
double angle(std::vector<cv::Point>& contour, int pt, int r)
{
int size = contour.size();
cv::Point p0 = (pt>0) ? contour[pt%size] : contour[size - 1 + pt];
cv::Point p1 = contour[(pt + r) % size];
cv::Point p2 = (pt>r) ? contour[pt - r] : contour[size - 1 - r];
double ux = p0.x - p1.x;
double uy = p0.y - p1.y;
double vx = p0.x - p2.x;
double vy = p0.y - p2.y;
return (ux*vx + uy*vy) / sqrt((ux*ux + uy*uy)*(vx*vx + vy*vy));
}
int rotation(std::vector<cv::Point>& contour, int pt, int r)
{
int size = contour.size();
cv::Point p0 = (pt>0) ? contour[pt%size] : contour[size - 1 + pt];
cv::Point p1 = contour[(pt + r) % size];
cv::Point p2 = (pt>r) ? contour[pt - r] : contour[size - 1 - r];
double ux = p0.x - p1.x;
double uy = p0.y - p1.y;
double vx = p0.x - p2.x;
double vy = p0.y - p2.y;
return (ux*vy - vx*uy);
}
bool isEqual(double a, double b)
{
return fabs(a - b) <= 1e-7;
}
int main()
{
Mat input = imread("C:\\Users\\Intern-3\\Desktop\\IPF\\2.png");
Size size = input.size();
int erosion_size = 1;
Mat HSV, threshold;
cvtColor(input, HSV, COLOR_BGR2HSV);
inRange(HSV, cv::Scalar(0, 0, 100), cv::Scalar(0, 0, 255), threshold);
Mat erodeElement = getStructuringElement(MORPH_RECT, cv::Size(5, 5));
Mat dilateElement = getStructuringElement(MORPH_RECT, cv::Size(8, 8));
erode(threshold, threshold, erodeElement);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
Mat mask = threshold;
findContours(mask.clone(), contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE, Point(0, 0));
/// Draw contours
Mat drawing = Mat::zeros(mask.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar(rnga.uniform(0, 255), rnga.uniform(0, 255), rnga.uniform(0, 255));
drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
}
cout << "Contours = " << contours.size() << endl;
for (int i = 0; i < contours.size(); i++)
{
cout << "area : " << contourArea(contours[i]) << endl;
}
imshow("contour", drawing);
if (!contours.empty())
{
for (int i = 0; i<contours.size(); i++)
{
if (cv::contourArea(contours[i])>500)
{
Point center;
std::vector<cv::Point> fingers;
std::vector<cv::Point> contour;
cv::Moments m = cv::moments(contours[i]);
center.x = m.m10 / m.m00;
center.y = m.m01 / m.m00;
for (int j = 0; j < contours[i].size(); j += 16)
{
double cos0 = angle(contours[i], j, 40);
if ((cos0 > 0.5) && (j + 16<contours[i].size()))
{
double cos1 = angle(contours[i], j - 16, 40);
double cos2 = angle(contours[i], j + 16, 40);
double maxCos = std::max(std::max(cos0, cos1), cos2);
bool equal = isEqual(maxCos, cos0);
signed int z = rotation(contours[i], j, 40);
if (equal == 1 && z<0)
{
fingers.push_back(contours[i][j]);
}
}
}
contour = contours[i];
cout << "Finger Count : "<<fingers.size()<<endl;
//hands.push_back(tmp);
}
}
}
imshow("input", input);
waitKey(0);
}
in the following code i m not able to understand why this is being done to calculate angle. which 3 points (p0,p1,p2) is being considered to find the angle and its rotation.
the code block which i am not able to understand is :
if (cv::contourArea(contours[i])>500)
{
Point center;
std::vector<cv::Point> fingers;
std::vector<cv::Point> contour;
cv::Moments m = cv::moments(contours[i]);
center.x = m.m10 / m.m00;
center.y = m.m01 / m.m00;
for (int j = 0; j < contours[i].size(); j += 16)
{
double cos0 = angle(contours[i], j, 40);
if ((cos0 > 0.5) && (j + 16<contours[i].size()))
{
double cos1 = angle(contours[i], j - 16, 40);
double cos2 = angle(contours[i], j + 16, 40);
double maxCos = std::max(std::max(cos0, cos1), cos2);
bool equal = isEqual(maxCos, cos0);
signed int z = rotation(contours[i], j, 40);
if (equal == 1 && z<0)
{
fingers.push_back(contours[i][j]);
}
}
}
contour = contours[i];
cout << "Finger Count : "<<fingers.size()<<endl;
//hands.push_back(tmp);
}