00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "libdenoising.h"
00043
00044
00045
00046
00047
00048
00049 void nlmeans_ipol(int iDWin,
00050 int iDBloc,
00051 float fSigma,
00052 float fFiltPar,
00053 float **fpI,
00054 float **fpO,
00055 int iChannels, int iWidth,int iHeight) {
00056
00057
00058
00059
00060
00061 int iwxh = iWidth * iHeight;
00062
00063
00064
00065 int ihwl = (2*iDWin+1);
00066 int iwl = (2*iDWin+1) * (2*iDWin+1);
00067 int icwl = iChannels * iwl;
00068
00069
00070
00071
00072 float fSigma2 = fSigma * fSigma;
00073 float fH = fFiltPar * fSigma;
00074 float fH2 = fH * fH;
00075
00076
00077 fH2 *= (float) icwl;
00078
00079
00080
00081
00082 int iLutLength = (int) rintf((float) LUTMAX * (float) LUTPRECISION);
00083 float *fpLut = new float[iLutLength];
00084 wxFillExpLut(fpLut,iLutLength);
00085
00086
00087
00088
00089
00090
00091 float *fpCount = new float[iwxh];
00092 fpClear(fpCount, 0.0f,iwxh);
00093
00094
00095
00096
00097
00098 for (int ii=0; ii < iChannels; ii++) fpClear(fpO[ii], 0.0f, iwxh);
00099
00100
00101
00102
00103
00104
00105 #pragma omp parallel shared(fpI, fpO)
00106 {
00107
00108
00109 #pragma omp for schedule(dynamic) nowait
00110
00111 for (int y=0; y < iHeight ; y++) {
00112
00113
00114
00115
00116 float **fpODenoised = new float*[iChannels];
00117 for (int ii=0; ii < iChannels; ii++) fpODenoised[ii] = new float[iwl];
00118
00119
00120
00121
00122
00123 for (int x=0 ; x < iWidth; x++) {
00124
00125
00126 int iDWin0 = MIN(iDWin,MIN(iWidth-1-x,MIN(iHeight-1-y,MIN(x,y))));
00127
00128
00129
00130 int imin=MAX(x-iDBloc,iDWin0);
00131 int jmin=MAX(y-iDBloc,iDWin0);
00132
00133 int imax=MIN(x+iDBloc,iWidth-1-iDWin0);
00134 int jmax=MIN(y+iDBloc,iHeight-1-iDWin0);
00135
00136
00137
00138
00139 for (int ii=0; ii < iChannels; ii++) fpClear(fpODenoised[ii], 0.0f, iwl);
00140
00141
00142
00143
00144 float fMaxWeight = 0.0f;
00145
00146
00147
00148 float fTotalWeight = 0.0f;
00149
00150
00151 for (int j=jmin; j <= jmax; j++)
00152 for (int i=imin ; i <= imax; i++)
00153 if (i!=x || j!=y) {
00154
00155 float fDif = fiL2FloatDist(fpI,fpI,x,y,i,j,iDWin0,iChannels,iWidth,iWidth);
00156
00157
00158 fDif = MAX(fDif - 2.0f * (float) icwl * fSigma2, 0.0f);
00159 fDif = fDif / fH2;
00160
00161 float fWeight = wxSLUT(fDif,fpLut);
00162
00163 if (fWeight > fMaxWeight) fMaxWeight = fWeight;
00164
00165 fTotalWeight += fWeight;
00166
00167
00168 for (int is=-iDWin0; is <=iDWin0; is++) {
00169 int aiindex = (iDWin+is) * ihwl + iDWin;
00170 int ail = (j+is)*iWidth+i;
00171
00172 for (int ir=-iDWin0; ir <= iDWin0; ir++) {
00173
00174 int iindex = aiindex + ir;
00175 int il= ail +ir;
00176
00177 for (int ii=0; ii < iChannels; ii++)
00178 fpODenoised[ii][iindex] += fWeight * fpI[ii][il];
00179
00180 }
00181
00182 }
00183
00184
00185 }
00186
00187
00188
00189
00190
00191 for (int is=-iDWin0; is <=iDWin0; is++) {
00192 int aiindex = (iDWin+is) * ihwl + iDWin;
00193 int ail=(y+is)*iWidth+x;
00194
00195 for (int ir=-iDWin0; ir <= iDWin0; ir++) {
00196
00197 int iindex = aiindex + ir;
00198 int il=ail+ir;
00199
00200 for (int ii=0; ii < iChannels; ii++)
00201 fpODenoised[ii][iindex] += fMaxWeight * fpI[ii][il];
00202
00203 }
00204 }
00205
00206
00207
00208 fTotalWeight += fMaxWeight;
00209
00210
00211
00212
00213
00214
00215
00216
00217 if (fTotalWeight > fTiny) {
00218
00219
00220
00221 for (int is=-iDWin0; is <=iDWin0; is++) {
00222 int aiindex = (iDWin+is) * ihwl + iDWin;
00223 int ail=(y+is)*iWidth+x;
00224
00225 for (int ir=-iDWin0; ir <= iDWin0; ir++) {
00226 int iindex = aiindex + ir;
00227 int il=ail+ ir;
00228
00229 fpCount[il]++;
00230
00231 for (int ii=0; ii < iChannels; ii++) {
00232 fpO[ii][il] += fpODenoised[ii][iindex] / fTotalWeight;
00233
00234 }
00235
00236 }
00237 }
00238
00239
00240 }
00241
00242
00243
00244
00245
00246
00247 }
00248
00249
00250
00251 for (int ii=0; ii < iChannels; ii++) delete[] fpODenoised[ii];
00252 delete[] fpODenoised;
00253
00254
00255 }
00256
00257
00258
00259
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 for (int ii=0; ii < iwxh; ii++)
00271 if (fpCount[ii]>0.0) {
00272 for (int jj=0; jj < iChannels; jj++) fpO[jj][ii] /= fpCount[ii];
00273
00274 } else {
00275
00276 for (int jj=0; jj < iChannels; jj++) fpO[jj][ii] = fpI[jj][ii];
00277 }
00278
00279
00280
00281
00282
00283 delete[] fpLut;
00284 delete[] fpCount;
00285
00286
00287
00288 }