Vicul 0 Жалоба Опубликовано August 10, 2009 Всем привет, кто-нибудь подкиньте пример с cvDFT(), реально работающий, ну чтобы на входе картинка и на выходе ее результат. Заранее благодарю. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано August 10, 2009 Всем привет, кто-нибудь подкиньте пример с cvDFT(), реально работающий, ну чтобы на входе картинка и на выходе ее результат. Заранее благодарю. Можно здесь глянуть: http://nashruddin.com/an-example-on-using-...ith-opencv.html, не cvDFT но вроде работает. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Vicul 0 Жалоба Опубликовано August 11, 2009 За библиотеку спасибо, но хотелось бы посмотреть, как работает cvDFT() для обучения. В книге по OpenCV есть пример, но я его не могу понять как его в реальности применить. Пытался сделать, как я его понимаю, в результате получил черное пятно в белой рамке. Поэтому хочу посмотреть живой пример для этой функции. На всякий случай привожу свой код, может кто подскажет, где я неправ. /* Take the Fourier transform of a small Gaussian distribution and the Fourier transform of an image. Multiply them and take the inverse Fourier transform of the results. What have you achieved? As the filters get bigger, you will find that working in the Fourier space is much faster than in the normal space. */ IplImage* img = cvLoadImage("Img17.jpeg"); IplImage* dst = cvCreateImage(cvSize(2*img->width -1, 2*img->height -1), IPL_DEPTH_32F, 1); IplImage* dst2 = cvCreateImage(cvSize(2*img->width -1, 2*img->height -1), IPL_DEPTH_8U, 1); cvZero(dst); cvZero(dst2); cvNamedWindow("Img", 0); cvShowImage("Img", img); //sobel IplImage* gauss = cvCloneImage(img); cvZero(gauss); cvSmooth(img, gauss, CV_GAUSSIAN, 3); cvNamedWindow("Gauss", 0); cvShowImage("Gauss", gauss); //fourier img IplImage* img2 = cvCreateImage(cvSize(img->width, img->height), IPL_DEPTH_32F, 3); cvZero(img2); cvConvertScale(img, img2); cvReleaseImage(&img); IplImage* img3 = cvCreateImage(cvSize(img2->width, img2->height), img2->depth, 1); cvSplit(img2, img3, NULL, NULL, NULL); cvReleaseImage(&img2); int dft_M = cvGetOptimalDFTSize(2 * img3->height -1); int dft_N = cvGetOptimalDFTSize(2 * img3->width -1); CvMat tmp; CvMat* dft_img = cvCreateMat(dft_M, dft_N, CV_32FC1); cvGetSubRect(dft_img, &tmp, cvRect(0, 0, img3->width, img3->height)); cvCopy(img3, &tmp); cvGetSubRect(dft_img, &tmp, cvRect(img3->width, 0, dft_img->cols-img3->width, img3->height)); cvZero(&tmp); cvDFT(dft_img, dft_img, CV_DXT_FORWARD, img3->height); cvReleaseImage(&img3); cvNamedWindow("Fourier_img", 0); cvShowImage("Fourier_img", dft_img); //fourier gaussian IplImage* gauss2 = cvCreateImage(cvSize(gauss->width, gauss->height), IPL_DEPTH_32F, gauss->nChannels); cvZero(gauss2); cvConvertScale(gauss, gauss2); cvReleaseImage(&gauss); IplImage* gauss3 = cvCreateImage(cvSize(gauss2->width, gauss2->height), gauss2->depth, 1); cvSplit(gauss2, gauss3, NULL, NULL, NULL); cvReleaseImage(&gauss2); CvMat* dft_gauss = cvCreateMat(dft_M, dft_N, CV_32FC1); cvGetSubRect(dft_gauss, &tmp, cvRect(0, 0, gauss3->width, gauss3->height)); cvCopy(gauss3, &tmp); cvGetSubRect( dft_gauss, &tmp, cvRect(gauss3->width, 0, dft_gauss->width-gauss3->width, gauss3->height)); cvZero(&tmp); cvDFT(dft_gauss, dft_gauss, CV_DXT_FORWARD, gauss3->height); cvReleaseImage(&gauss3); cvNamedWindow("Fourier_gauss", 0); cvShowImage("Fourier_gauss", dft_img); //mul cvMulSpectrums(dft_img, dft_gauss, dft_gauss, CV_DXT_FORWARD); cvDFT(dft_gauss, dft_gauss, CV_DXT_INV_SCALE, dst->height); cvGetSubRect(dft_gauss, &tmp, cvRect(0, 0, dst->width, dst->height)); cvCopy(&tmp, dst); cvReleaseMat(&dft_gauss); cvReleaseMat(&dft_img); // cvConvertScale(dst, dst2); cvNamedWindow("Fourier", 0); cvShowImage("Fourier", dst); cvReleaseImage(&dst); cvReleaseImage(&dst2); cvWaitKey(0); cvDestroyAllWindows(); Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано August 11, 2009 За библиотеку спасибо, но хотелось бы посмотреть, как работает cvDFT() для обучения. В книге по OpenCV есть пример, но я его не могу понять как его в реальности применить. Пытался сделать, как я его понимаю, в результате получил черное пятно в белой рамке. Поэтому хочу посмотреть живой пример для этой функции. В папке с примерами есть такой код (opencv\samples\c\dft.c), скорее всего, Вам просто нужно правильно преобразовать шкалы. #include <cxcore.h> #include <cv.h> #include <highgui.h> // Rearrange the quadrants of Fourier image so that the origin is at // the image center // src & dst arrays of equal size & type void cvShiftDFT(CvArr * src_arr, CvArr * dst_arr ) { CvMat * tmp; 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){ cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ ); } 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 )){ cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ ); } 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); } } int main(int argc, char ** argv) { const char* filename = argc >=2 ? argv[1] : "lena.jpg"; IplImage * im; IplImage * realInput; IplImage * imaginaryInput; IplImage * complexInput; int dft_M, dft_N; CvMat* dft_A, tmp; IplImage * image_Re; IplImage * image_Im; double m, M; im = cvLoadImage( filename, CV_LOAD_IMAGE_GRAYSCALE ); if( !im ) return -1; realInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1); imaginaryInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1); complexInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 2); cvScale(im, realInput, 1.0, 0.0); cvZero(imaginaryInput); cvMerge(realInput, imaginaryInput, NULL, NULL, complexInput); dft_M = cvGetOptimalDFTSize( im->height - 1 ); dft_N = cvGetOptimalDFTSize( im->width - 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); // copy A to dft_A and pad dft_A with zeros cvGetSubRect( dft_A, &tmp, cvRect(0,0, im->width, im->height)); cvCopy( complexInput, &tmp, NULL ); if( dft_A->cols > im->width ) { cvGetSubRect( dft_A, &tmp, cvRect(im->width,0, dft_A->cols - im->width, im->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, complexInput->height ); cvNamedWindow("win", 0); cvNamedWindow("magnitude", 0); cvShowImage("win", im); // 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 cvShiftDFT( image_Re, image_Re ); cvMinMaxLoc(image_Re, &m, &M, NULL, NULL, NULL); cvScale(image_Re, image_Re, 1.0/(M-m), 1.0*(-m)/(M-m)); cvShowImage("magnitude", image_Re); cvWaitKey(-1); return 0; }[/code] Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Vicul 0 Жалоба Опубликовано August 11, 2009 Спасибо за инфу, теперь начало доходить что к чему. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Wildcat 2 Жалоба Опубликовано November 27, 2009 А вот еще вопрос по преобразованию фурье: Тут в примере приведено комплексное преобразование Фурье. (оно осуществляется над комплексным представлением сигнала). Но есть также возможность осуществлять преобразование над вещественным сигналом с помощью функции cvDFT. Результаты будут разные или это только вопрос как будут располагаться числа в выходной матрице. Вопрос возник так ака недавно нашла статью, в которой рассказывается разница между вещественным преобразованием Фурье и комплексным. Саму статью можно почитать по ссылке: http://www.google.ru/url?sa=t&source=w...rqXEGbQRhmWMGCA там глава 31. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано November 27, 2009 Да, разница видимо есть, и она подробно описана начиная со страницы №5 того документа, который Вы прикрепили. (правда русский перевод немного бредовый ) Вообще документик интересный и полезный, надо будет перевести нормально. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано March 22, 2011 есть ли какой то смысл\возможность использовать cvDFT вместо cvMatchTemplate?(для поиска пересечения 2-х изображений) есть ли смысл использовать FFTW может будет быстрее? Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 22, 2011 В детали не вдавался, но cvMatchTemplate внутри себя вызывает функцию icvCrossCorr, которая использует cvDFT. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано March 23, 2011 ну тут как бы с одной стороны важно понять как это делается математически, а с другой как это быстрее реализовано технически. cvMatchTemplate использует большое поле на одном изображении и ищет на нем маленький кусок со второго. http://nashruddin.com/phase-correlation-function-in-opencv.html#results вот есть еще такая вещь через FFTW, но тут походу смотрится корреляция 2-х изображений целиком. может возможно ее как то переделать как cvMatchTemplate для кусков изображения? а то я самой математической подоплеки не особо понимаю. причем в icvCrossCorr еще интересный комментарий // disable OpenMP in the case of Visual Studio, // otherwise the performance drops significantly Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано March 24, 2011 еще возможно у кого то есть идеи насчет http://fly.mpi-cbg.de/~preibisch/software.html http://pacific.mpi-cbg.de/wiki/index.php/Downloads попробовать можно скачав тут.плагин Stitch2D. там можно задавать кол-во пиков для нахождения.(вроде бы находит точнее, чем если использовать 1 пик) я не понимаю как это можно использовать, ибо после использования cvMatchTemplate обычно ищут всего 1 пик. и что за глобальная оптимизация? If more than two input images/stacks are used the correct placement of all tiles is determined using a global optimization. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Smorodov 579 Жалоба Опубликовано April 22, 2011 Программа для экспериментов с преобразованием Фурье. Содержит примеры разложения изображения на действительную и мнимую части спектра, и для разложения изображения на амплитудную и фазовую части спектра, а так-же обратные преобразования для обоих типов разложения. На картинке я вырезал кольцо из амплитудной и фазовой составляющей спектра разложения. И провел обратное преобразование. Исходник: FFT.RAR 2 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах