各向异性扩散

Anisotropic Diffusion

本文关键字:      更新时间:2023-10-16

我已经将此Matlab各向异性扩散代码转换为C++,但我没有得到所需的输出。我得到的只是一张黑色的照片。有人能检查一下我的代码并给出一些建议吗?以下是我的代码:

const double lambda = 1 / 7;
const double k = 30;
const int iter = 1;

int ahN[3][3] = { {0, 1, 0}, {0, -1, 0}, {0, 0, 0} };
int ahS[3][3] = { {0, 0, 0}, {0, -1, 0}, {0, 1, 0} };
int ahE[3][3] = { {0, 0, 0}, {0, -1, 1}, {0, 0, 0} };
int ahW[3][3] = { {0, 0, 0}, {1, -1, 0}, {0, 0, 0} };
int ahNE[3][3] = { {0, 0, 1}, {0, -1, 0}, {0, 0, 0} };
int ahSE[3][3] = { {0, 0, 0}, {0, -1, 0}, {0, 0, 1} };
int ahSW[3][3] = { {0, 0, 0}, {0, -1, 0}, {1, 0, 0} };
int ahNW[3][3] = { {1, 0, 0}, {0, -1, 0}, {0, 0, 0} };
Mat hN = Mat(3, 3, CV_32FC1, &ahN);
Mat hS = Mat(3, 3, CV_32FC1, &ahS);
Mat hE = Mat(3, 3, CV_32FC1, &ahE);
Mat hW = Mat(3, 3, CV_32FC1, &ahW);
Mat hNE = Mat(3, 3, CV_32FC1, &ahNE);
Mat hSE = Mat(3, 3, CV_32FC1, &ahSE);
Mat hSW = Mat(3, 3, CV_32FC1, &ahSW);
Mat hNW = Mat(3, 3, CV_32FC1, &ahNW);
void anisotropicDiffusion(Mat &output, int width, int height) {
//mat initialisation
Mat nablaN, nablaS, nablaW, nablaE, nablaNE, nablaSE, nablaSW, nablaNW;
Mat cN, cS, cW, cE, cNE, cSE, cSW, cNW;
//depth of filters
int ddepth = -1;
//center pixel distance
double dx = 1, dy = 1, dd = sqrt(2);
double idxSqr = 1.0 / (dx * dx), idySqr = 1.0 / (dy * dy), iddSqr = 1 / (dd * dd);
for (int i = 0; i < iter; i++) {
    //filters 
    filter2D(output, nablaN, ddepth, hN);
    filter2D(output, nablaS, ddepth, hS);
    filter2D(output, nablaW, ddepth, hW);
    filter2D(output, nablaE, ddepth, hE);
    filter2D(output, nablaNE, ddepth, hNE);
    filter2D(output, nablaSE, ddepth, hSE);
    filter2D(output, nablaSW, ddepth, hSW);
    filter2D(output, nablaNW, ddepth, hNW);
    //exponential flux
    cN = nablaN / k;
    cN.mul(cN);
    cN = 1.0 / (1.0 + cN);
    //exp(-cN, cN);
    cS = nablaS / k;
    cS.mul(cS);
    cS = 1.0 / (1.0 + cS);
    //exp(-cS, cS);
    cW = nablaW / k;
    cW.mul(cW);
    cW = 1.0 / (1.0 + cW);
    //exp(-cW, cW);
    cE = nablaE / k;
    cE.mul(cE);
    cE = 1.0 / (1.0 + cE);
    //exp(-cE, cE);
    cNE = nablaNE / k;
    cNE.mul(cNE);
    cNE = 1.0 / (1.0 + cNE);
    //exp(-cNE, cNE);
    cSE = nablaSE / k;
    cSE.mul(cSE);
    cSE = 1.0 / (1.0 + cSE);
    //exp(-cSE, cSE);
    cSW = nablaSW / k;
    cSW.mul(cSW);
    cSW = 1.0 / (1.0 + cSW);
    //exp(-cSW, cSW);
    cNW = nablaNW / k;
    cNW.mul(cNW);
    cNW = 1.0 / (1.0 + cNW);
    //exp(-cNW, cNW);
    output = output + lambda * (idySqr * cN.mul(nablaN) + idySqr * cS.mul(nablaS) + 
                                idxSqr * cW.mul(nablaW) + idxSqr * cE.mul(nablaE) +
                                iddSqr * cNE.mul(nablaNE) + iddSqr * cSE.mul(nablaSE) +
                                iddSqr * cNW.mul(nablaNW) + iddSqr * cSW.mul(nablaSW));
    }
}

在c#中解决。易于翻译成c++你需要这个变量:

IMAGE[高度,宽度]=存储图像的整数数组

height=图像高度(以像素为单位)

width=以像素为单位的图像宽度

/// <summary>Perona & Malik anisotropic difusion filter. (squared formula)</summary>
/// <param name="data">Image data</param>
/// <param name="dt">Heat difusion value. Upper = more rapid convergence.</param>
/// <param name="lambda">The shape of the diffusion coefficient g(), controlling the Perona Malik diffusion g(delta) = 1/((1 +  delta2)  / lambda2). Upper = more blurred image & more noise removed</param>
/// <param name="interations">Determines the maximum number of iteration steps of the filter. Upper = less speed & more noise removed</param>
private void PeronaMalik(int[,] image, double dt, int lambda, int interations)
{
    try
    {
        //test parameters
        if (dt < 0)
            throw new Exception("DT negative value not allowed");
        if (lambda < 0)
            throw new Exception("lambda must be upper of 0");
        if (interations <= 0)
            throw new Exception("Iterations must be upper of 0");
        //Make temp image
        int[,] temp = new int[height, width];
        Array.Copy(image, temp, image.Length);
        //Precalculate tables (for speed up)
        double[] precal = new double[512];
        double lambda2 = lambda * lambda;
        for (int f = 0; f < 512; f++)
        {
            int diff = f - 255;
            precal[f] = -dt * diff * lambda2 / (lambda2 + diff * diff);
        }
        //Apply the filter
        for (int n = 0; n < interations; n++)
        {
            for (int h = 0; h < height; h++)
                for (int w = 0; w < width; w++)
                {
                    int current = temp[h, w];
                    int px = w - 1;
                    int nx = w + 1;
                    int py = h - 1;
                    int ny = h + 1;
                    if (px < 0)
                        px = 0;
                    if (nx >= width)
                        nx = width - 1;
                    if (py < 0)
                        py = 0;
                    if (ny >= height)
                        ny = height - 1;
                    image[h, w] = (int)(precal[255 + current - temp[h, px]] +
                                        precal[255 + current - temp[h, nx]] +
                                        precal[255 + current - temp[py, w]] +
                                        precal[255 + current - temp[ny, w]]) +
                                        temp[h, w];
                }
        }
    }
    catch (Exception ex) { throw new Exception(ex.Message + "rnIn PeronaMalik"); }
}

该解适用于方程2。如果你想要方程1(指数),你可以改变预计算表中的计算:

precal[f] = -dt * delta * Math.Exp(-(delta * delta / lambda2));

看起来您需要分配乘法结果:

Mat C = A.mul(B);

int ahN[3][3] .... 

应该是

float ahN[3][3] ....
相关文章:
  • 没有找到相关文章