Witam!
Pracuje aktualnie nad algorytmem który ma za zadanie "wykryć" na obrazie wejściowym rejestrację samochodową (temat pracy licencjackiej) . Po przeprowadzeniu szybkiej transformaty fouriera i otrzymaniu widma obrazu chcę na tym widmie zastosować filtr górnoprzepustowy lub dolnoprzepustowy i wykonać odwrotną transformate fouriera aby zobaczyć jak będzie wyglądał obraz po zastosowaniu filtrów.
Korzystam przy tym z biblioteki OpenCV, fftw3, Qt 4.7.
A o to co mam:
////////////////////////////////////////////////////////////////////////*/ converter.h *//////////////////
#ifndef CONVERTER_H
#define CONVERTER_H
#include <iostream>
#include <fftw3.h>
#include <cv.h>
#include <highgui.h>
#include <QImage>
#include <QPixmap>
#include <QPicture>
#include <QRgb>
using namespace cv;
class Converter{
public:
Converter();
~Converter();
QImage makeN2Dimension(const QImage qImage);
void transform(char* fileName);
private:
IplImage *img1;
IplImage *img2;
uchar *img1_data;
uchar *img2_data;
fftw_complex *data_in;
fftw_complex *fft;
fftw_complex *ifft;
fftw_plan plan_f;
fftw_plan plan_b;
int width, height, step;
};
#endif // CONVERTER_H
////////////////////////////////////////////////////////////////////////*/ converter.cpp *//////////////
#include <converter.h>
// Konstructor
Converter::Converter(){
img1 = 0;
img2 = 0;
data_in = 0;
fft = 0;
ifft = 0;
plan_f = 0;
plan_b = 0;
}
// Destructor
Converter::~Converter(){
// Zwolnij pamięć
if(img1 != 0)
cvReleaseImage(&img1);
if(img2 != 0)
cvReleaseImage(&img2);
if(plan_f != 0)
fftw_destroy_plan(plan_f);
if(plan_b != 0)
fftw_destroy_plan(plan_b);
if(data_in != 0)
fftw_free( data_in );
if(fft != 0)
fftw_free( fft );
if(ifft != 0)
fftw_free( ifft );
}
// Dopełnia obraz tak aby boki były tej samej długości
QImage Converter::makeN2Dimension(const QImage qImage){
QImage n2Image;
int h = qImage.height();
int w = qImage.width();
if(w == h) return qImage;
if(w == 0 || h == 0) return QImage(100, 100, QImage::Format_RGB888);
w > h ? n2Image = QImage(w, w, QImage::Format_RGB888) :
n2Image = QImage(h, h, QImage::Format_RGB888);
for(int i = 0; i < w; i++)
for(int j = 0; j < h; j++)
n2Image.setPixel(i,j, qImage.pixel(i,j));
return n2Image;
}
void Converter::transform(char* fileName){
// Wczytaj orginalny obraz
img1 = cvLoadImage(fileName, CV_LOAD_IMAGE_GRAYSCALE);
// Sprawdź plik
if(fileName == 0){
std::cout<<"Couldn't load file: "<< fileName <<std::endl;
return;
}
img2 = cvCreateImage(cvSize(img1->height, img1->height), IPL_DEPTH_8U, 1);
// Pobierz właściwości obrazu
width = img1->width;
height = img1->height;
step = img1->widthStep;
img1_data = (uchar*)img1->imageData;
img2_data = (uchar*)img2->imageData;
// Inicjalizacja tablic dla operacji fftw
data_in = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height);
fft = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height);
ifft = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * width * height);
// Stwórz plan
plan_f = fftw_plan_dft_1d(width * height, data_in, fft, FFTW_FORWARD, FFTW_ESTIMATE);
plan_b = fftw_plan_dft_1d(width * height, fft, ifft, FFTW_BACKWARD, FFTW_ESTIMATE);
// Wczytaj dane z img1_data do fftw
for(int i = 0, k = 0; i < height; i++){
for(int j = 0; j < width; j++){
data_in[k][0] = (double)img1_data[i * step + j];
data_in[k][1] = 0.0;
k++;
}
}
// Przeprowadź FFT
fftw_execute(plan_f);
/*
Wydaje mi się że w tym miejscu należy zastosować filtry
na 'fft'
*/
// Przeprowadź IFFT
fftw_execute(plan_b);
// Normalizacja wyników IFFT
for(int i = 0; i < (width * height); i++){
ifft[i][0] /= (double)(width * height);
}
// Kopiowanie wyników IFFT do img2_data
for(int i = 0, k = 0; i < height; i++){
for(int j = 0; j < width; j++){
img2_data[i * step + j] = (uchar)ifft[k++][0];
}
}
// Wyświetl obrazy
cvNamedWindow("Obraz", CV_WINDOW_AUTOSIZE);
cvNamedWindow("IFFT", CV_WINDOW_AUTOSIZE);
cvShowImage("Obraz", img1);
cvShowImage("IFFT", img2);
cvWaitKey(0);
// Zwolnij pamięć
cvDestroyWindow("Obraz");
cvDestroyWindow("IFFT");
}
Problem jest taki, że zabardzo nie wiem jak dany filtr zaimplementować.