//************************************************************************** #include <iostream.h> #include <fstream.h> #include <math.h> #include "matrix.h" #include "gabor.h" #include "gaussian.h" #include "edgeflow.h" //************************************************************************** // Filter mask size is 2*NUM_BOUNDARY_PIXELS_FOR_PADDING+1 squared! #define NUM_BOUNDARY_PIXELS_FOR_PADDING 60 //************************************************************************** extern int debugflag; extern int textureflag; extern int intensityflag; //************************************************************************** void ComputeEdgeFlowVector(Matrix *Fr, Matrix *Fi, Matrix &imgR, Matrix &imgG, Matrix &imgB, int numorient, double sigma) { int height = imgR.nx; int width = imgR.ny; int N = numorient; // number of different theta values Matrix *E, *P; E = allocateMatrixArray(N, height, width); P = allocateMatrixArray(N, height, width); for (int i = 0; i < N; i++) { int side = NUM_BOUNDARY_PIXELS_FOR_PADDING; double theta = (i*2.0/N)*Pi; cout << endl << "Calculating Total Edge Flow for theta = " << theta*RAD2DEG << " deg" << endl; TotalEdgeFlowRGB(&E[i], &P[i], imgR, imgG, imgB, sigma, theta, numorient, side); } if (debugflag) { printMatrixArray(E, "TotalE.dbg", N, height, width); printMatrixArray(P, "TotalP.dbg", N, height, width); } // Compute edge flow vector cout << endl << "Computing Edge Flow Vector from above data..."; cout.flush(); Fr->Zero(); Fi->Zero(); for (int h = 0; h < height; h++) for (int w = 0; w < width; w++) { int index = -1; double maxP = -1.0e+300; for (int k = 0; k < N; k++) { double sumP = 0.0; for (int i = 0; i < N/2; i++) { int m = (i + k)%N; sumP += P[m].p[h][w]; // P(s,theta) } if (sumP > maxP) { maxP = sumP; index = k; } } for (int k = 0; k < N/2; k++) { int m = (index + k)%N; double theta = (m*2.0/N)*Pi; Fr->p[h][w] += E[m].p[h][w]*cos(theta); Fi->p[h][w] += E[m].p[h][w]*sin(theta); } } double norm_r = Fr->Norm(); double norm_i = Fi->Norm(); double norm = sqrt(norm_r*norm_r + norm_i*norm_i); if (norm > 0.0) { Fr->scale(1.0/norm); Fi->scale(1.0/norm); } #ifdef FREEMEM deallocateMatrixArray(E, N); deallocateMatrixArray(P, N); #endif cout << "done!" << endl; cout.flush(); } //************************************************************************** void TotalEdgeFlowRGB(Matrix *E, Matrix *P, Matrix &imgR, Matrix &imgG, Matrix &imgB, double sigma, double theta, int numorient, int side) { cout << " Calling TotalEdgeFlow..." << endl; int height = imgR.nx; int width = imgR.ny; // Intensity Edge Flow Matrix TmpE(height, width); Matrix TmpP(height, width); E->Zero(); P->Zero(); if (intensityflag) { if (imgR == imgG) { cout << " GRAY: "; IntensityEdgeFlow(E, P, imgR, sigma, theta, side); } else { // Red cout << " RED: "; IntensityEdgeFlow(&TmpE, &TmpP, imgR, sigma, theta, side); *E += TmpE; *P += TmpP; // Green cout << " GREEN: "; IntensityEdgeFlow(&TmpE, &TmpP, imgG, sigma, theta, side); *E += TmpE; *P += TmpP; // Blue cout << " BLUE: "; IntensityEdgeFlow(&TmpE, &TmpP, imgB, sigma, theta, side); *E += TmpE; *P += TmpP; E->scale(1.0/3.0); P->scale(1.0/3.0); } if (debugflag) { E->WriteImage("IntensityE.dbg", "gif"); P->WriteImage("IntensityP.dbg", "gif"); } //E->Normalize(); E->scale(0.6); P->scale(0.6); } // end intensityflag if (textureflag) { // Texture Edge Flow int scale = 4; int orientation = numorient; double Ul = 0.25/sigma; //0.1; double Uh = 0.45; //0.4; int flag = 0; // Remove DC component Matrix img(height, width); img += imgR; img += imgG; img += imgB; TextureEdgeFlow(&TmpE, &TmpP, img, theta, side, Ul, Uh, sigma, scale, 6, flag); if (debugflag) { TmpE.WriteImage("TextureE.dbg", "gif"); TmpP.WriteImage("TextureP.dbg", "gif"); } //TmpE.Normalize(); TmpE.scale(0.4); TmpP.scale(0.4); *E += TmpE; *P += TmpP; } // end textureflag cout << " Exiting TotalEdgeFlow." << endl; cout.flush(); } //************************************************************************** void IntensityEdgeFlow(Matrix *E, Matrix *P, Matrix &img, double sigma, double theta, int side) { cout << "Calling IntensityEdgeFlow..."; cout.flush(); int height = img.nx; int width = img.ny; FilteredImg(E, img, GDmask, sigma, theta, side); E->Abs(); if (debugflag) { E->WriteImage("GDafter.dbg", "gif"); } Matrix Err1(height, width), Err2(height, width), Tmp(height, width); FilteredImg(&Err1, img, DOOGmask, sigma, theta, side); Err1.Abs(); if (debugflag) { Err1.WriteImage("DOOGafter.dbg", "gif"); } //Err1.WriteImage("Err1.dbg", "gif"); FilteredImg(&Err2, img, DOOGmask, sigma, theta+Pi, side); Err2.Abs(); //Err2.WriteImage("Err2.dbg", "gif"); Tmp = Err1 + Err2; //Tmp.WriteImage("ErrSum.dbg", "gif"); // P(s,theta) *P = Err1/Tmp; cout << "done!" << endl; cout.flush(); } //************************************************************************** void TextureEdgeFlow(Matrix *E, Matrix *P, Matrix &img, double theta, int side, double Ul, double Uh, double sigma, int scale, int orientation, int flag) { static int firstcall = 1; static Matrix **F_r, **F_i; cout << " Calling TextureEdgeFlow." << endl; int height = img.nx; int width = img.ny; if (firstcall) { F_r = allocateMatrixArray(scale, orientation, height, width); F_i = allocateMatrixArray(scale, orientation, height, width); GaborFilteredImg(F_r, F_i, img, side, Ul, Uh, scale, orientation, flag); firstcall = 0; } Matrix Err1(height, width), Err2(height, width), Tmp(height, width); E->Zero(); cout << " TextureEdgeFlow: Processing Image 0/" << scale*orientation; for (int i = 0; i < scale; i++) for (int j = 0; j < orientation; j++) { cout << "\r TextureEdgeFlow: Processing Image " << i*orientation+j+1 << "/" << scale*orientation; cout.flush(); // Converts: F_r -> mag, F_i -> phase Complex2Polar(&F_r[i][j], &F_i[i][j]); // Calculate E(s,theta) FilteredImg(&Tmp, F_r[i][j], GDmask, sigma, theta, side); Tmp.Abs(); Tmp.NormalizeEnergy(); *E += Tmp; // Calculate Error(s,theta) FilteredImg(&Tmp, F_r[i][j], DOOGmask, sigma, theta, side); Tmp.Abs(); Tmp.NormalizeEnergy(); Err1 += Tmp; // Calculate Error(s,theta+Pi) FilteredImg(&Tmp, F_r[i][j], DOOGmask, sigma, theta+Pi, side); Tmp.Abs(); Tmp.NormalizeEnergy(); Err2 += Tmp; } cout << "...done!" << endl; cout.flush(); if (debugflag) { printMatrixArray(F_r, "TextureMatR.dbg", scale, orientation, height, width); printMatrixArray(F_i, "TextureMatI.dbg", scale, orientation, height, width); } Tmp = Err1 + Err2; *P = Err1/Tmp; // P(s, theta) /* #ifdef FREEMEM deallocateMatrixArray(F_r, scale, orientation); deallocateMatrixArray(F_i, scale, orientation); #endif */ cout << " Exiting TextureEdgeFlow." << endl; cout.flush(); } //**************************************************************************