NLM去噪与创建目录

参考 https://blog.csdn.net/piaoxuezhong/article/details/78345929 如此博主所说,以前使用的对像素点pt,其Size x Size邻域内取均值或加权平均后的值作为去噪后的像素值pt_denoised,这常常导致细节丢失、边缘模糊,因为这些都是依赖于像素点pt邻域Size x Size内的每个像素点pt_neighbor。而NLM却不是这样,NLM是针对块的相似性。NLM是:

1,首先设置pt的搜索窗WinSize x WinSize,搜索窗内的每个像素点如点pt_neighbor,

2,然后对中心像素点 pt邻域Size x Size即W1 , pt_neighbor邻域Size x Size即W2。易知,搜索窗WinSize x WinSize内会有多个W2,W2在围绕W1滑动。

3,对每一个W2,可与W1计算出一个权重tmp_w,将tmp_w作为W2中心像素点pt_neighbor的权重。

4,那么对于每一个W2,都可以与W1计算出一个权重tmp_w,作为每个W2中心pt_neighbor的权重。找出最大的权重wmax,作为W1的中心即pt的权重。

5,然后整个WinSize x WinSize内滑完,可求得所有 pt_neighbor*tmp_w之和即加权平均值average_value。还可求得 所有权重 tmp_w 之和即weight_value。

6,那么最终的去噪后像素值为pt_denoised=average_value/weight_value 。

其中,对于第3步对于中心像素点所在窗W1 与 比较点所在窗W2 的计算如下:

A,首先计算Size X Size的权重,如下计算出的是5x5的窗口

f=2;
kernel=zeros(2*f+1,2*f+1);
for d=1:f
    value= 1 / (2*d+1)^2 ;
    for i=-d:d
        for j=-d:d
            kernel(f+1-i,f+1-j)= kernel(f+1-i,f+1-j) + value ;
        end
    end
end
kernel = kernel ./ f;

B,对W1内每个像素 - W2内每个像素 得到像素差 sub,然后sub*sub*上述对应的权重,最后相加的结果d进行计算得到权重 tmp_w=exp(-d/h)即可。(h是系数)

 还有一种对NLM的升级算法,是一种查表方式求得tmp_W:

int ds=1;
     int Ds=1;//2
     float a=1.0f;
     float h=8.5f;

     int lExpLUT=1+ceil((float)MaxExpLUT*SampExpLUT);
     vector<float> ExpLUT(lExpLUT,1.0f);
      for(int i=1; i<lExpLUT; i++) ExpLUT[i]=exp(-(float)i/SampExpLUT);

     
      int d=2*ds+1;
      vector<double> K(d,0.0f);
      a*=693*a;
      double s=0;
      for(int i=0,t=-ds; t<=ds;t++,i++)
     {
          K[i]=exp(-((double)t*t)/a);
          s+=K[i];
     }
    
     int normdatawd=215;//越大越模糊,会损失细节
     for(int i=0;i<d;i++) K[i]/=s*h*normdatawd;

查找表通过ExpLUT获得,其中K本来是Size x Size大小的2维权重窗口,但被分解成了X方向、Y方向的两个一样的1维权重窗口,即上面的K。

首先对原带噪图进行填充得到新图srcimgsym,然后按 https://download.csdn.net/download/wd1603926823/84993303 进行处理。即如NLM一样,相似窗内像素差与对应权重相乘相加,然后对tmp_W进行查表得到新的权重。最后加权的结果就是去噪的结果。

在Intel cpu i9-9900k上测试600x2432图像15ms 。

 

创建路径或目录

#include <sys/stat.h>
#include <sys/types.h>
#include <stdio.h>

string realpath="/home/jumper/JPMV_IMPS_XRT/SysPara/tmpimgs";
string tmppath("mkdir -p "+realpath);
int ret=std::system(tmppath.c_str());
    
string wholepath=realpath+"/debug_"+std::to_string(jin_score)+"_"+std::to_string(predicttimeStart)+".png";
imwrite(wholepath.c_str(),fusionimgdebug);    

 

posted @ 2022-03-04 19:44  秦时明月卫庄  阅读(186)  评论(0)    收藏  举报