428.Pow(x, n)-x的n次幂(中等题)

x的n次幂

  1. 题目

    实现 pow(x,n)

    注意事项
    不用担心精度,当答案和标准输出差绝对值小于1e-3时都算正确

  2. 样例

    Pow(2.1, 3) = 9.261
    Pow(0, 1) = 0
    Pow(1, 0) = 1

  3. 题解

    用二分法优化累计相乘的过程。

public class Solution {
    /**
     * @param x the base number
     * @param n the power number
     * @return the result
     */
    public double myPow(double x, int n) {
        if (n < 0)
        {
            x = 1/x;
            n = -n;
        }
        if (n == 0)
        {
            return 1;
        }
        else if (n == 1)
        {
            return x;
        }
        else if (n % 2 == 0)
        {
            return myPow(x, n/2) * myPow(x, n/2);
        }
        else
        {
            return x * myPow(x, n/2) * myPow(x, n/2);
        }
    }
}

Last Update 2016.11.17

#include <opencv2/opencv.hpp> #include <cmath> #include <complex> #include <vector> #include <iostream> using namespace cv; using namespace std; // 位反转函数(用于蝶形运算准备) int bitReverse(int num, int log2n) { int result = 0; for (int i = 0; i < log2n; ++i) { if (num & (1 << i)) result |= 1 << (log2n - 1 - i); } return result; } // 1D FFT实现(基2-FFT蝶形运算) void fft(vector<complex<float>>& data, bool inverse = false) { const int n = data.size(); const int log2n = static_cast<int>(log2(n)); // 位反转重排 vector<complex<float>> temp(n); for (int i = 0; i < n; ++i) { int rev = bitReverse(i, log2n); temp[i] = data[rev]; } // 蝶形运算 for (int s = 1; s <= log2n; ++s) { int m = 1 << s; // 当前处理块大小 float ang = 2 * CV_PI / m * (inverse ? 1 : -1); complex<float> wm(cos(ang), sin(ang)); for (int k = 0; k < n; k += m) { complex<float> w(1.0f); for (int j = 0; j < m / 2; ++j) { complex<float> t = w * temp[k + j + m / 2]; complex<float> u = temp[k + j]; temp[k + j] = u + t; temp[k + j + m / 2] = u - t; w *= wm; } } } // 逆变换缩放 if (inverse) { for (auto& x : temp) x /= n; } data = temp; } // 2D FFT实现 void fft2d(Mat& complexImage, bool inverse = false) { int rows = complexImage.rows; int cols = complexImage.cols; // 行变换 for (int y = 0; y < rows; ++y) { vector<complex<float>> rowData; for (int x = 0; x < cols; ++x) { rowData.push_back(complexImage.at<Vec2f>(y, x).val[0] + complexImage.at<Vec2f>(y, x).val[1] * 1if); } fft(rowData, inverse); for (int x = 0; x < cols; ++x) { complexImage.at<Vec2f>(y, x) = Vec2f(rowData[x].real(), rowData[x].imag()); } } // 列变换 for (int x = 0; x < cols; ++x) { vector<complex<float>> colData; for (int y = 0; y < rows; ++y) { colData.push_back(complexImage.at<Vec2f>(y, x).val[0] + complexImage.at<Vec2f>(y, x).val[1] * 1if); } fft(colData, inverse); for (int y = 0; y < rows; ++y) { complexImage.at<Vec2f>(y, x) = Vec2f(colData[y].real(), colData[y].imag()); } } } // 频域中心化 (fftshift) void fftShift(Mat& mag) { int cx = mag.cols / 2; int cy = mag.rows / 2; Mat q0(mag, Rect(0, 0, cx, cy)); Mat q1(mag, Rect(cx, 0, cx, cy)); Mat q2(mag, Rect(0, cy, cx, cy)); Mat q3(mag, Rect(cx, cy, cx, cy)); Mat tmp; q0.copyTo(tmp); q3.copyTo(q0); tmp.copyTo(q3); q1.copyTo(tmp); q2.copyTo(q1); tmp.copyTo(q2); } // 计算MSE double calculateMSE(const Mat& img1, const Mat& img2) { if (img1.size() != img2.size() || img1.type() != img2.type()) { cerr << "Images must have same size and type" << endl; return -1; } Mat diff; absdiff(img1, img2, diff); diff = diff.mul(diff); Scalar s = sum(diff); return s[0] / (img1.total() * img1.channels()); } // 计算PSNR double calculatePSNR(const Mat& img1, const Mat& img2) { double mse = calculateMSE(img1, img2); if (mse <= 1e-10) return 100; // 避免除以0 return 10.0 * log10((255.0 * 255.0) / mse); } // 创建低通滤波器掩膜 Mat createLowPassFilter(Size size, double D0) { Mat mask = Mat::zeros(size, CV_32F); Point center(size.width / 2, size.height / 2); for (int y = 0; y < size.height; y++) { for (int x = 0; x < size.width; x++) { double d = sqrt(pow(x - center.x, 2) + pow(y - center.y, 2)); if (d <= D0) { mask.at<float>(y, x) = 1.0f; } } } return mask; } int main() { // 读取灰度图像 Mat img = imread("input.jpg", IMREAD_GRAYSCALE); if (img.empty()) { cerr << "Could not read image" << endl; return -1; } // 调整大小为2的次(FFT要求) int newRows = pow(2, ceil(log2(img.rows))); int newCols = pow(2, ceil(log2(img.cols))); resize(img, img, Size(newCols, newRows)); // 转换为浮点型归一化 Mat floatImg; img.convertTo(floatImg, CV_32F, 1.0 / 255.0); // 准备复矩阵(实部=图像,虚部=0) Mat planes[] = { Mat_<float>(floatImg), Mat::zeros(floatImg.size(), CV_32F) }; Mat complexImg; merge(planes, 2, complexImg); // ===== 执行FFT ===== fft2d(complexImg); // 分离实部和虚部 split(complexImg, planes); // 计算幅度谱 (log scale) Mat mag; magnitude(planes[0], planes[1], mag); mag += Scalar::all(1); // 避免log(0) log(mag, mag); normalize(mag, mag, 0, 1, NORM_MINMAX); // 频域中心化 fftShift(mag); // 显示幅度谱 imshow("Frequency Spectrum", mag); imwrite("spectrum.jpg", mag * 255); waitKey(0); // ===== 重建原始图像 (IFFT) ===== fft2d(complexImg, true); // 逆变换 // 获取实部作为重建图像 split(complexImg, planes); Mat reconstructed; normalize(planes[0], reconstructed, 0, 1, NORM_MINMAX); // 显示重建图像 imshow("Reconstructed Image", reconstructed); imwrite("reconstructed.jpg", reconstructed * 255); // 计算重建MSE/PSNR double mseOriginal = calculateMSE(floatImg, reconstructed); double psnrOriginal = calculatePSNR(floatImg, reconstructed * 255); cout << "MSE (Original): " << mseOriginal << endl; cout << "PSNR (Original): " << psnrOriginal << " dB" << endl; // ===== 低通滤波处理 ===== // 创建低通滤波器(截止频率=图像尺寸的15%) double D0 = min(img.rows, img.cols) * 0.15; Mat lpfMask = createLowPassFilter(complexImg.size(), D0); // 应用滤波器(在频域中心化状态) fftShift(mag); // 确保频域在中心 Mat filteredPlanes[] = { planes[0].mul(lpfMask), planes[1].mul(lpfMask) }; Mat filteredComplex; merge(filteredPlanes, 2, filteredComplex); // 逆变换得到滤波后图像 fft2d(filteredComplex, true); split(filteredComplex, filteredPlanes); Mat filteredImg; normalize(filteredPlanes[0], filteredImg, 0, 1, NORM_MINMAX); // 显示滤波后图像 imshow("Low-Pass Filtered", filteredImg); imwrite("filtered.jpg", filteredImg * 255); // 计算滤波后PSNR double mseFiltered = calculateMSE(floatImg, filteredImg); double psnrFiltered = calculatePSNR(floatImg, filteredImg * 255); cout << "MSE (Filtered): " << mseFiltered << endl; cout << "PSNR (Filtered): " << psnrFiltered << " dB" << endl; waitKey(0); return 0; } 将低通滤波器改为高斯滤波器给出完整代码
最新发布
06-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值