aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorN.N. <sevyves@users.sourceforge.net>2009-06-29 17:53:37 +0000
committerN.N. <sevyves@users.sourceforge.net>2009-06-29 17:53:37 +0000
commitbb51cb7b85a80bae5c867fdc92d15028d718b257 (patch)
tree712c31c68a6f04d372d8cb2d6aa4149c4d0d90a6
parente7e2e222ffaabba154b88a9a7c03c73189d472bd (diff)
Discrete Fourier Transform for Gem
svn path=/trunk/externals/pix_opencv/; revision=11834
-rw-r--r--Makefile8
-rwxr-xr-xpix_opencv_dft-help.pd103
-rwxr-xr-xpix_opencv_dft.cc461
-rwxr-xr-xpix_opencv_dft.h88
4 files changed, 656 insertions, 4 deletions
diff --git a/Makefile b/Makefile
index df7f630..926369e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
-PD_DIR = ../../pd
-GEM_DIR = ../../Gem
+PD_DIR = ../pd
+GEM_DIR = ../gem
GEM_OPENCV_VERSION = 0.1
@@ -14,7 +14,7 @@ CPPFLAGS = -fPIC -DPD -O2 -funroll-loops -fomit-frame-pointer -ffast-math \
UNAME := $(shell uname -s)
ifeq ($(UNAME),Linux)
INCLUDES += `pkg-config --cflags opencv`
- LDFLAGS = -Wl,--export-dynamic -shared
+ LDFLAGS = -export_dynamic -shared
LIBS = `pkg-config --libs opencv`
EXTENSION = pd_linux
endif
@@ -36,7 +36,7 @@ endif
.SUFFIXES = $(EXTENSION)
-SOURCES = pix_opencv_edge.cc pix_opencv_laplace.cc pix_opencv_morphology.cc pix_opencv_distrans.cc pix_opencv_motempl.cc pix_opencv_haarcascade.cc pix_opencv_contours_boundingrect.cc pix_opencv_bgsubstract.cc pix_opencv_contours_convexity.cc
+SOURCES = pix_opencv_edge.cc pix_opencv_laplace.cc pix_opencv_morphology.cc pix_opencv_distrans.cc pix_opencv_motempl.cc pix_opencv_haarcascade.cc pix_opencv_contours_boundingrect.cc pix_opencv_bgsubstract.cc pix_opencv_contours_convexity.cc pix_opencv_dft.cc
all: $(SOURCES:.cc=.$(EXTENSION))
diff --git a/pix_opencv_dft-help.pd b/pix_opencv_dft-help.pd
new file mode 100755
index 0000000..1963806
--- /dev/null
+++ b/pix_opencv_dft-help.pd
@@ -0,0 +1,103 @@
+#N canvas 36 143 1154 642 10;
+#X obj 396 -37 gemhead;
+#X obj 364 351 pix_texture;
+#X obj 364 379 square 2;
+#X obj 9 -28 cnv 15 220 70 empty empty empty 20 12 0 14 -195568 -66577
+0;
+#N canvas 0 22 454 304 gemwin 0;
+#X obj 132 136 gemwin;
+#X obj 67 89 outlet;
+#X obj 67 10 inlet;
+#X obj 67 41 route create;
+#X msg 67 70 set destroy;
+#X msg 182 68 set create;
+#X msg 132 112 create \, 1;
+#X msg 238 112 destroy;
+#N canvas 87 154 247 179 Gem.init 0;
+#X obj 118 46 loadbang;
+#X msg 118 81 reset;
+#X obj 118 113 outlet;
+#X connect 0 0 1 0;
+#X connect 1 0 2 0;
+#X restore 289 80 pd Gem.init;
+#X connect 2 0 3 0;
+#X connect 3 0 4 0;
+#X connect 3 0 6 0;
+#X connect 3 1 5 0;
+#X connect 3 1 7 0;
+#X connect 4 0 1 0;
+#X connect 5 0 1 0;
+#X connect 6 0 0 0;
+#X connect 7 0 0 0;
+#X connect 8 0 0 0;
+#X restore 14 16 pd gemwin;
+#X msg 14 -8 destroy;
+#X text 15 -26 Create window and render;
+#X obj 200 368 pix_texture;
+#X obj 200 396 square 2;
+#X obj 367 159 translateXYZ -2 0 0;
+#X obj 367 224 separator;
+#X obj 499 -71 cnv 15 155 250 empty empty empty 20 12 0 14 -24198 -66577
+0;
+#X obj 511 -66 bng 25 250 50 0 empty empty empty 0 -6 0 8 -262144 -1
+-1;
+#X obj 524 128 unpack 0 0 0;
+#X floatatom 514 151 5 0 0 3 length - -;
+#X floatatom 563 151 5 0 0 3 width - -;
+#X floatatom 613 151 5 0 0 3 height - -;
+#X obj 568 109 bng 15 250 50 0 empty empty end_reached 20 7 0 10 -262144
+-1 -1;
+#X floatatom 550 74 5 0 10000 1 frame# - -;
+#X obj 511 -37 openpanel;
+#X msg 511 -17 open \$1;
+#X obj 499 92 pix_film;
+#X msg 517 26 auto \$1;
+#X obj 517 8 tgl 15 0 empty empty empty 0 -6 0 8 -262144 -1 -1 1 1
+;
+#X obj 364 259 translateXYZ 4 0 0;
+#X obj 364 316 pix_opencv_dft;
+#X text 8 -64 written by yves degoyon ( ydegoyon@gmail.com );
+#X text 9 -80 this can be used for pattern matching;
+#X text 9 -94 pix_opencv_dft : discrete fourier transform;
+#X msg 426 282 bang;
+#X obj 503 258 bng 15 250 50 0 empty empty empty 17 7 0 10 -262144
+-1 -1;
+#X obj 502 232 loadbang;
+#X obj 503 282 metro 100;
+#X text 572 282 <-- Calculate Discrete Fourier Transform of the pattern
+;
+#X text 594 293 pdp_opencv_dft is too greedy to be calculayed for every
+;
+#X text 592 306 frame so it is just processed when it receives a bang
+;
+#X obj 580 26 loadbang;
+#X msg 528 50 colorspace RGBA;
+#X connect 0 0 21 0;
+#X connect 1 0 2 0;
+#X connect 4 0 5 0;
+#X connect 5 0 4 0;
+#X connect 7 0 8 0;
+#X connect 9 0 7 0;
+#X connect 9 0 10 0;
+#X connect 10 0 24 0;
+#X connect 12 0 19 0;
+#X connect 13 0 14 0;
+#X connect 13 1 15 0;
+#X connect 13 2 16 0;
+#X connect 17 0 18 0;
+#X connect 18 0 21 1;
+#X connect 19 0 20 0;
+#X connect 20 0 21 0;
+#X connect 21 0 9 0;
+#X connect 21 1 13 0;
+#X connect 21 2 17 0;
+#X connect 22 0 21 0;
+#X connect 23 0 22 0;
+#X connect 24 0 25 0;
+#X connect 25 0 1 0;
+#X connect 29 0 25 0;
+#X connect 30 0 32 0;
+#X connect 31 0 30 0;
+#X connect 32 0 25 0;
+#X connect 36 0 37 0;
+#X connect 37 0 21 0;
diff --git a/pix_opencv_dft.cc b/pix_opencv_dft.cc
new file mode 100755
index 0000000..e4f5240
--- /dev/null
+++ b/pix_opencv_dft.cc
@@ -0,0 +1,461 @@
+////////////////////////////////////////////////////////
+//
+// GEM - Graphics Environment for Multimedia
+//
+// zmoelnig@iem.kug.ac.at
+//
+// Implementation file
+//
+// Copyright (c) 1997-2000 Mark Danks.
+// Copyright (c) Günther Geiger.
+// Copyright (c) 2001-2002 IOhannes m zmoelnig. forum::für::umläute. IEM
+// Copyright (c) 2002 James Tittle & Chris Clepper
+// For information on usage and redistribution, and for a DISCLAIMER OF ALL
+// WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
+//
+/////////////////////////////////////////////////////////
+
+#include "pix_opencv_dft.h"
+
+CPPEXTERN_NEW(pix_opencv_dft)
+
+/////////////////////////////////////////////////////////
+//
+// pix_opencv_dft
+//
+/////////////////////////////////////////////////////////
+// Constructor
+//
+/////////////////////////////////////////////////////////
+
+pix_opencv_dft :: pix_opencv_dft()
+{
+ int i;
+
+ x_calculate = 1;
+ comp_xsize=0;
+ comp_ysize=0;
+
+ rgb = NULL;
+ rgba = NULL;
+ gray = NULL;
+ input_re = NULL;
+ input_im = NULL;
+ input_co = NULL;
+ dft_A = NULL;
+ image_re = NULL;
+ image_im = NULL;
+ image_mout = NULL;
+}
+
+/////////////////////////////////////////////////////////
+// Destructor
+//
+/////////////////////////////////////////////////////////
+pix_opencv_dft :: ~pix_opencv_dft()
+{
+ //Destroy cv_images to clean memory
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &rgba );
+ //cvReleaseImage( &gray );
+ cvReleaseImage( &input_re );
+ cvReleaseImage( &input_im );
+ cvReleaseImage( &input_co );
+ cvReleaseMat( &dft_A );
+ //cvReleaseImage( &mage_re );
+ //cvReleaseImage( &image_im );
+ //cvReleaseImage( &image_mout );
+
+}
+
+/////////////////////////////////////////////////////////
+// shiftDFT
+//
+/////////////////////////////////////////////////////////
+void pix_opencv_dft :: shiftDFT(CvArr * src_arr, CvArr * dst_arr )
+{
+ CvMat *tmp=NULL;
+ CvMat q1stub, q2stub;
+ CvMat q3stub, q4stub;
+ CvMat d1stub, d2stub;
+ CvMat d3stub, d4stub;
+ CvMat * q1, * q2, * q3, * q4;
+ CvMat * d1, * d2, * d3, * d4;
+
+ CvSize size = cvGetSize(src_arr);
+ CvSize dst_size = cvGetSize(dst_arr);
+ int cx, cy;
+
+ if(dst_size.width != size.width ||
+ dst_size.height != size.height){
+ return;
+ }
+
+ if(src_arr==dst_arr){
+ tmp = cvCreateMat(size.height/2, size.width/2, cvGetElemType(src_arr));
+ }
+
+ cx = size.width/2;
+ cy = size.height/2; // image center
+
+ q1 = cvGetSubRect( src_arr, &q1stub, cvRect(0,0,cx, cy) );
+ q2 = cvGetSubRect( src_arr, &q2stub, cvRect(cx,0,cx,cy) );
+ q3 = cvGetSubRect( src_arr, &q3stub, cvRect(cx,cy,cx,cy) );
+ q4 = cvGetSubRect( src_arr, &q4stub, cvRect(0,cy,cx,cy) );
+ d1 = cvGetSubRect( src_arr, &d1stub, cvRect(0,0,cx,cy) );
+ d2 = cvGetSubRect( src_arr, &d2stub, cvRect(cx,0,cx,cy) );
+ d3 = cvGetSubRect( src_arr, &d3stub, cvRect(cx,cy,cx,cy) );
+ d4 = cvGetSubRect( src_arr, &d4stub, cvRect(0,cy,cx,cy) );
+
+ if(src_arr!=dst_arr)
+ {
+ if( !CV_ARE_TYPES_EQ( q1, d1 )){
+ return;
+ }
+ cvCopy(q3, d1, 0);
+ cvCopy(q4, d2, 0);
+ cvCopy(q1, d3, 0);
+ cvCopy(q2, d4, 0);
+ }
+ else
+ {
+ cvCopy(q3, tmp, 0);
+ cvCopy(q1, q3, 0);
+ cvCopy(tmp, q1, 0);
+ cvCopy(q4, tmp, 0);
+ cvCopy(q2, q4, 0);
+ cvCopy(tmp, q2, 0);
+ }
+ if(src_arr==dst_arr){
+ cvReleaseMat( &tmp );
+ }
+
+}
+
+/////////////////////////////////////////////////////////
+// processImage
+//
+/////////////////////////////////////////////////////////
+void pix_opencv_dft :: processRGBAImage(imageStruct &image)
+{
+ unsigned char *pixels = image.data;
+ int i;
+ CvMat tmp;
+ double m,M;
+ int px,py;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize)) {
+
+ this->comp_xsize=image.xsize;
+ this->comp_ysize=image.ysize;
+
+ //Destroy cv_images to clean memory
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &rgba );
+ //cvReleaseImage( &gray );
+ cvReleaseImage( &input_re );
+ cvReleaseImage( &input_im );
+ cvReleaseImage( &input_co );
+ cvReleaseMat( &dft_A );
+ //cvReleaseImage( &image_re );
+ //cvReleaseImage( &image_im );
+ //cvReleaseImage( &image_mout );
+ //cvReleaseImage( &image_pout );
+
+ //Create cv_images
+ rgb = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 3);
+ rgba = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 4);
+ gray = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 1);
+ input_re = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 1);
+ input_im = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 1);
+ input_co = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 2);
+ dft_M = cvGetOptimalDFTSize( image.ysize - 1 );
+ dft_N = cvGetOptimalDFTSize( image.xsize - 1 );
+ dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 );
+ image_re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
+ image_im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
+ image_mout = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_8U, 1);
+
+ }
+
+ memcpy( rgba->imageData, image.data, image.xsize*image.ysize*4 );
+ cvCvtColor(rgba, gray, CV_BGRA2GRAY);
+
+ if ( x_calculate )
+ {
+ // discrete fourier transform
+ cvScale(gray, input_re, 1.0, 0.0);
+ cvZero(input_im);
+ cvMerge(input_re, input_im, NULL, NULL, input_co);
+
+ // copy A to dft_A and pad dft_A with zeros
+ cvGetSubRect( dft_A, &tmp, cvRect(0,0, gray->width, gray->height));
+ cvCopy( input_co, &tmp, NULL );
+ if( dft_A->cols > gray->width )
+ {
+ cvGetSubRect( dft_A, &tmp, cvRect(gray->width,0, dft_A->cols - gray->width, gray->height));
+ cvZero( &tmp );
+ }
+
+ // no need to pad bottom part of dft_A with zeros because of
+ // use nonzero_rows parameter in cvDFT() call below
+ cvDFT( dft_A, dft_A, CV_DXT_FORWARD, input_co->height );
+
+ // Split Fourier in real and imaginary parts
+ cvSplit( dft_A, image_re, image_im, 0, 0 );
+
+ // Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
+ cvPow( image_re, image_re, 2.0);
+ cvPow( image_im, image_im, 2.0);
+ cvAdd( image_re, image_im, image_re, NULL);
+ cvPow( image_re, image_re, 0.5 );
+
+ // Compute log(1 + Mag)
+ cvAddS( image_re, cvScalarAll(1.0), image_re, NULL ); // 1 + Mag
+ cvLog( image_re, image_re ); // log(1 + Mag)
+
+ // Rearrange the quadrants of Fourier image so that the origin is at
+ // the image center
+ this->shiftDFT( image_re, image_re );
+
+ // normalize image
+ cvMinMaxLoc(image_re, &m, &M, NULL, NULL, NULL);
+ cvScale(image_re, image_re, 255.0/(M-m), 255.0*(-m)/(M-m));
+
+ for( py=0; py<image_re->height; py++ ) {
+ double* ptri = (double*) ( image_re->imageData + py * image_re->widthStep);
+ unsigned char* ptrp = (unsigned char*) ( image_mout->imageData + py * image_mout->widthStep);
+ for( px=0; px<image_re->width; px++ ) {
+ if ( *(ptrp+px) > 255.0 ) post( "pix_opencv_dft : error value over 255" );
+ (*(ptrp+px)) = (unsigned char)( (*(ptri+px)) );
+ }
+ }
+
+ x_calculate=0;
+ }
+
+ cvCvtColor(image_mout, rgba, CV_GRAY2RGBA);
+ memcpy( image.data, rgba->imageData, image.xsize*image.ysize*4 );
+}
+
+void pix_opencv_dft :: processRGBImage(imageStruct &image)
+{
+ unsigned char *pixels = image.data;
+ int i;
+ CvMat tmp;
+ double m,M;
+ int px,py;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize)) {
+
+ this->comp_xsize=image.xsize;
+ this->comp_ysize=image.ysize;
+
+ //Destroy cv_images to clean memory
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &rgba );
+ //cvReleaseImage( &gray );
+ cvReleaseImage( &input_re );
+ cvReleaseImage( &input_im );
+ cvReleaseImage( &input_co );
+ cvReleaseMat( &dft_A );
+ //cvReleaseImage( &image_re );
+ //cvReleaseImage( &image_im );
+ //cvReleaseImage( &image_mout );
+ //cvReleaseImage( &image_pout );
+
+ //Create cv_images
+ rgb = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 3);
+ rgba = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 4);
+ gray = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 1);
+ input_re = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 1);
+ input_im = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 1);
+ input_co = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 2);
+ dft_M = cvGetOptimalDFTSize( image.ysize - 1 );
+ dft_N = cvGetOptimalDFTSize( image.xsize - 1 );
+ dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 );
+ image_re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
+ image_im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
+ image_mout = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_8U, 1);
+
+ }
+
+ memcpy( rgb->imageData, image.data, image.xsize*image.ysize*3 );
+ cvCvtColor(rgb, gray, CV_BGR2GRAY);
+
+ if ( x_calculate )
+ {
+ // discrete fourier transform
+ cvScale(gray, input_re, 1.0, 0.0);
+ cvZero(input_im);
+ cvMerge(input_re, input_im, NULL, NULL, input_co);
+
+ // copy A to dft_A and pad dft_A with zeros
+ cvGetSubRect( dft_A, &tmp, cvRect(0,0, gray->width, gray->height));
+ cvCopy( input_co, &tmp, NULL );
+ if( dft_A->cols > gray->width )
+ {
+ cvGetSubRect( dft_A, &tmp, cvRect(gray->width,0, dft_A->cols - gray->width, gray->height));
+ cvZero( &tmp );
+ }
+
+ // no need to pad bottom part of dft_A with zeros because of
+ // use nonzero_rows parameter in cvDFT() call below
+ cvDFT( dft_A, dft_A, CV_DXT_FORWARD, input_co->height );
+
+ // Split Fourier in real and imaginary parts
+ cvSplit( dft_A, image_re, image_im, 0, 0 );
+
+ // Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
+ cvPow( image_re, image_re, 2.0);
+ cvPow( image_im, image_im, 2.0);
+ cvAdd( image_re, image_im, image_re, NULL);
+ cvPow( image_re, image_re, 0.5 );
+
+ // Compute log(1 + Mag)
+ cvAddS( image_re, cvScalarAll(1.0), image_re, NULL ); // 1 + Mag
+ cvLog( image_re, image_re ); // log(1 + Mag)
+
+ // Rearrange the quadrants of Fourier image so that the origin is at
+ // the image center
+ this->shiftDFT( image_re, image_re );
+
+ // normalize image
+ cvMinMaxLoc(image_re, &m, &M, NULL, NULL, NULL);
+ cvScale(image_re, image_re, 255.0/(M-m), 255.0*(-m)/(M-m));
+
+ for( py=0; py<image_re->height; py++ ) {
+ double* ptri = (double*) ( image_re->imageData + py * image_re->widthStep);
+ unsigned char* ptrp = (unsigned char*) ( image_mout->imageData + py * image_mout->widthStep);
+ for( px=0; px<image_re->width; px++ ) {
+ if ( *(ptrp+px) > 255.0 ) post( "pix_opencv_dft : error value over 255" );
+ (*(ptrp+px)) = (unsigned char)( (*(ptri+px)) );
+ }
+ }
+
+ x_calculate=0;
+ }
+
+ cvCvtColor(image_mout, rgb, CV_GRAY2RGB);
+ memcpy( image.data, rgb->imageData, image.xsize*image.ysize*3 );
+}
+
+void pix_opencv_dft :: processYUVImage(imageStruct &image)
+{
+}
+
+void pix_opencv_dft :: processGrayImage(imageStruct &image)
+{
+ unsigned char *pixels = image.data;
+ int i;
+ CvMat tmp;
+ double m,M;
+ int px,py;
+
+ if ((this->comp_xsize!=image.xsize)&&(this->comp_ysize!=image.ysize)) {
+
+ this->comp_xsize=image.xsize;
+ this->comp_ysize=image.ysize;
+
+ //Destroy cv_images to clean memory
+ cvReleaseImage( &rgb );
+ cvReleaseImage( &rgba );
+ //cvReleaseImage( &gray );
+ cvReleaseImage( &input_re );
+ cvReleaseImage( &input_im );
+ cvReleaseImage( &input_co );
+ cvReleaseMat( &dft_A );
+ //cvReleaseImage( &image_re );
+ //cvReleaseImage( &image_im );
+ //cvReleaseImage( &image_mout );
+ //cvReleaseImage( &image_pout );
+
+ //Create cv_images
+ rgb = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 3);
+ rgba = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 4);
+ gray = cvCreateImage(cvSize(image.xsize,image.ysize), IPL_DEPTH_8U, 1);
+ input_re = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 1);
+ input_im = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 1);
+ input_co = cvCreateImage( cvGetSize(rgb), IPL_DEPTH_64F, 2);
+ dft_M = cvGetOptimalDFTSize( image.ysize - 1 );
+ dft_N = cvGetOptimalDFTSize( image.xsize - 1 );
+ dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 );
+ image_re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
+ image_im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1);
+ image_mout = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_8U, 1);
+
+ }
+
+ memcpy( gray->imageData, image.data, image.xsize*image.ysize );
+
+ if ( x_calculate )
+ {
+ // discrete fourier transform
+ cvScale(gray, input_re, 1.0, 0.0);
+ cvZero(input_im);
+ cvMerge(input_re, input_im, NULL, NULL, input_co);
+
+ // copy A to dft_A and pad dft_A with zeros
+ cvGetSubRect( dft_A, &tmp, cvRect(0,0, gray->width, gray->height));
+ cvCopy( input_co, &tmp, NULL );
+ if( dft_A->cols > gray->width )
+ {
+ cvGetSubRect( dft_A, &tmp, cvRect(gray->width,0, dft_A->cols - gray->width, gray->height));
+ cvZero( &tmp );
+ }
+
+ // no need to pad bottom part of dft_A with zeros because of
+ // use nonzero_rows parameter in cvDFT() call below
+ cvDFT( dft_A, dft_A, CV_DXT_FORWARD, input_co->height );
+
+ // Split Fourier in real and imaginary parts
+ cvSplit( dft_A, image_re, image_im, 0, 0 );
+
+ // Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
+ cvPow( image_re, image_re, 2.0);
+ cvPow( image_im, image_im, 2.0);
+ cvAdd( image_re, image_im, image_re, NULL);
+ cvPow( image_re, image_re, 0.5 );
+
+ // Compute log(1 + Mag)
+ cvAddS( image_re, cvScalarAll(1.0), image_re, NULL ); // 1 + Mag
+ cvLog( image_re, image_re ); // log(1 + Mag)
+
+ // Rearrange the quadrants of Fourier image so that the origin is at
+ // the image center
+ this->shiftDFT( image_re, image_re );
+
+ // normalize image
+ cvMinMaxLoc(image_re, &m, &M, NULL, NULL, NULL);
+ cvScale(image_re, image_re, 255.0/(M-m), 255.0*(-m)/(M-m));
+
+ for( py=0; py<image_re->height; py++ ) {
+ double* ptri = (double*) ( image_re->imageData + py * image_re->widthStep);
+ unsigned char* ptrp = (unsigned char*) ( image_mout->imageData + py * image_mout->widthStep);
+ for( px=0; px<image_re->width; px++ ) {
+ if ( *(ptrp+px) > 255.0 ) post( "pix_opencv_dft : error value over 255" );
+ (*(ptrp+px)) = (unsigned char)( (*(ptri+px)) );
+ }
+ }
+
+ x_calculate=0;
+ }
+
+ memcpy( image.data, image_mout->imageData, image.xsize*image.ysize );
+}
+
+/////////////////////////////////////////////////////////
+// static member function
+//
+/////////////////////////////////////////////////////////
+
+void pix_opencv_dft :: obj_setupCallback(t_class *classPtr)
+{
+ class_addmethod(classPtr, (t_method)&pix_opencv_dft::calculateCallback,
+ gensym("bang"), A_NULL);
+}
+
+void pix_opencv_dft :: calculateCallback(void *data)
+{
+ GetMyClass(data)->x_calculate = 1.0;
+}
diff --git a/pix_opencv_dft.h b/pix_opencv_dft.h
new file mode 100755
index 0000000..a3c4a08
--- /dev/null
+++ b/pix_opencv_dft.h
@@ -0,0 +1,88 @@
+/*-----------------------------------------------------------------
+LOG
+ GEM - Graphics Environment for Multimedia
+
+ Change pix to greyscale
+
+ Copyright (c) 1997-1999 Mark Danks. mark@danks.org
+ Copyright (c) Günther Geiger. geiger@epy.co.at
+ Copyright (c) 2001-2002 IOhannes m zmoelnig. forum::für::umläute. IEM. zmoelnig@iem.kug.ac.at
+ Copyright (c) 2002 James Tittle & Chris Clepper
+ For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ WARRANTIES, see the file, "GEM.LICENSE.TERMS" in this distribution.
+
+-----------------------------------------------------------------*/
+
+#ifndef INCLUDE_PIX_OPENCV_DISTRANS_H_
+#define INCLUDE_PIX_OPENCV_DISTRANS_H_
+
+#include "Base/GemPixObj.h"
+
+#ifndef _EiC
+#include "cv.h"
+#endif
+
+/*-----------------------------------------------------------------
+-------------------------------------------------------------------
+CLASS
+ pix_opencv_dft
+
+ Change pix to greyscale
+
+KEYWORDS
+ pix
+
+DESCRIPTION
+
+-----------------------------------------------------------------*/
+class GEM_EXTERN pix_opencv_dft : public GemPixObj
+{
+ CPPEXTERN_HEADER(pix_opencv_dft, GemPixObj)
+
+ public:
+
+ //////////
+ // Constructor
+ pix_opencv_dft();
+
+ protected:
+
+ //////////
+ // Destructor
+ virtual ~pix_opencv_dft();
+
+ //////////
+ // Do the processing
+ virtual void processRGBAImage(imageStruct &image);
+ virtual void processRGBImage(imageStruct &image);
+ virtual void processYUVImage(imageStruct &image);
+ virtual void processGrayImage(imageStruct &image);
+
+ int comp_xsize;
+ int comp_ysize;
+ int x_calculate;
+ int dft_M;
+ int dft_N;
+
+ private:
+
+ //////////
+ // Static member functions
+ static void calculateCallback(void *data);
+ static void shiftDFT(CvArr*, CvArr*);
+
+ // The output and temporary images
+ IplImage *rgb;
+ IplImage *rgba;
+ IplImage *gray;
+ IplImage *input_re;
+ IplImage *input_im;
+ IplImage *input_co;
+ CvMat *dft_A;
+ IplImage *image_re;
+ IplImage *image_im;
+ IplImage *image_mout;
+
+};
+
+#endif // for header file