#include <stdio.h>
#include <string.h>
#include <math.h>
#include "cv.h"
#include "highgui.h"
#define MaxP(x,y) (float)(x>y?x:y)
#define MinP(x,y) (float)(x<y?x:y)
#define PI 3.14
#define MAXFACT 50
unsigned int fact_array[MAXFACT];
IplImage* oriImg;
IplImage* grayImg;
unsigned int fact(int n)
{
if(fact_array[n]!=0)
return fact_array[n];
fact_array[0] = 1;
fact_array[1] = 1;
int index = n;
fact_array[n] = n;
index--;
while(fact_array[index]==0){
fact_array[n] = fact_array[n] * index;
index--;
}
fact_array[n] = fact_array[n]*fact_array[index];
return fact_array[n];
}
double ZernikePolynomial(int n,int m,double r)
{
if(n>50)
{
printf("I can only deal with factorial lower than 50 ");
return 0;}
int s;
double sum=0;
m=abs(m);
if( (n<0)||(n-m)%2!=0||(m>n))
{
printf("ZernikePolynomial(): improper values of n,m %d%d ",n,m);
return 0;
}
if(r>1)
{
printf("ZernikePolynomial(): improper value of r %f ",r);
return 0;
}
for(s=0;s<=(n-m)/2;s++)
{
sum+=(pow(-1.0,s)*fact(n-s)*pow(r,n-2*s)) / (fact(s)*fact((n+m-2*s)/2)*fact((n-m-2*s)/2));
}
return sum;
}
float get_8_XYValue(int x,int y)
{
int height = grayImg->height;
int widthStep = grayImg->widthStep;
char* Data = grayImg->imageData;
uchar c_value = ((uchar *)(Data+x*widthStep))[y];
float value = (float)c_value;
return value;
}
int Img2Gray(void)
{
int a =1;
if((oriImg = cvLoadImage("E:/XH.jpg", 1)) != 0 )
{ grayImg = cvCreateImage(cvSize(oriImg->width,oriImg->height),IPL_DEPTH_8U,1);
cvCvtColor(oriImg,grayImg,CV_BGR2GRAY);
return 1;}
return 0;
}
void ClearOpenCV(void)
{
if(oriImg!=NULL){
cvReleaseImage( &oriImg );
oriImg = NULL;
}
if(grayImg!=NULL){
cvReleaseImage( &grayImg );
grayImg = NULL;
}
}
float Caculate_8_Zernike(int n,int m)
{
float Cnm,Snm;
float Z_mode;
int height = grayImg->height;
int widthStep = grayImg->widthStep;
float N = MinP(height,widthStep);
float N2 = N/2;
float Rnmr_C =0;
float Rnmr_S =0;
float rou;
float sigma;
for(rou=1;rou<N2;r++)
{
float temp_C = 0;
float temp_S = 0;
for(sigma=1;sigma<=8*rou;sigma++)
{
float v = get_8_XYValue(rou,sigma);
temp_C+= cos((PI*m*sigma)/(4*rou))*v;
temp_S+= sin((PI*m*sigma)/(4*rou))*v;
}
float Rnmr = (float)ZernikePolynomial(n,m,(2*rou)/N);
Rnmr_C = Rnmr_C + temp_C* Rnmr;
Rnmr_S = Rnmr_S + temp_S* Rnmr;
}
Cnm = Rnmr_C*(2*n+2)/pow(N,2);
Snm = Rnmr_S*(2*n+2)/pow(N,2);
Z_mode = pow(pow(Cnm,2)+pow(Cnm,2),0.5);
return Z_mode;
}
float getZernike(int n,int m)
{
int pass = Img2Gray();
if(!pass)
return -1;
int depth = 0;
int nChannels = 0;
nChannels = grayImg->nChannels;
if(nChannels!=1)
return -1;
depth = grayImg->depth;
switch(depth)
{
case IPL_DEPTH_8U: Caculate_8_Zernike(n,m); break;
case IPL_DEPTH_32F: Caculate_32_Zernike(n,m); break;
default: break;
}
ClearOpenCV();
return Z_mode;
}
int main(int argc,char** argv)
{
if(argc!=2)
printf("Improper number of argumnt ");
int n ;
sscanf(argv[1],"%d",&n);
float Zn[100];
int i,j,count=0;
for(i=n;i>=2;i--)
for(j=i;j>=0;j=j-2)
{
Zn[count] = getZernike(i,j);
printf("Z%d%d is : %f ",i,j,Zn[count]);
count++;
}
return 0;
}
#include <string.h>
#include <math.h>
#include "cv.h"
#include "highgui.h"
#define MaxP(x,y) (float)(x>y?x:y)
#define MinP(x,y) (float)(x<y?x:y)
#define PI 3.14
#define MAXFACT 50
unsigned int fact_array[MAXFACT];
IplImage* oriImg;
IplImage* grayImg;
unsigned int fact(int n)
{
if(fact_array[n]!=0)
return fact_array[n];
fact_array[0] = 1;
fact_array[1] = 1;
int index = n;
fact_array[n] = n;
index--;
while(fact_array[index]==0){
fact_array[n] = fact_array[n] * index;
index--;
}
fact_array[n] = fact_array[n]*fact_array[index];
return fact_array[n];
}
double ZernikePolynomial(int n,int m,double r)
{
if(n>50)
{
printf("I can only deal with factorial lower than 50 ");
return 0;}
int s;
double sum=0;
m=abs(m);
if( (n<0)||(n-m)%2!=0||(m>n))
{
printf("ZernikePolynomial(): improper values of n,m %d%d ",n,m);
return 0;
}
if(r>1)
{
printf("ZernikePolynomial(): improper value of r %f ",r);
return 0;
}
for(s=0;s<=(n-m)/2;s++)
{
sum+=(pow(-1.0,s)*fact(n-s)*pow(r,n-2*s)) / (fact(s)*fact((n+m-2*s)/2)*fact((n-m-2*s)/2));
}
return sum;
}
float get_8_XYValue(int x,int y)
{
int height = grayImg->height;
int widthStep = grayImg->widthStep;
char* Data = grayImg->imageData;
uchar c_value = ((uchar *)(Data+x*widthStep))[y];
float value = (float)c_value;
return value;
}
int Img2Gray(void)
{
int a =1;
if((oriImg = cvLoadImage("E:/XH.jpg", 1)) != 0 )
{ grayImg = cvCreateImage(cvSize(oriImg->width,oriImg->height),IPL_DEPTH_8U,1);
cvCvtColor(oriImg,grayImg,CV_BGR2GRAY);
return 1;}
return 0;
}
void ClearOpenCV(void)
{
if(oriImg!=NULL){
cvReleaseImage( &oriImg );
oriImg = NULL;
}
if(grayImg!=NULL){
cvReleaseImage( &grayImg );
grayImg = NULL;
}
}
float Caculate_8_Zernike(int n,int m)
{
float Cnm,Snm;
float Z_mode;
int height = grayImg->height;
int widthStep = grayImg->widthStep;
float N = MinP(height,widthStep);
float N2 = N/2;
float Rnmr_C =0;
float Rnmr_S =0;
float rou;
float sigma;
for(rou=1;rou<N2;r++)
{
float temp_C = 0;
float temp_S = 0;
for(sigma=1;sigma<=8*rou;sigma++)
{
float v = get_8_XYValue(rou,sigma);
temp_C+= cos((PI*m*sigma)/(4*rou))*v;
temp_S+= sin((PI*m*sigma)/(4*rou))*v;
}
float Rnmr = (float)ZernikePolynomial(n,m,(2*rou)/N);
Rnmr_C = Rnmr_C + temp_C* Rnmr;
Rnmr_S = Rnmr_S + temp_S* Rnmr;
}
Cnm = Rnmr_C*(2*n+2)/pow(N,2);
Snm = Rnmr_S*(2*n+2)/pow(N,2);
Z_mode = pow(pow(Cnm,2)+pow(Cnm,2),0.5);
return Z_mode;
}
float getZernike(int n,int m)
{
int pass = Img2Gray();
if(!pass)
return -1;
int depth = 0;
int nChannels = 0;
nChannels = grayImg->nChannels;
if(nChannels!=1)
return -1;
depth = grayImg->depth;
switch(depth)
{
case IPL_DEPTH_8U: Caculate_8_Zernike(n,m); break;
case IPL_DEPTH_32F: Caculate_32_Zernike(n,m); break;
default: break;
}
ClearOpenCV();
return Z_mode;
}
int main(int argc,char** argv)
{
if(argc!=2)
printf("Improper number of argumnt ");
int n ;
sscanf(argv[1],"%d",&n);
float Zn[100];
int i,j,count=0;
for(i=n;i>=2;i--)
for(j=i;j>=0;j=j-2)
{
Zn[count] = getZernike(i,j);
printf("Z%d%d is : %f ",i,j,Zn[count]);
count++;
}
return 0;
}