#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdarg.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "fstream"
#include "iostream"
using namespace std;
using namespace cv;
//-----------------------------------------------------------------------------------------------------
// Моменты Зернике, реализованы по статье (для квадратного изображения):
// http://www.utdallas.edu/~a.tahmasbi/publications/Zernike_CBM_2011.pdf
// и матлабовской реализации отсюда
// http://www.mathworks.com/matlabcentral/fileexchange/38900-zernike-moments
//-----------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------
// Нормированная длина радиус вектора
//-----------------------------------------------------------------------------------------------------
double Rho(double row,double col,double N)
{
double rho=sqrt(pow(2*col-N+1,2.0)+pow(2*row-N+1,2.0))/N;
return rho;
}
//-----------------------------------------------------------------------------------------------------
// Угол радиус-вектора от центра изображения к координатам (row,col)
//-----------------------------------------------------------------------------------------------------
double Theta(double row,double col,double N)
{
double theta=atan2(N-1-2*row,2*col-N+1);
return theta;
}
//-----------------------------------------------------------------------------------------------------
// Факториал
//-----------------------------------------------------------------------------------------------------
int factorial(int n)
{
return !n ? 1 : n * factorial(n - 1);
}
//-----------------------------------------------------------------------------------------------------
// Радиальный полином
//-----------------------------------------------------------------------------------------------------
double R(double n,double m,double rho)
{
double r=0;
for(int s=0;s<=(n-fabs(m))*0.5;s++)
{
r+=pow(-1.0,s)*factorial(n-s)*pow(rho,(n-2*s))/(factorial(s)*factorial(((n+fabs(m))*0.5)-s)*factorial(((n-fabs(m))*0.5)-s));
}
return r;
}
//-----------------------------------------------------------------------------------------------------
// Момент Зернике с параметрами:
// n - неотрицательное целое, представляющее порядок радиального полинома,
// m - положительное или отрицательное целое, удовлетворяющее условию n-|m|=четное число и |m|<=n,
// m - представляет повторение азимутального угла.
//-----------------------------------------------------------------------------------------------------
complex<double> Z(Mat& img ,double n,double m)
{
double N=MIN(img.rows,img.cols);
complex<double> z=(0,0);
double lambda=0;
for(int r=0;r<N;r++)
{
for(int c=0;c<N;c++)
{
// здесь расчет ведется для изображения, содержащего только 0 или 1
// вероятно можно считать и для других изображений,
// но тогда надо думать как нормировать (см. коэффициент lambda).
double f=img.at<unsigned char>(r,c);
if(f>0)
{
z+=f*R(n,m,Rho(r,c,N))*exp(complex<double>(0,-m*Theta(r,c,N)));
}
}
}
// Нормирующий коэффициент (площадь круга, вписанного в изображение)
lambda=CV_PI*pow(N/2,2)*255;
z*=(n+1)/lambda;
return z;
}
//-----------------------------------------------------------------------------------------------------
// Точка входа
//-----------------------------------------------------------------------------------------------------
int main( int argc, char** argv )
{
namedWindow("Res");
Mat res=imread("D:\\ImagesForTest\\Oval_H.png",0);
// Изображение черным по белому, поэтому инвертируем ее.
// Если изображение белым по черному, тогда инверсия не нужна.
res=255-res;
cout << "begin" << endl;
// Расчет момента
complex<double> z= Z(res,4,2);
// Угол в градусах
double angle=atan2(z.imag(),z.real())*180.0/CV_PI;
// Модуль
double ampl=abs(z);
// Вывод результатов
cout << z << endl;
cout << angle << endl;
cout << ampl << endl;
cout << "end" << endl;
imshow("Res",res);
waitKey(0);
return 0;
}
zernike矩的算法实现MATLAB
需积分: 50 99 浏览量
2018-12-18
09:26:56
上传
评论 1
收藏 2KB ZIP 举报
guo_8787
- 粉丝: 7
- 资源: 17
最新资源
- 花数据集+数据集汇总+标签txt+数据集汇总代码+迁移学习最佳模型+全部迭代最佳模型
- 20240329224412.zip
- switch.docx `switch`语句是C++中的一种流程控制语句,通常用于根据表达式的值选择执行不同的代码块 下面是`
- python绘制直方图-02-进程之间不共享全局变量.ev4.rar
- python绘制直方图-01-第三天知识点回顾.ev4.rar
- 01背包问题动态规划.docx
- 表达式求值.docx表达式求值涉及许多不同的情况和方法,具体取决于表达式的形式和要求的精度 下面是一个简单的例子
- python绘制直方图-08-软件的卸载.ev4.rar
- tcp和udp的区别.docx
- 斐波那契数列c.docx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈