From 85236329aa410d21cb81c4c9079c6c35a367923d Mon Sep 17 00:00:00 2001 From: Michal Vokac Date: Wed, 8 Dec 2010 19:08:02 +0100 Subject: [PATCH] barcam: add "realtime" plot of DFT result in gnuplot window using c2gnuplot lib. --- src/camera/barcam/barcam.cxx | 162 +++++++++++------------------------ 1 file changed, 52 insertions(+), 110 deletions(-) diff --git a/src/camera/barcam/barcam.cxx b/src/camera/barcam/barcam.cxx index b5ef8260..5fa88a6c 100644 --- a/src/camera/barcam/barcam.cxx +++ b/src/camera/barcam/barcam.cxx @@ -5,7 +5,7 @@ * Created for Eurobot 2010 competition. * * Petr Kubizňák (kubiznak.petr@gmail.com), 2010 - * rewriten by Mihal Vokac (vokac.m@gmail.com), for Eurobot 2011 + * rewriten by Michal Vokac (vokac.m@gmail.com), for Eurobot 2011 * * This program is used to recognize type of playing elements (pawns, qeens, * kings) in Eurobot 2011 competition. @@ -50,13 +50,17 @@ #include #include #include +#include #include #include +// gnuplot fifo plot +#include + extern "C" { #include -#include +//#include } /******************************************************************************/ @@ -320,119 +324,58 @@ int countThreshold(const IplImage *frame) * @param frame Frame to be processed. * @return */ int recognize(IplImage* gray_frame) { - - int i, j, k; - - double eps = 0.00000000001; - - -// int n = gray_frame->height; -// -// double *rdata, *idata; -// fftw_plan rplan; -// -// rdata = (double*) malloc(sizeof(double) * n); -// idata = (double*) malloc(sizeof(double) * n); -// -// rplan = fftw_plan_r2r_1d(n, rdata, idata, FFTW_R2HC, FFTW_ESTIMATE); -// -// // we have no imaginary data, so clear idata -// memset((void *)idata, 0, n * sizeof(double)); -// -// // fill rdata with actual data -// for (i = 0; i < n; i++) { -// rdata[i] = ((uchar*)(gray_frame->imageData + i*gray_frame->widthStep))[(gray_frame->width/2)*3]; -// } -// -// fftw_execute(rplan); -// -// // post-process FFT data: make absolute values, and calculate -// // real frequency of each power line in the spectrum -// int m = 0; -// double absval = 0; -// double cc = 0; -// double correction = (double)255 / (double)n; -// -// // TODO plot spectra in graph -// for (i = 0; i < (n-2); i++) { -// absval = sqrt(idata[i] * idata[i]); -// cc = (double)m * correction; -// -// // this is used to present the result somehow -// ((uchar*)(gray_frame->imageData + i*gray_frame->widthStep))[(gray_frame->width/2)*3] = absval; -// -// fprintf(stderr, "i:%d cc:%f abs:%f\n",i, cc, absval); -// m++; -// } - -// fftw_destroy_plan(rplan); -// free(idata); -// free(rdata); - -/** - experiment with 2d dft, - laborating with size of data for dft, (original img size or nearest 2^N size) - it is possible to use another fftw plan, e.g. fftw_plan_dft_1d.. - - I need to normalize the spectrum properly, search for high frequency - and then make decision if there is an barcode in the image. -*/ - int w = gray_frame->width; - int h = gray_frame->height; - int w2 = cvGetOptimalDFTSize(gray_frame->width); - int h2 = cvGetOptimalDFTSize(gray_frame->height); - - /*initialize arrays for fftw operations */ - fftw_complex *src = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * w * h); - - fftw_complex *fft = ( fftw_complex* )fftw_malloc( sizeof( fftw_complex ) * w * h); - - /* create plans */ - fftw_plan plan_f = fftw_plan_dft_2d(h , w, src, fft, FFTW_FORWARD, FFTW_ESTIMATE ); + // create gnuplot window + static gnuplot_window window; + int i = 0; + int n = gray_frame->height; + int m = 0; + double absval = 0; + double cc = 0; + double correction = (double)255 / (double)n; - /* load data to fft input */ - for( i = 0, k = 0 ; i < h ; i++ ) { - for( j = 0 ; j < w ; j++ ) { - src[k][0] = ( double )gray_frame->imageData[i * gray_frame->widthStep + j]; - src[k][1] = 0.0; - k++; - } - } + double *rdata, *idata; + fftw_plan rplan; + + rdata = (double*) malloc(sizeof(double) * n); + idata = (double*) malloc(sizeof(double) * n); -// // pad fft with zeros -// for( i = h, k = h ; i < h2 ; i++ ) { -// for( j = w ; j < w2; j++ ) { -// src[k][0] = 0; -// src[k][1] = 0; -// k++; -// } -// } - - /* perform FFT */ - fftw_execute( plan_f ); + rplan = fftw_plan_r2r_1d(n, rdata, idata, FFTW_R2HC, FFTW_ESTIMATE); + + // we have no imaginary data, so clear idata + memset((void *)idata, 0, n * sizeof(double)); + + // fill rdata with actual data + for (i = 0; i < n; i++) { + rdata[i] = ((uchar*)(gray_frame->imageData + i*gray_frame->widthStep))[(gray_frame->width/2)*3]; - /* normalize FFT result */ - for( i = 0 ; i < ( gray_frame->width * gray_frame->height ) ; i++ ) { - fft[i][0] /= ( double )( gray_frame->width * gray_frame->height ); - fft[i][0] = sqrt(fft[i][0] * fft[i][0]); - fft[i][0] = log(fft[i][0] + eps); + // draw black line in the midle of the image where DFT is computed + ((uchar*)(gray_frame->imageData + i*gray_frame->widthStep))[(gray_frame->width/2)*3] = 0; } - //TODO zero - shift the fft image + fftw_execute(rplan); + + // set plot parameters + window.plot_data("u 1:2 w p ps 2"); + + // post-process FFT data: make absolute values, and calculate + // real frequency of each power line in the spectrum + for (i = 0; i < (n-2); i++) { + absval = sqrt(idata[i] * idata[i]); + cc = (double)m * correction; + m++; - /* copy FFT result to gray_frame */ - for( i = 0, k = 0 ; i < h ; i++ ) { - for( j = 0 ; j < w ; j++ ) { - gray_frame->imageData[i * gray_frame->widthStep + j] = (uchar)fft[k++][0]; - } + // plot fft data, do not plot first 10 values + if (i > 10) window.data("%f, %f",cc,absval); } - fftw_free(fft); - fftw_free(src); - - fftw_destroy_plan(plan_f); + // plot values from FIFO + window.flush(); + + fftw_destroy_plan(rplan); + free(idata); + free(rdata); return 0; } @@ -459,8 +402,6 @@ int modeImage(char *imageFilename) while (1) { - //TODO do something useful with the image - recognize(frame); // wait infinitely for a keyboard event switch((char)(cvWaitKey(0) & 0xFF)) { @@ -621,7 +562,7 @@ int modeRecognize(CvCapture* capture, CvRect *roi) int ret; IplImage *frame = NULL; IplImage *roi_frame = cvCreateImage(cvSize(roi->width, roi->height), 8, 1); - + while (camera_control_on) { if ((ret = recognizeMode_processKeys(roi_frame)) != MODE_RECOGNIZE) @@ -639,10 +580,12 @@ int modeRecognize(CvCapture* capture, CvRect *roi) //ORTEPublicationSend(orte.publication_camera_result); // } + // set region of interest on captured image cvSetImageROI(frame, *roi); + // copy ROI part of captured image to roi_frame and convert to grayscale cvCvtColor(frame, roi_frame, CV_BGR2GRAY); - + //TODO call image processing (do something useful with the image, FFT atc.) ret = recognize(roi_frame); @@ -657,7 +600,6 @@ int modeRecognize(CvCapture* capture, CvRect *roi) // ORTEPublicationSend(orte.publication_camera_result); } - return MODE_WAIT; } -- 2.39.2