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
00043
00044
00045
00046 #include "libdemosaicking.h"
00047
00048
00049 #define GREENPOSITION 0
00050 #define REDPOSITION 1
00051 #define BLUEPOSITION 2
00052
00053
00054
00055
00084 void demosaicking_adams(float threshold, int redx,int redy,float *ired,float *igreen,float *iblue,float *ored,float *ogreen,float *oblue,int width,int height)
00085 {
00086
00087
00088
00089 wxCopy(ired,ored,width*height);
00090 wxCopy(igreen,ogreen,width*height);
00091 wxCopy(iblue,oblue,width*height);
00092
00093
00094
00095 int bluex = 1 - redx;
00096 int bluey = 1 - redy;
00097
00098
00099
00100 unsigned char* mask = (unsigned char *) malloc(width*height*sizeof(unsigned char));
00101
00102 for(int x=0;x<width;x++)
00103 for(int y=0;y<height;y++){
00104
00105 if (x%2 == redx && y%2 == redy) mask[y*width+x] = REDPOSITION;
00106 else if (x%2 == bluex && y%2 == bluey) mask[y*width+x] = BLUEPOSITION;
00107 else mask[y*width+x] = GREENPOSITION;
00108
00109 }
00110
00111
00112
00113
00114
00115
00116 for(int x=0;x<width;x++)
00117 for(int y=0;y<height;y++)
00118 if ( (mask[y*width+ x] != GREENPOSITION) && (x < 3 || y < 3 || x>= width - 3 || y>= height - 3 )) {
00119
00120
00121 int gn, gs, ge, gw;
00122
00123 if (y > 0) gn = y-1; else gn = 1;
00124 if (y < height-1) gs = y+1; else gs = height - 2 ;
00125 if (x < width-1) ge = x+1; else ge = width-2;
00126 if (x > 0) gw = x-1; else gw = 1;
00127
00128 ogreen[y*width + x] = (ogreen[gn*width + x] + ogreen[gs*width + x] + ogreen[y*width + gw] + ogreen[y*width + ge])/ 4.0;
00129
00130 }
00131
00132
00133
00134
00135
00136 for(int x=3;x<width-3;x++)
00137 for(int y=3;y<height-3;y++)
00138 if (mask[y*width+ x] != GREENPOSITION ) {
00139
00140
00141 int l = y*width+x;
00142 int lp1 = (y+1)*width +x;
00143 int lp2 = (y+2)*width +x;
00144 int lm1 = (y-1)*width +x;
00145 int lm2 = (y-2)*width +x;
00146
00147
00148 float adv = fabsf(ogreen[lp1] - ogreen[lm1]);
00149 float adh = fabsf(ogreen[l-1] - ogreen[l+1]);
00150 float dh0, dv0;
00151
00152
00153
00154 if (mask[l] == BLUEPOSITION){
00155
00156 dh0 = 2.0 * oblue[l] - oblue[l+2] - oblue[l-2];
00157 dv0 = 2.0 * oblue[l] - oblue[lp2] - oblue[lm2];
00158
00159 } else {
00160
00161
00162 dh0 = 2.0 * ored[l] - ored[l+2] - ored[l-2];
00163 dv0 = 2.0 * ored[l] - ored[lp2] - ored[lm2];
00164
00165 }
00166
00167
00168 adh = adh + fabsf(dh0);
00169 adv = adv + fabsf(dv0);
00170
00171
00172 if (fabsf(adv - adh) < threshold)
00173
00174 ogreen[l] = (ogreen[lm1] + ogreen[lp1] + ogreen[l-1] + ogreen[l+1]) /4.0 + (dh0 + dv0) / 8.0;
00175
00176
00177 else if (adh < adv )
00178
00179 ogreen[l] = (ogreen[l-1] + ogreen[l+1])/2.0 + (dh0)/4.0;
00180
00181
00182 else if ( adv < adh )
00183
00184 ogreen[l] = (ogreen[lp1] + ogreen[lm1])/2.0 + (dv0)/4.0;
00185
00186 }
00187
00188
00189
00190 demosaicking_bilinear_red_blue(redx,redy,ored,ogreen,oblue,width,height);
00191
00192
00193 free(mask);
00194 }
00195
00196
00197
00198
00210 void demosaicking_bilinear_red_blue(int redx,int redy,float *ored,float *ogreen,float *oblue,int width,int height)
00211 {
00212
00213
00214
00215
00216 int bluex = 1 - redx;
00217 int bluey = 1 - redy;
00218
00219
00220
00221 unsigned char* mask = (unsigned char *) malloc(width*height*sizeof(unsigned char));
00222
00223 for(int x=0;x<width;x++)
00224 for(int y=0;y<height;y++){
00225
00226 if (x%2 == redx && y%2 == redy) mask[y*width+x] = REDPOSITION;
00227 else if (x%2 == bluex && y%2 == bluey) mask[y*width+x] = BLUEPOSITION;
00228 else mask[y*width+x] = GREENPOSITION;
00229
00230 }
00231
00232
00233
00234 for(int i=0; i < width*height;i++){
00235
00236 ored[i] -= ogreen[i];
00237 oblue[i] -= ogreen[i];
00238
00239 }
00240
00241
00242
00243
00244 for(int x=0; x < width;x++)
00245 for(int y=0; y < height;y++)
00246 if (mask[y*width+x] != BLUEPOSITION){
00247
00248 int gn, gs, ge, gw;
00249
00250
00251
00252 if (y > 0) gn = y-1; else gn = 1;
00253 if (y < height-1) gs = y+1; else gs = height - 2 ;
00254 if (x < width-1) ge = x+1; else ge = width-2;
00255 if (x > 0) gw = x-1; else gw = 1;
00256
00257 if (mask[y*width+x] == GREENPOSITION && y % 2 == bluey)
00258 oblue[y*width+x] = ( oblue[y*width+ge] + oblue[y*width+gw])/2.0;
00259 else if (mask[y*width+x] == GREENPOSITION && x % 2 == bluex)
00260 oblue[y*width+x] = ( oblue[gn*width+x] + oblue[gs*width+x])/2.0;
00261 else {
00262 oblue[y*width+x] = (oblue[gn*width+ge] + oblue[gn*width + gw] + oblue[gs*width + ge] + oblue[gs*width +gw])/4.0;
00263 }
00264
00265 }
00266
00267
00268
00269
00270
00271 for(int x=0;x<width;x++)
00272 for(int y=0;y<height;y++)
00273 if (mask[y*width+x] != REDPOSITION){
00274
00275 int gn, gs, ge, gw;
00276
00277
00278
00279 if (y > 0) gn = y-1; else gn = 1;
00280 if (y < height-1) gs = y+1; else gs = height - 2 ;
00281 if (x < width-1) ge = x+1; else ge = width-2;
00282 if (x > 0) gw = x-1; else gw = 1;
00283
00284 if (mask[y*width+x] == GREENPOSITION && y % 2 == redy)
00285 ored[y*width+x] = ( ored[y*width+ge] + ored[y*width+gw])/2.0;
00286 else if (mask[y*width+x] == GREENPOSITION && x % 2 == redx)
00287 ored[y*width+x] = ( ored[gn*width+x] + ored[gs*width+x])/2.0;
00288 else {
00289 ored[y*width+x] = (ored[gn*width+ge] + ored[gn*width + gw] + ored[gs*width + ge] + ored[gs*width +gw])/4.0;
00290 }
00291
00292 }
00293
00294
00295
00296 for(int i=0;i<width*height;i++){
00297
00298 ored[i] += ogreen[i];
00299 oblue[i] += ogreen[i];
00300 }
00301
00302
00303
00304 free(mask);
00305
00306 }
00307
00308
00309
00310
00311
00312
00313
00330 void demosaicking_nlmeans(int bloc, float h,int redx,int redy,float *ired,float *igreen,float *iblue,float *ored,float *ogreen,float *oblue,int width,int height)
00331 {
00332
00333
00334
00335 int bluex = 1 - redx;
00336 int bluey = 1 - redy;
00337
00338
00339
00340
00341 unsigned char *cfamask = new unsigned char[width*height];
00342
00343
00344 for(int x=0;x<width;x++)
00345 for(int y=0;y<height;y++){
00346
00347 if (x%2 == redx && y%2 == redy) cfamask[y*width+x] = REDPOSITION;
00348 else if (x%2 == bluex && y%2 == bluey) cfamask[y*width+x] = BLUEPOSITION;
00349 else cfamask[y*width+x] = GREENPOSITION;
00350
00351 }
00352
00353
00354 wxCopy(ired,ored,width*height);
00355 wxCopy(igreen,ogreen,width*height);
00356 wxCopy(iblue,oblue,width*height);
00357
00358
00359
00360
00361 int luttaille = (int) (LUTMAX*LUTPRECISION);
00362 float *lut = new float[luttaille];
00363
00364 sFillLut(lut, luttaille);
00365
00366
00367
00368
00369
00370 for(int y=2; y <height-2; y++)
00371 for(int x=2; x<width-2; x++)
00372 {
00373
00374 int l=y*width+x;
00375
00376
00377
00378 int imin=MAX(x-bloc,1);
00379 int jmin=MAX(y-bloc,1);
00380
00381 int imax=MIN(x+bloc,width-2);
00382 int jmax=MIN(y+bloc,height-2);
00383
00384
00385
00386 float red=0.0;
00387 float green=0.0;
00388 float blue=0.0;
00389
00390 float rweight=0.0;
00391 float gweight=0.0;
00392 float bweight=0.0;
00393
00394
00395
00396 for(int j=jmin;j<=jmax;j++)
00397 for(int i=imin;i<=imax;i++) {
00398
00399
00400 int l0=j*width+i;
00401
00402
00403 if (cfamask[l]!=cfamask[l0]) {
00404
00405
00406
00407 float some = 0.0;
00408
00409 some = l2_distance_r1(ired, x, y, i,
00410 j, width);
00411 some += l2_distance_r1(igreen, x, y, i,
00412 j, width);
00413 some += l2_distance_r1(iblue, x, y, i,
00414 j, width);
00415
00416
00417
00418
00419 some= some / (27.0 * h);
00420
00421 float weight = sLUT(some,lut);
00422
00423
00424
00425 if (cfamask[l0] == GREENPOSITION) {
00426
00427 green += weight*igreen[l0];
00428 gweight+= weight;
00429
00430 } else if (cfamask[l0] == REDPOSITION) {
00431
00432 red += weight*ired[l0];
00433 rweight+= weight;
00434
00435 } else {
00436
00437 blue += weight*iblue[l0];
00438 bweight+= weight;
00439 }
00440
00441 }
00442
00443 }
00444
00445
00446
00447 if (cfamask[l] != GREENPOSITION && gweight > fTiny) ogreen[l] = green / gweight;
00448 else ogreen[l] = igreen[l];
00449
00450 if ( cfamask[l] != REDPOSITION && rweight > fTiny) ored[l] = red / rweight ;
00451 else ored[l] = ired[l];
00452
00453 if (cfamask[l] != BLUEPOSITION && bweight > fTiny) oblue[l] = blue / bweight;
00454 else oblue[l] = iblue[l];
00455
00456
00457 }
00458
00459 delete[] cfamask;
00460 delete[] lut;
00461
00462 }
00463
00464
00465
00466
00482 void chromatic_median(int iter,int redx,int redy,int projflag,float side,float *ired,float *igreen, float *iblue,float *ored,float *ogreen,float *oblue,int width,int height)
00483 {
00484
00485
00486 int size=height*width;
00487
00488
00489 float *y=new float[size];
00490 float *u=new float[size];
00491 float *v=new float[size];
00492 float *u0=new float[size];
00493 float *v0=new float[size];
00494
00495 int bluex=1-redx;
00496 int bluey=1-redy;
00497
00498
00499
00500 for(int i=1;i<=iter;i++){
00501
00502
00503
00504 wxRgb2Yuv(ired,igreen,iblue,y,u,v,width,height);
00505
00506
00507 wxMedian(u,u0,side,1 ,width,height);
00508 wxMedian(v,v0,side,1 ,width,height);
00509
00510
00511
00512 wxYuv2Rgb(ored,ogreen,oblue,y,u0,v0,width,height);
00513
00514
00515 if (projflag)
00516 {
00517
00518 for(int x=0;x<width;x++)
00519 for(int y=0;y<height;y++){
00520
00521 int l=y*width+x;
00522
00523 if (x%2==redx && y%2==redy) ored[l]=ired[l];
00524
00525 else if (x%2==bluex && y%2==bluey) oblue[l]=iblue[l];
00526
00527 else ogreen[l]=igreen[l];
00528
00529 }
00530
00531 }
00532
00533
00534 wxCopy(ored,ired,size);
00535 wxCopy(ogreen,igreen,size);
00536 wxCopy(oblue,iblue,size);
00537
00538 }
00539
00540
00541
00542 delete[] y;
00543 delete[] u;
00544 delete[] u0;
00545 delete[] v;
00546 delete[] v0;
00547
00548 }
00549
00550
00551
00552
00553
00554
00555
00586 void ssd_demosaicking_chain(int redx,int redy,float *ired,float *igreen,float *iblue,float *ored,float *ogreen,float *oblue,int width,int height)
00587 {
00588
00589
00591
00592
00593
00594 float h;
00595 int dbloc = 7;
00596 float side = 1.5;
00597 int iter = 1;
00598 int projflag = 1;
00599 float threshold = 2.0;
00600
00601
00602 demosaicking_adams(threshold,redx,redy,ired, igreen, iblue, ored, ogreen, oblue, width,height);
00603
00604
00605
00606 h = 16.0;
00607 demosaicking_nlmeans(dbloc,h,redx,redy,ored,ogreen,oblue,ired,igreen,iblue,width,height);
00608 chromatic_median(iter,redx,redy,projflag,side,ired,igreen,iblue,ored,ogreen,oblue,width,height);
00609
00610
00611
00612 h = 4.0;
00613 demosaicking_nlmeans(dbloc,h,redx,redy,ored,ogreen,oblue,ired,igreen,iblue,width,height);
00614 chromatic_median(iter,redx,redy,projflag,side,ired,igreen,iblue,ored,ogreen,oblue,width,height);
00615
00616
00617
00618 h = 1.0;
00619 demosaicking_nlmeans(dbloc,h,redx,redy,ored,ogreen,oblue,ired,igreen,iblue,width,height);
00620 chromatic_median(iter,redx,redy,projflag,side,ired,igreen,iblue,ored,ogreen,oblue,width,height);
00621
00622
00623
00624 }
00625
00626