C++ Opencv 使用幅度和相位进行傅里叶逆变换

问题描述 投票:0回答:0

我在opencv中采用DFT方法。

当我对主机图像进行 DFT 时,我知道我得到了 2 个通道的结果,第一个是实部,第二个是虚部。

通常,我们处理傅立叶变换的幅度,所以我编写代码,分别制作幅度和相位。

但是,出于某种目的,当我想修改特定点(例如(3,3))的幅度时。

我在下面写了代码,但是当我立即在 fft 之后进行 idft 时,它没有给我相同的图像(原始图像有些丢失..)

从数学的角度来看,量级是 sqrt(re * im)。 当我在那个点修改诸如 * 0.3 之类的幅度时,我该如何在那个点重建 re,im? (我错过了什么吗?)

int main(int argc, const char * argv[]) {
std::cout << "Main Function Begin" << std::endl;

const std::string readPath {};

cv::Mat testImg = cv::imread("/Users/a./Documents/CPlusPlus/ironman.jpg");
cv::cvtColor(testImg, testImg, cv::COLOR_BGR2GRAY);
cv::imshow("testImg", testImg);

cv::Mat outputPhaseArray, outputMagnitudeArray;

cv::Mat padded;

cv::Mat inputArray = testImg;
cv::Mat outputArray;
cv::Mat iDFTArray;

fft(testImg, outputPhaseArray, outputMagnitudeArray);
ifft(outputPhaseArray, outputMagnitudeArray, iDFTArray);

iDFTArray.convertTo(iDFTArray, CV_8U);
cv::imshow("iDFTArray", iDFTArray);


cv::waitKey(0);

return 0;
}

void fft(cv::Mat inputArray, cv::Mat& outputArray) {

cv::Mat padded;

int m = cv::getOptimalDFTSize(inputArray.rows);
int n = cv::getOptimalDFTSize(inputArray.cols);
cv::copyMakeBorder(inputArray, padded, 0, m - inputArray.rows, 0, n - inputArray.cols, cv::BORDER_CONSTANT, cv::Scalar::all(0));
cv::Mat plaens[] = { cv::Mat_<float>(padded), cv::Mat::zeros(padded.size(), CV_32F) };
cv::Mat complexArray;
merge(plaens, 2, complexArray);
cv::dft(complexArray, outputArray);
}

void fft(cv::Mat inputArray, cv::Mat& outputPhaseArray, cv::Mat& outputMagnitudeArray) {
cv::Mat outputFFTArray;

fft(inputArray, outputFFTArray);

outputPhaseArray = cv::Mat(inputArray.rows, inputArray.cols, CV_32FC1);
outputMagnitudeArray = cv::Mat(inputArray.rows, inputArray.cols, CV_32FC1);

//float* pt_outputFFTArray = (float*)outputFFTArray.data;
//float* pt_outputPhaseArray = (float*)outputPhaseArray.data;
//float* pt_outputMagnitudeArray = (float*)outputMagnitudeArray.data;


for (int i = 0; i < inputArray.rows; i++) {
    for (int j = 0; j < inputArray.cols; j++) {
        float real = outputFFTArray.at<cv::Vec2f>(i, j)[0];
        float imagine = outputFFTArray.at<cv::Vec2f>(i, j)[1];

        outputPhaseArray.at<float>(i, j) = atan2(imagine, real);
        outputMagnitudeArray.at<float>(i, j) = sqrt((real * real) + (imagine * imagine));

        //float real = pt_outputFFTArray[inputArray.cols * i * 2 + j * 2];
        //float imagine = pt_outputFFTArray[inputArray.cols * i * 2 + j * 2 + 1];

        //pt_outputPhaseArray[inputArray.cols * i + j] = atan2(imagine, real);
        //pt_outputMagnitudeArray[inputArray.cols * i + j] = sqrt((real * real) + (imagine * imagine));
    }
}
}

void ifft(cv::Mat inputPhaseArray, cv::Mat inputMagnitudeArray, cv::Mat& outputArray) {
cv::Mat complexArray = cv::Mat(inputPhaseArray.rows, inputPhaseArray.cols, CV_32FC2);

for (int i = 0; i < inputPhaseArray.rows; i++) {
    for (int j = 0; j < inputPhaseArray.cols; j++) {
        complexArray.at<cv::Vec2f>(i, j)[0] = (inputMagnitudeArray.at<float>(i, j) * cos(inputPhaseArray.at<float>(i, j)));
        complexArray.at<cv::Vec2f>(i, j)[1] = (inputMagnitudeArray.at<float>(i, j) * sin(inputPhaseArray.at<float>(i, j)));

        // pt_complexArray[inputPhaseArray.cols * i * 2 + j * 2] = (pt_inputMagnitudeArray[inputPhaseArray.cols * i + j] * cos(pt_inputPhaseArray[inputPhaseArray.cols * i + j]));
        // pt_complexArray[inputPhaseArray.cols * i * 2 + j * 2 + 1] = (pt_inputMagnitudeArray[inputPhaseArray.cols * i + j] * sin(pt_inputPhaseArray[inputPhaseArray.cols * i + j]));
    }
}

cv::dft(complexArray, outputArray, cv::DFT_INVERSE | cv::DFT_REAL_OUTPUT | cv::DFT_SCALE);
}

void
shiftQuadrants(cv::Mat& srcImg) {
int cy = srcImg.rows / 2;
int cx = srcImg.cols / 2;

// Take four quadrants
cv::Mat q1 = srcImg(cv::Rect(0, 0, cx, cy));
cv::Mat q2 = srcImg(cv::Rect(cx, 0, cx, cy));
cv::Mat q3 = srcImg(cv::Rect(0, cy, cx, cy));
cv::Mat q4 = srcImg(cv::Rect(cx, cy, cx, cy));

swapImage(q1, q4);
swapImage(q2, q3);
}

void swapImage(cv::Mat& im1, cv::Mat& im2) {
cv::Mat temp;
im1.copyTo(temp);
im2.copyTo(im1);
temp.copyTo(im2);
}
opencv image-processing fft dft
© www.soinside.com 2019 - 2024. All rights reserved.