您的位置:首页 > 编程语言 > MATLAB

C++实现Matlab的psf2otf函数

2015-10-11 10:43 465 查看
最近在用C++实现L0Smooth的代码,其中里面用到了psf2otf这个函数,但是OpenCV没有,因此我自写了一个。

关于这个函数的介绍,你可以参考Matlab的官方文档及其源代码,也可以参考这里写的一个记录,这里不做过多介绍了。

代码

[code]////////////////////////////////////////////////////////////////////////////////
/**
 * FileName    :   filter.cpp
 *  Version    :   0.10
 *  Author     :   WinCoder
 *   Date      :   2015-10-11 10:22:21
 *  Comment    :  Implenment Matlab psf2osf function.
 */
Mat psf2otf(Mat psf, Size size)
{
    Mat otf = Mat::zeros(size.height,size.width,psf.type());

     // Pad the PSF to outSize
    Size dftSize;

    // compute the size of DFT transform
    dftSize.width  = getOptimalDFTSize(size.width);
    dftSize.height = getOptimalDFTSize(size.height);

    // allocate temporary buffers and initialize them with 0's
    Mat temp(dftSize, psf.type(), Scalar::all(0));

    //copy psf to the top-left corners of temp
    Mat roipsf(temp,Rect(0,0,psf.cols,psf.rows));
    psf.copyTo(roipsf);

    // Circularly shift otf so that the "center" of the PSF is at the
    // (0,0) element of the array.
    Mat psf2 = temp.clone();

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

    Mat p0(temp, Rect(0, 0, cx, cy));                   // Top-Left - Create a ROI per quadrant 
    Mat p1(temp, Rect(cx, 0, psf2.cols-cx, cy));            // Top-Right
    Mat p2(temp, Rect(0, cy, cx, psf2.rows - cy));      // Bottom-Left
    Mat p3(temp, Rect(cx,cy, psf2.cols-cx, psf2.rows - cy)); // Bottom-Right

    Mat q0(psf2, Rect(0, 0,  psf2.cols-cx, psf2.rows - cy));// Top-Left - Create a ROI per quadrant 
    Mat q1(psf2, Rect(psf2.cols-cx, 0, cx, psf2.rows - cy));// Top-Right
    Mat q2(psf2, Rect(0, psf2.rows - cy, psf2.cols-cx, cy));        // Bottom-Left
    Mat q3(psf2, Rect(psf2.cols-cx, psf2.rows - cy,cx,cy)); // Bottom-Right

    // swap quadrants (Top-Left with Bottom-Right)
    p0.copyTo(q3);
    p3.copyTo(q0);

    // swap quadrant (Top-Right with Bottom-Left)
    p1.copyTo(q2);                    
    p2.copyTo(q1);

    // Computer the OTF
    Mat planes[] = {Mat_<float>(psf2), Mat::zeros(psf2.size(), CV_32F)};
    Mat complexI;
    merge(planes, 2, complexI);

    dft(complexI, complexI);

    otf = complexI;

    return otf(Range(0,size.height),Range(0,size.width));
}


说明

这个程序使用了OpenCV库,我使用的版本是OpenCV300,其他版本也是可以的。

程序是先将矩阵填充到输出大小,然后将原始psf的中心移动到左上角,matlab中psf2otf函数中使用了circshift函数(可以查看其源代码),OpenCV好像没有这个函数,这里我就直接将矩阵分成四个象限,然后将1和3象限对调,2和4象限对调。

值得说明的是OpenCV中傅里叶变换输出有两种格式 全复数输出(full-complex output,占用两个矩阵大小)和复数共轭对称压缩输出(Complex Conjugate Symmetric (CCS) packed output,一个矩阵大小) 。为了生活保持简单和美好,我个人偏向于全复数格式输出,关于 CCS 格式说明见OpenCV官文dft

测试

测试了几个例子,代码正确。

参考资料

Matlab中psf2otf.m源码

转载请保留以下信息

作者日期联系方式
风吹夏天2015年10月11日wincoder@qq.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: