Bonjour,

j'aurais besoin d'implanter un filtre homomorphique pour réaliser du traitement sur des images prises sous l'eau. Je "comprend" les différentes étapes à réaliser mais je n'obtiens pas de résultat correct (image noire). J'ai essayé de normaliser mon résultat au vu des valeurs qu'il contient mais sans succès. Je me suis beaucoup inspiré des codes trouvés.

Voici mes différentes méthodes implémentées :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
void HomomorphicFilter::butterworth_homomorphic_filter(Mat &dft_Filter, int D, int n, float high_h_v_TB, float low_h_v_TB)
{
    Mat single(dft_Filter.rows, dft_Filter.cols, CV_32F);
    Point centre = Point(dft_Filter.rows/2, dft_Filter.cols/2);
    double radius;
    float upper = (high_h_v_TB * 0.01);
    float lower = (low_h_v_TB * 0.01);
 
    //create essentially create a butterworth highpass filter
    for(int i = 0; i < dft_Filter.rows; i++)
    {
        for(int j = 0; j < dft_Filter.cols; j++)
        {
            radius = (double) sqrt(pow((i - centre.x), 2.0) + pow((double) (j - centre.y), 2.0));
            single.at<float>(i,j) =((upper - lower) * (1/(1 + pow((double) (D/radius), (double) (2*n))))) + lower;
        }
    }
 
    //Apply filter
    mulSpectrums( dft_Filter, single, dft_Filter, 0);
}
 
void HomomorphicFilter::Shifting_DFT(Mat &fImage)
{
    //For visualization purposes we may also rearrange the quadrants of the result, so that the origin (0,0), corresponds to the image center.
    Mat tmp, q0, q1, q2, q3;
 
    /*First crop the image, if it has an odd number of rows or columns.
    Operator & bit to bit by -2 (two's complement : -2 = 111111111....10) to eliminate the first bit 2^0 (In case of odd number on row or col, we take the even number in below)*/
    fImage = fImage(Rect(0, 0, fImage.cols & -2, fImage.rows & -2));
    int cx = fImage.cols/2;
    int cy = fImage.rows/2;
 
    /*Rearrange the quadrants of Fourier image so that the origin is at the image center*/
    q0 = fImage(Rect(0, 0, cx, cy));
    q1 = fImage(Rect(cx, 0, cx, cy));
    q2 = fImage(Rect(0, cy, cx, cy));
    q3 = fImage(Rect(cx, cy, cx, cy));
 
    /*We reverse each quadrant of the frame with its other quadrant diagonally opposite*/
    /*We reverse q0 and q3*/
    q0.copyTo(tmp);
    q3.copyTo(q0);
    tmp.copyTo(q3);
 
    /*We reverse q1 and q2*/
    q1.copyTo(tmp);
    q2.copyTo(q1);
    tmp.copyTo(q2);
}
 
void HomomorphicFilter::Fourier_Transform(Mat frame_bw, Mat &image_phase, Mat &image_mag)
{
    Mat frame_log;
    frame_bw.convertTo(frame_log, CV_32F);
    /*1. Take the natural log
    Take the natural log of the input (compute log(1 + Mag)*/
    frame_log += 1;
    log( frame_log, frame_log); // log(1 + Mag)
 
    /*2. Expand the image to an optimise size
    The performance of the DFT depends of the image size. It tends to be the fastest for image sizes that are multiple of 2, 3 or 5.
    We can use the copyMakeBorder() function to expand the borders of an image.*/
    Mat padded;
    int M = getOptimalDFTSize(frame_log.rows);
    int N = getOptimalDFTSize(frame_log.cols);
    copyMakeBorder(frame_log, padded, 0, M - frame_log.rows, 0, N - frame_log.cols, BORDER_CONSTANT, Scalar::all(0));
 
    /*3. Make place for both the complex and real values
    The result of the DFT is a complex. Then the result is 2 images (Imaginary + Real), and the frequency domains range is much larger than the spatial one.    Therefore we need to store in float !
    That's why we will convert our input image "padded" to float and expand it to another channel to hold the complex values.
    Planes is an arrow of 2 matrix (planes[0] = Real part, planes[1] = Imaginary part)*/
    Mat image_planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat image_complex;
    /*Creates one multichannel array out of several single-channel ones.*/
    merge(image_planes, 2, image_complex);
 
    /*4. Make the DISCRETE FOURIER TRANSFORM
    The result of thee DFT is a complex image : "image_complex"*/
    dft(image_complex, image_complex);
 
    /***************************/
    //Create spectrum magnitude//
    /***************************/
    /*5. Transform the real and complex values to magnitude*/
    split(image_complex, image_planes);
    //Starting with this part we have the real part of the image in planes[0] and the imaginary in planes[1]
    phase(image_planes[0], image_planes[1], image_phase);
    magnitude(image_planes[0], image_planes[1], image_mag);
}
 
void HomomorphicFilter::Inv_Fourier_Transform(Mat image_phase, Mat image_mag, Mat &inverseTransform)
{
    /*Calculates x and y coordinates of 2D vectors from their magnitude and angle.*/
    Mat result_planes[2];
    polarToCart(image_mag, image_phase, result_planes[0], result_planes[1]);
 
    /*Creates one multichannel array out of several single-channel ones.*/
    Mat result_complex;
    merge(result_planes, 2, result_complex);
 
    /*Make the IDFT*/
    dft(result_complex, inverseTransform, DFT_INVERSE|DFT_REAL_OUTPUT);
 
    /*Take the exponentiel*/
    exp(inverseTransform, inverseTransform);
}
et la partie du main :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**************************/
        /****Homomorphic filter****/
        /**************************/
        /**********************************************/
        //Getting the frequency and magnitude of image//
        /**********************************************/
        Mat image_phase, image_mag;
        HomomorphicFilter().Fourier_Transform(frame_bw, image_phase, image_mag);
        /******************/
        //Shifting the DFT//
        /******************/
        HomomorphicFilter().Shifting_DFT(image_mag);
        /********************************/
        //Butterworth homomorphic filter//
        /********************************/
        int high_h_v_TB = 101;
        int low_h_v_TB = 99;
        int D = 10;// radius of band pass filter parameter
        int order = 2;// order of band pass filter parameter
        HomomorphicFilter().butterworth_homomorphic_filter(image_mag, D, order, high_h_v_TB, low_h_v_TB);
        /******************/
        //Shifting the DFT//
        /******************/
        HomomorphicFilter().Shifting_DFT(image_mag);
        /*******************************/
        //Inv Discret Fourier Transform//
        /*******************************/
        Mat inverseTransform;
        HomomorphicFilter().Inv_Fourier_Transform(image_phase, image_mag, inverseTransform);
 
        imshow("Result_final", inverseTransform);

Si quelqu'un pouvait m'expliquer mes erreurs/m'orienter vers une solution, j'apprécierais beaucoup . Merci

EDIT : J'arrive maintenant à avoir un résultat final mais il est loin d'être exploitable...
Pour obtenir ce résultat j'ai modifié 2 points dans mon code : j'applique log(mag + 1) après la dft et non plus sur l'image d'entrée, et j'ai supprimé l'exp() après idft.

Voici mes resultats :

image origine : http://i.imgur.com/Kw0Wdo4.png
magnitude (après dft) : http://i.imgur.com/9n7L0Qp.png
phase : http://i.imgur.com/IyKDWIL.png
mag après shifting : http://i.imgur.com/XsCwysy.png
butterworth filter : http://i.imgur.com/QCsxGS3.png
mag après butterworth : http://i.imgur.com/yMLH1VV.png
mag après shifting : http://i.imgur.com/cNfTuIP.png
image finale : http://i.imgur.com/7AX9j5u.png

En comparant mes résultats avec les autres sujets abordant le filtre homomorphique, je constate que mon filtre butterworth et le résultat de la magnitude après dft/shifting semble correcte. Par contre je ne comprends pas pourquoi mon image finale est autant "bruitée"... une idée ? Merci ^^