2015-12-11 35 views
0

我已將這種Matlab Anisotropic擴散代碼轉換爲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)); 
    } 
} 
+0

什麼是「理想輸出」? – user463035818

+0

我沒有在任何地方看到變量'k'。 –

+2

yoz在哪裏初始化過濾器內核? – Micka

回答

1

看起來你需要分配乘法結果:

Mat C = A.mul(B); 

而且

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

應該

float ahN[3][3] .... 
+0

非常感謝...解決了這個問題 –

0

在C#中解決。轉化爲C++ 的容易時,需要這些變量:

IMAGE [高度,寬度] =整數數組存儲的圖像

高度=以像素爲單位的圖像的高度

寬度=以像素

圖像的寬度
/// <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 + "\r\nIn PeronaMalik"); } 
} 

的解決方案是式(2)如果你想方程式1(指數),您可以更改precal表ecuation此:

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