در ابتدا بایستی نقاط مربط به کانتور درب قوطی را استخراج کنید ابتدا پیش پردازش انجا داده و سپس با تابع findcontour مجموعه نقاط مربوط به ناحیه درب قوطی را بدست بیارید و سپس با استفاده از مومنت مرتیه اول مرکز ثقل این نقاط را محاسبه کنید. سپس شعاع هر نقطه نسبت به مرکز را محاسبه نمائید .شما می تونید کارتون را با هر resolution ی ضرایب فوریه را استخراج کنید من در اینجا از 17 ضریب استفاده کردم.
از رابطه زیر(تبدیل فوریه) ضرایب را محاسبه نمائید.هر چقدر شکل مورد نظر دایره ای باشد کاملاً ضرایب بکدیگر را خنثی و مجموع صفر می گردد.
از مجموع ضرایب میزان دایروی بودن را محاسبه نمائید.
vector<float> getRadiuses(const vector<cv::POint>& contour, const Point& center){
vector<float> result;
result.reserve(contour.size());
for (auto& pnt : contour)
result.push_back((float)norm(pnt - center));
return result;
}
float getDFTCircularity(const vector<cv::POint>& contour, const cv::Point& center){
const int N = contour.size();
const int M = 17;
vector<float> radiuses = getRadiuses(contour, center);
vector<std::complex<double>> C(M, 0.f);
double result = 0;
for (int k = 1; k < M; k++){
C[k] = std::complex<double>(0.,0.);
std::complex<double> value(0.0, 0.0);
for (int theta = 0; theta < N; theta++){
value = std::complex<double>(0.0, -(2 * CV_PI * k * theta / N));
value = std::exp(value);
value = std::complex<double>(radiuses[theta] * value.imag(), radiuses[theta] * value.real());
C[k] += value;
}
result += std::norm(C[k]) ;
}
result = std::max(0., 100 - result / N);
return (float)result;
}