// convolve.cpp // // Karl's Nifty Convolve by FFT thingy // Nov 4, 2000 #include #include #include #include #include #include #define MAXSIGNALSIZE 520 #define INSIGNALSOURCE argv[1] //"2D_White_Box.pgm" #define KERNELSOURCE argv[2] //"2D_White_Box.pgm" #define OUTSIGNALDEST argv[3] //"2D_Square_Square.pgm" struct complex { float R,I; }; int MAX(int x, int y); int MIN(int x, int y); int getImageFromFile(char *filename, int signalarray[MAXSIGNALSIZE][MAXSIGNALSIZE], int *sizex, int *sizey, int *sdepth); int writeImageToFile(char *filename, int signalarray[MAXSIGNALSIZE][MAXSIGNALSIZE], int sizex, int sizey, int sdepth); void TwoDUFFT(complex f[MAXSIGNALSIZE][MAXSIGNALSIZE], int sizex, int sizey, int depth); void TwoDFFT(complex f[MAXSIGNALSIZE][MAXSIGNALSIZE], int sizex, int sizey, int depth); void FFT(complex signalarray[], int size); void uFFT(complex signalarray[], int size); void FFTs(complex signalarray[], int size); void uFFTs(complex signalarray[], int size); void Mult(complex s[MAXSIGNALSIZE][MAXSIGNALSIZE], complex k[MAXSIGNALSIZE][MAXSIGNALSIZE], int sizex, int sizey); int maxpix; //Main Program ************************************************** int main(int argc, char *argv[]) { //cout << "Hello\n"; maxpix=0; if (argc<3) { cout << "\nUsage: " << argv[0] << " signal.dat kernel.dat out.dat\n\n"; exit(0); } int insignal[MAXSIGNALSIZE][MAXSIGNALSIZE]; int kernel[MAXSIGNALSIZE][MAXSIGNALSIZE]; complex ker[MAXSIGNALSIZE][MAXSIGNALSIZE]; complex sig[MAXSIGNALSIZE][MAXSIGNALSIZE]; //cout << "Allocated\n"; int insizex, insizey, depth; int ksizex, ksizey, kdepth; if (!getImageFromFile(INSIGNALSOURCE, insignal, &insizex, &insizey, &depth)) { cout << "\nError, could not open file " << INSIGNALSOURCE << "\n\n"; exit(0); } if (!getImageFromFile(KERNELSOURCE, kernel, &ksizex, &ksizey, &kdepth)) { cout << "\nError, could not open file " << KERNELSOURCE << "\n\n"; exit(0); } int newsizex, newsizey, newksizex, newksizey; for (newsizex=1; newsizex=((newsizex/2) + (insizex/2))) || (y>=((newsizey/2) + (insizey/2)))) { sig[x][y].R = 0; } else { sig[x][y].R = insignal[x-newsizex/2+insizex/2][y-newsizey/2+insizey/2]; } sig[x][y].I = 0; if ((x<((newksizex/2) - (ksizex/2))) || (y<((newksizey/2) - (ksizey/2))) || (x>=((newksizex/2) + (ksizex/2))) || (y>=((newksizey/2) + (ksizey/2)))) { ker[x][y].R = 0; } else { ker[x][y].R = kernel[x-newksizex/2+ksizex/2][y-newksizey/2+ksizey/2]; } ker[x][y].I = 0; } } insizex=newsizex; insizey=newsizey; ksizex=newsizex; ksizey=newsizey; TwoDFFT(sig,insizex,insizey,depth); TwoDFFT(ker,ksizex,ksizey,kdepth); Mult(sig,ker,insizex,insizey); TwoDUFFT(sig,insizex,insizey,depth); int midx = insizex/2; int midy = insizey/2; for (int x=0; x> image_type >> width >> height >> depth; //cout << "Reading ... size = " << height << ", " << width << "\n"; *sizex = width; *sizey = height; *sdepth = depth; if (image_type!="P5") { cout << "\nError: " << image_type << " is not a valid image type.\n\n"; exit(1); } xin = 0; yin = 0; unsigned char greyscale; while (!Infile.eof()) { Infile.read(&greyscale,1); if (greyscale>depth) { cout << "Greyscale Out of Bounds! = " << greyscale << "\n"; } else { signalarray[xin][yin]=(int)greyscale; } if (xin<(width-1)) { xin++; } else { xin=0; yin++; } } Infile.close(); return 1; } } //Dump array to signal file *************************************** int writeImageToFile(char *filename, int signalarray[MAXSIGNALSIZE][MAXSIGNALSIZE], int sizex, int sizey, int sdepth) { maxpix=0; for (int x=0; xmaxpix) { maxpix=signalarray[x][y]; } } } ofstream outfile; outfile.open(filename, ios::out); outfile << "P5\n" << sizex << " " << sizey << "\n" << sdepth << "\n"; if (!outfile) { return 0; } else { outfile.setf(ios::fixed); for (int y=0; y (" << signalarray[0].R << "," << signalarray[0].I // << ") (" << signalarray[1].R << "," << signalarray[1].I << ")\n"; } else { complex g[size/2]; complex h[size/2]; for (int loop=0; loop<(size/2); loop++) { g[loop]=signalarray[2*loop]; h[loop]=signalarray[2*loop + 1]; } FFT(g, size/2); FFT(h, size/2); complex gsum,hsum; //cout << "Sig array tally -> "; for (int loop=0; loop (" << signalarray[0].R << "," << signalarray[0].I // << ") (" << signalarray[1].R << "," << signalarray[1].I << ")\n"; } else { complex g[size/2]; complex h[size/2]; for (int loop=0; loop<(size/2); loop++) { g[loop]=signalarray[2*loop]; h[loop]=signalarray[2*loop + 1]; } uFFT(g, size/2); uFFT(h, size/2); complex gsum,hsum; //cout << "Sig array tally -> "; for (int loop=0; loopy) return x; else return y; } int MIN(int x,int y) { if (x>y) return y; else return x; }