예제 #1
0
int main()
{
    void ddct8x8s(int isgn, double **a);
    void ddct16x16s(int isgn, double **a);
    void putdata2d(int n1, int n2, double **a);
    double errorcheck2d(int n1, int n2, double scale, double **a);
    double err;
    
    int i;
    double aarr[NMAX][NMAX], *a[NMAX], barr[NMAX][NMAX], *b[NMAX];
    for (i = 0; i < NMAX; i++) a[i] = aarr[i];
    for (i = 0; i < NMAX; i++) b[i] = barr[i];

    /* check of 8x8 DCT */
    putdata2d(8, 8, a);
    ddct8x8s(-1, a);
    ddct8x8s(1, a);
    err = errorcheck2d(8, 8, 1.0, a);
    printf("ddct8x8s   err= %g\n", err);

    /* check of 16x16 DCT */
    putdata2d(16, 16, a);
    ddct16x16s(-1, a);
    ddct16x16s(1, a);
    err = errorcheck2d(16, 16, 1.0, a);
    printf("ddct16x16s err= %g\n", err);

    return 0;
}
예제 #2
0
void dctNxN(int n, double **data, int* ip, double* w) {
    switch(n) {
        case 2:
        case 4:
            ddct2d(n, n, -1, data, NULL, ip, w);
            break;
        case 8:
            ddct8x8s(-1,data);
            break;
        case 16:
            ddct16x16s(-1,data);
            break;
        default:
            error("N (blocksize) wasn't a power of 2 in dctNxN");
            //exit(1);
            break;
    }
}
예제 #3
0
void CLASS cfa_linedn(float noise)
{
  // local variables
  //int height=m_OutHeight, width=m_OutWidth;
  int top, left, row, col;
  int rr, cc, indx, i, j;
  int ex, ey;
  int verbose=1;

  float eps=1e-10;      //tolerance to avoid dividing by zero

  float gauss[5] = {0.20416368871516755, 0.18017382291138087, 0.1238315368057753, 0.0662822452863612, 0.02763055063889883};
  float rolloff[8] = {0, 0.135335, 0.249352, 0.411112, 0.606531, 0.800737, 0.945959, 1}; //gaussian with sigma=3
  float window[8] = {0, .25, .75, 1, 1, .75, .25, 0}; //sine squared
  float noisevar, linehvar, linevvar, coeffsq;

  float *cfain, *cfablur, *cfadiff,*cfadn;

  float aarr[8][8], *dctblock[8];  

  for (i = 0; i < 8; i++) dctblock[i] = aarr[i];

  if (verbose) fprintf (stderr,_("Line denoise ...\n"));	
  // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


  noisevar=SQR(3*noise*65535); // _noise_ (as a fraction of saturation) is input to the algorithm

  cfain = (float (*)) calloc (TS*TS, sizeof(float));
  cfablur = (float (*)) calloc (TS*TS, sizeof(float));
  cfadiff = (float (*)) calloc (TS*TS, sizeof(float));
  cfadn = (float (*)) calloc (TS*TS, sizeof(float));


  // Main algorithm: Tile loop
  for (top=0; top < height-16; top += TS-32)
    for (left=0; left < width-16; left += TS-32) {
      int bottom = MIN( top+TS,height);
      int right  = MIN(left+TS, width);
      int numrows = bottom - top;
      int numcols = right - left;

      // load CFA data; data should be in linear gamma space, before white balance multipliers are applied
      for (rr=top; rr < top+numrows; rr++)
        for (cc=left, indx=(rr-top)*TS; cc < left+numcols; cc++, indx++) {
          // cfain[indx] = ri->data[rr][cc];
          cfain[indx] = image[rr*width+cc][FC(rr,cc)];
        }
      //pad the block to a multiple of 16 on both sides

      if (numcols < TS) {
        indx=numcols % 16;
        for (i=0; i<(16-indx); i++)
          for (rr=0; rr<numrows; rr++)
            cfain[(rr)*TS+numcols+i+1]=cfain[(rr)*TS+numcols-i];
        numcols += 16-indx;
      }

      if (numrows < TS) {
        indx=numrows % 16;
        for (i=0; i<(16-indx); i++)
          for (cc=0; cc<numcols; cc++)
            cfain[(numrows+i+1)*TS+cc]=cfain[(numrows-i)*TS+cc];
        numrows += 16-indx;
      }

      //The cleaning algorithm starts here


      //gaussian blur of CFA data
      for (rr=8; rr < numrows-8; rr++)
        for (indx=rr*TS; indx < rr*TS+numcols; indx++) {

          cfablur[indx]=gauss[0]*cfain[indx];
          for (i=1; i<5; i++) {
            cfablur[indx] += gauss[i]*(cfain[indx-(2*i)*TS]+cfain[indx+(2*i)*TS]);
          }
        }
      for (rr=8; rr < numrows-8; rr++)
        for (indx=rr*TS+8; indx < rr*TS+numcols-8; indx++) {

          cfadn[indx] = gauss[0]*cfablur[indx];
          for (i=1; i<5; i++) {
            cfadn[indx] += gauss[i]*(cfablur[indx-2*i]+cfablur[indx+2*i]);
          }
          cfadiff[indx]=cfain[indx]-cfadn[indx]; // hipass cfa data
        }

      //begin block DCT
      for (ey=0; ey<2; ey++) // (ex,ey) specify RGGB subarray
        for (ex=0; ex<2; ex++)
          for (rr=8+ey; rr < numrows-22; rr+=8) // (rr,cc) shift by 8 to overlap blocks
            for (cc=8+ex; cc < numcols-22; cc+=8) {
              //grab an 8x8 block of a given RGGB channel
              for (i=0; i<8; i++)
                for (j=0; j<8; j++) {
                  dctblock[i][j]=cfadiff[(rr+2*i)*TS+cc+2*j];
                }

			  
               ddct8x8s(-1, &dctblock); //forward DCT

              linehvar=linevvar=0;
              for (i=4; i<8; i++) {
                linehvar += SQR(dctblock[0][i]);
                linevvar += SQR(dctblock[i][0]);
              }
              //Wiener filter for line denoising; roll off low frequencies
              if (noisevar>linehvar) {
                for (i=1; i<8; i++) {
                  coeffsq=SQR(dctblock[0][i]);
                  dctblock[0][i] *= coeffsq/(coeffsq+rolloff[i]*noisevar+eps);
                }
              }
              if (noisevar>linevvar) {
                for (i=1; i<8; i++) {
                  coeffsq=SQR(dctblock[i][0]);
                  dctblock[i][0] *= coeffsq/(coeffsq+rolloff[i]*noisevar+eps);
                }
              }

              ddct8x8s(1, &dctblock); //inverse DCT

              //multiply by window fn and add to output (cfadn)
              for (i=0; i<8; i++)
                for (j=0; j<8; j++) {
                  cfadn[(rr+2*i)*TS+cc+2*j] += window[i]*window[j]*dctblock[i][j];
                }
            }

      // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      // copy smoothed results back to image matrix
      for (rr=16; rr < numrows-16; rr++) {
        row = rr + top;
        for (col=16+left, indx=rr*TS+16; indx < rr*TS+numcols-16; indx++, col++) {
          image[row*width+col][FC(row,col)] = CLIP((int)(cfadn[indx]+ 0.5));
        }
      }
      //~ if(plistener) plistener->setProgress(fabs((float)top/height));
    }
  // clean up
  free(cfain);
  free(cfablur);
  free(cfadiff);
  free(cfadn);


}