Pregunta

He creado un dft de una imagen y después de algunos ajustes con filtros quiero volver a convertirla a la imagen real, pero cada vez que lo hago me da un resultado incorrecto... parece que no la está volviendo a convertir.ForierTransform y createGaussianHighPassFilter Son mis propias funciones el resto del código que estoy usando como se muestra a continuación para la inversión a la imagen real.

Mat fft = ForierTransform(HeightPadded,WidthPadded);
Mat ghpf = createGaussianHighPassFilter(Size(WidthPadded, HeightPadded), db);
Mat res;
cv::multiply(fft,ghpf,res);
imshow("fftXhighpass1", res);
idft(res,res,DFT_INVERSE,res.rows);
cv::Mat croped = res(cv::Rect(0, 0, img.cols,img.rows));

//res.convertTo(res,CV_32S);
imshow("fftXhighpass", res);

Incluso si no aplico el filtro, no puedo revertir el resultado dft...aquí está mi código dft, no pude encontrar ninguna muestra para revertir dft a la imagen normal.

Mat ForierTransform(int M,int N)
{
    Mat img = imread("thumb1-small-test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat padded;
    copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexImg;
    merge(planes, 2, complexImg);

    dft(complexImg, complexImg);


    split(complexImg, planes);
    magnitude(planes[0], planes[1], planes[0]);
    Mat mag = planes[0];
    mag += Scalar::all(1);
    log(mag, mag);

        // crop the spectrum, if it has an odd number of rows or columns
    mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));


    normalize(mag, mag, 0, 1, CV_MINMAX);
    return mag;
}

amablemente ayuda

[EDITAR:Después encontré la solución con la ayuda de mevatron] (a continuación se muestra el código correcto)

 Mat ForierTransform(int M,int N)
{
    Mat img = imread("thumb1-small-test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat padded;
    copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexImg;
    merge(planes, 2, complexImg);

    dft(complexImg, complexImg);

    return complexImg;
}

Mat img = imread("thumb1-small-test.jpg",CV_LOAD_IMAGE_GRAYSCALE);
int WidthPadded=0,HeightPadded=0;
WidthPadded=img.cols*2;
HeightPadded=img.rows*2;
int M = getOptimalDFTSize( img.rows );
//Create a Gaussian Highpass filter 5% the height of the Fourier transform
double db  = 0.05 * HeightPadded;


Mat fft = ForierTransform(HeightPadded,WidthPadded);
Mat ghpf = createGaussianHighPassFilter(Size(WidthPadded, HeightPadded), db);
Mat res;

cv::mulSpectrums(fft,ghpf,res,DFT_COMPLEX_OUTPUT);


idft(res,res,DFT_COMPLEX_OUTPUT,img.rows);

Mat padded;
copyMakeBorder(img, padded, 0, img.rows, 0, img.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
split(res, planes);
magnitude(planes[0], planes[1], planes[0]);
Mat mag = planes[0];
mag += Scalar::all(1);
log(mag, mag);

// crop the spectrum, if it has an odd number of rows or columns
mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));

int cx = mag.cols/2;
int cy = mag.rows/2;

normalize(mag, mag, 1, 0, CV_MINMAX);

cv::Mat croped = mag(cv::Rect(cx, cy, img.cols,img.rows));
cv::threshold(croped , croped , 0.56, 1, cv::THRESH_BINARY);

imshow("fftPLUShpf", mag);
imshow("cropedBinary", croped);

Ahora puede mostrar las crestas del valle del dedo y también puede optimizarse más con respecto al umbral.

¿Fue útil?

Solución

Veo algunos problemas aquí.

Primero, necesitas usar el mulSpectrums función para convolucionar dos FFT, y no multiplicar.

En segundo lugar, el createGaussianHighPassFilter solo genera un filtro no complejo de un solo canal.Probablemente necesitarás configurar el canal complejo en Mat::zeros como lo hizo con su imagen de entrada.

En tercer lugar, no convierta la salida de la FFT a un espectro de magnitud logarítmica.No se combinará correctamente con el filtro y no obtendrás lo mismo al realizar lo inverso.Entonces, solo regresa complexImg justo después de ejecutar el DFT.El espectro de magnitud logarítmica es útil para que un ser humano observe los datos, pero no para lo que está intentando hacer.

Finalmente, asegúrese de prestar atención a la diferencia entre la salida completa y compleja de dft y la salida empaquetada compleja conjugada simétrica (CCS).Intel tiene una buena página sobre cómo se formatean estos datos. aquí.En su caso, por simplicidad, mantendría todo en modo complejo completo para facilitarle la vida.

¡Espero que ayude!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top