Ejemplo n.º 1
0
 virtual void onDraw(SkCanvas* canvas) {
     if (!fInitialized) {
         make_checkerboard(4, 4);
         fInitialized = true;
     }
     SkScalar sk32 = SkIntToScalar(32);
     canvas->clear(0x00000000);
     SkPaint bilinearPaint, bicubicPaint;
     SkSize scale = SkSize::Make(sk32, sk32);
     canvas->save();
     canvas->scale(sk32, sk32);
     bilinearPaint.setFilterLevel(SkPaint::kLow_FilterLevel);
     canvas->drawBitmap(fCheckerboard, 0, 0, &bilinearPaint);
     canvas->restore();
     SkAutoTUnref<SkImageFilter> bicubic(SkBicubicImageFilter::CreateMitchell(scale));
     bicubicPaint.setImageFilter(bicubic);
     SkRect srcBounds;
     fCheckerboard.getBounds(&srcBounds);
     canvas->translate(SkIntToScalar(140), 0);
     canvas->saveLayer(&srcBounds, &bicubicPaint);
     canvas->drawBitmap(fCheckerboard, 0, 0);
     canvas->restore();
 }
Ejemplo n.º 2
0
/**
 *  @brief PSF Estimation (Main Function)
 */
float * psf_estim (float *img, int nx, int ny,
                   float *pattern, int pat_nx, int pat_ny,
                   int s, int psf_nrow, int psf_ncol, int solver,
                   char *detected_ppm)
{
    ImageFloat in, imgW, imgN, imgT, imgEq, xGrid, yGrid, imgC, imgP, imgPf;
    int i, j;
    int ncs, nrs;

    float *psharp, *pblur;
    float xmin, xmax, ymin, ymax;

    float fcx, fcy;

    float *cblur, *csharp;
    float ps;

    float *A, *b, *x;
    int ncol, nrow;

    ImageFloat imgMask;

    ThinPlate tp, tpI;

    /* convert input image to ImageFloat */
    in = new_imageFloat (nx, ny);
    memcpy (in->val, img, nx * ny * sizeof (float));

    /* Convert the input random pattern image to a sharp pattern image
     of UP_RES x UP_RES larger size by replacing each pixel by a block of
     UP_RES x UP_RES pixels with the same gray value. Also normalize
     the sharp pattern image to be a FloatImage in [0,1]*/
    imgP =  pattern_to_pattern_image(pattern, pat_nx, pat_ny);


    /*---------Detecting the pattern---------*/
    printf ("Detecting the pattern...\n");
    pblur = detect_pattern (in);


    /*Check if the detected pattern is required by the user*/
    if(detected_ppm)
    {
        ImageFloat inR_detected, inG_detected, inB_detected;
        inR_detected =  draw_detected_corners_image_maxval(in, pblur);
        inG_detected =  draw_detected_corners_image_minval(in, pblur);
        inB_detected =  draw_detected_corners_image_minval(in, pblur);

        write_ppm_normalize_float(detected_ppm,
                                  inR_detected->val,
                                  inG_detected->val,
                                  inB_detected->val,
                                  inR_detected->ncol, inR_detected->nrow);
        free_imageFloat(inR_detected);
        free_imageFloat(inG_detected);
        free_imageFloat(inB_detected);

    }

    /*---Extract a sub image with the target
     *  and update the checkpoints locations relative to the extracted image
     */
    printf ("Extracting the pattern...\n");
    imgT = extract_pattern_region (in, pblur, 12);


#ifdef SAVE_INTERMEDIATE_IMGS
    write_pgm_normalize_float("pattern_region_image.pgm",
                              imgT->val,imgT->ncol, imgT->nrow);
#endif

    /*----Geometric Distortion - Thin Plates----*/
    printf ("Calculating thin-plates distortion...\n");

    /* Compute checkerboard X points positions in the analytic pattern */
    psharp = pattern_Xpoints ();

    tp = calculate_thinPlate (pblur, psharp, 12, 10);/*lambda = 10 */
    tpI = calculate_thinPlate (psharp, pblur, 12, 10);/*lambda = 10 */

    /*---Image Ilumination Normalization B&W---*/
    printf ("Normalizing image illumination...\n");
    imgN = image_normalization (imgT, tpI);
#ifdef SAVE_INTERMEDIATE_IMGS
    write_pgm_normalize_float("illumination_normalized_image.pgm",
                              imgN->val, imgN->ncol, imgN->nrow);
#endif

    /*---CRF Estimation and Correction---*/
    printf ("Estimating and correcting CRF...\n");
    imgEq = crf_correction (imgN, tpI);
#ifdef SAVE_INTERMEDIATE_IMGS
    write_pgm_normalize_float("crf_corrected_image.pgm",
                              imgEq->val, imgEq->ncol, imgEq->nrow);
#endif

    /*---Extract Noise Region from the observed image*/
    printf ("Extracting noise region...\n");
    imgW =
    extract_noise_region (imgEq, tpI, &xmin, &xmax, &ymin, &ymax, &imgMask);
#ifdef SAVE_INTERMEDIATE_IMGS
    write_pgm_normalize_float("noise_region_image.pgm",
                              imgW->val, imgW->ncol, imgW->nrow);
    write_pgm_normalize_float("mask_image.pgm",
                              imgMask->val, imgMask->ncol, imgMask->nrow);
#endif

    /*--- Pattern Rasterization --- */
    /*--------> Cut the spectrum- */
    /*
     * int m = up_res*512;
     * int n = up_res*512;
     * double fcx = q*s/(2*n);
     * double fcy = p*s/(2*m);
     */

    /*
     fcx = imgW->ncol*s/(2*UP_RES*512);
     fcy = imgW->nrow*s/(2*UP_RES*512);
     */
    printf ("Filtering and interpolating sharp pattern image...\n");

    fcx = roundfi (imgW->ncol * s);
    fcy = roundfi (imgW->nrow * s);

    imgPf = lpf_image_dct (imgP, (int) fcx, (int) fcy);


    /* Pattern sx Interpolation */
    ps = 1 / ((float) s);
    ncs = (xmax - xmin) * s + 1;
    nrs = (ymax - ymin) * s + 1;

    cblur = (float *) malloc (nrs * ncs * 2 * sizeof (float));
    csharp = (float *) malloc (nrs * ncs * 2 * sizeof (float));

    /*Generating the sx-sampling grid */
    for (i = 0; i < nrs; i++)
        for (j = 0; j < ncs; j++)
        {
            cblur[2 * i * ncs + 2 * j] = xmin + j * ps;
            cblur[2 * i * ncs + 2 * j + 1] = ymin + i * ps;

        }

    /*Applying TP to the sx-sampling grid and interpolate the Sharp pattern */
    evaluate_thinPlate (tp, cblur, csharp, nrs * ncs);

    xGrid = new_imageFloat (ncs, nrs);
    yGrid = new_imageFloat (ncs, nrs);

    /*The Sharp pattern image only contains the noise part
     * so i need to translate the x,y Grid. Noise regions
     * starts in (PATTERN_BLOCK_SIZE,PATTERN_BLOCK_SIZE)*UP_RES
     */
    for (i = 0; i < nrs; i++)
        for (j = 0; j < ncs; j++)
        {
            xGrid->val[i * ncs + j] =
            csharp[2 * i * ncs + 2 * j] - PATTERN_BLOCK_SIZE * UP_RES;
            yGrid->val[i * ncs + j] =
            csharp[2 * i * ncs + 2 * j + 1] - PATTERN_BLOCK_SIZE * UP_RES;

        }

    /*In version 1.0 the parameter was wrongly set to 0.5 instead of -0.5*/
    imgC = bicubic (xGrid, yGrid, imgPf, -0.5);
#ifdef SAVE_INTERMEDIATE_IMGS
    write_pgm_normalize_float("pattern_interpolated_image.pgm",
                              imgC->val, imgC->ncol, imgC->nrow);
#endif

    /*Generating A and b for Ax = b system */
    printf ("Generating A,b for Ax = b linear system...\n");
    make_Ab (imgC, imgW, imgMask, psf_nrow, psf_ncol, s, &A, &b, &ncol, &nrow);


    /*There are three different ways of solving
     * x / Ax = b.
     * i)   least squares
     * ii)  least squares and then projection (x>=th)
     * iii) non-negative least squares (x>=0)
     */

    printf ("Estimating the PSF: solving Ax = b...\n");

    if(solver==0)
    {
        x = solve_lsd(A, b, nrow, ncol);
    }
    else if (solver==1)
    {
        x = solve_lsd_th (A, b, nrow, ncol, 0.001);
    }
    else if (solver ==2)
    {
        x = solve_nnlsd(A, b, nrow, ncol);
    }
    else {
        error("Solver not recognized. Solver must be 0,1,2");
    }

    printf ("Cleaning the house...\n");
    free_imageFloat (imgW);
    free_imageFloat (imgN);
    free_imageFloat (imgT);
    free_imageFloat (imgEq);
    free_imageFloat (xGrid);
    free_imageFloat (yGrid);
    free_imageFloat (imgC);
    free_imageFloat (imgP);
    free_imageFloat (imgPf);
    free_imageFloat (in);

    free_thinPlate (tp);
    free_thinPlate (tpI);

    free ((void *) cblur);
    free ((void *) csharp);
    free ((void *) psharp);
    free ((void *) pblur);
    free ((void *) A);
    free((void*) b);


    return x;
}
void inter_image_kernel_to_psf(float *H, float* xinter, float *h, 
                               int nx, int ny)
{
    
    int it_max = 3;
    int it=0;
    int i,j;
    float lambda_x, lambda_y;
    float scale_x, scale_y, nx2, ny2, nxS2, nyS2, tx, ty;
    int nxS,nyS;
    
    ImageFloat x, xn, xGrid,yGrid,scaled_x,aux;
    
    nx2 = (((float)nx)-1)/2;
    ny2 = (((float)ny)-1)/2;
    
    
    /*Create image with the kernel*/
    x = new_imageFloat(nx,ny);
    xn = new_imageFloat(nx,ny);
    
    memcpy (x->val, xinter, nx * ny * sizeof (float));
    memcpy (xn->val, xinter, nx * ny * sizeof (float));
    
    /*lambda from ThinPlate Affine Part*/
    lambda_x = H[0];
    lambda_y = H[4];
        
    /* Initialize scale=lambda^n, n=1*/
    scale_x = lambda_x;
    scale_y = lambda_y;
    
    /*nxS = (int)(nx*scale_x+1);
    nyS = (int)(ny*scale_y+1);
    */
    while (scale_x < 50 && scale_y < 50 && it< it_max)
    {
        nxS = ceil(nx*scale_x);
        nyS = ceil(ny*scale_y);
     
        nxS2 = (((float)nxS)-1)/2;
        nyS2 = (((float)nyS)-1)/2;
        
        xGrid = new_imageFloat (nxS, nyS);
        yGrid = new_imageFloat (nxS, nyS);
        
        tx = nx2 - nxS2/scale_x;
        ty = ny2 - nyS2/scale_y;
                
        /*Start from the center so the (tx,ty); is needed*/
        for (i = 0; i < xGrid->nrow; i++)
            for (j = 0; j < xGrid->ncol; j++)
            {
                xGrid->val[i * xGrid->ncol + j] = ((float)j)/scale_x + tx; 
                yGrid->val[i * xGrid->ncol + j] = ((float)i)/scale_y + ty;
            }
        
        scaled_x = bicubic (xGrid, yGrid, x, -0.5);
        
        free_imageFloat(xGrid);
        free_imageFloat(yGrid);

        printf("Iteration %d :: scale x: %f, y: %f\n",it, scale_x, scale_y);
        
        aux = convol(scaled_x,xn);
        
        free_imageFloat(xn);
        free_imageFloat(scaled_x);


        xn = new_imageFloat(aux->ncol,aux->nrow);
        memcpy (xn->val, aux->val, aux->ncol * aux->nrow * sizeof (float));
        free_imageFloat(aux);
        
        scale_x =  scale_x*lambda_x;
        scale_y =  scale_y*lambda_y;
        
        it = it+1;
    
    
    }
    
    /*I added one extra scale...*/
    scale_x =  scale_x/lambda_x;
    scale_y =  scale_y/lambda_y;
    
    xGrid = new_imageFloat (nx,ny);
    yGrid = new_imageFloat (nx,ny);
    
    tx = nxS2 - nx2*scale_x;
    ty = nyS2 - ny2*scale_y;
    
    
    /*I start from the center*/
    for (i = 0; i < ny; i++)
        for (j = 0; j < nx; j++)
        {
            xGrid->val[i * xGrid->ncol + j] = j*scale_x + tx;
            yGrid->val[i * xGrid->ncol + j] = i*scale_y + ty;
        }
    
    aux = bicubic (xGrid, yGrid, xn, -0.5);
    
    /*h = (float *) malloc (nx * ny * sizeof (float));*/

    memcpy (h, aux->val, nx * ny * sizeof (float));
    
    free_imageFloat(aux);
    free_imageFloat(xGrid);
    free_imageFloat(yGrid);
    free_imageFloat(xn);
    free_imageFloat(x);
        
    
}
/** 
 *  @brief Interpolate the  closest image \f$\textbf{v}_1\f$
 *  to generate \f$\textbf{H}_{\lambda/s} \tilde{\textbf{v}}_1\f$ 
 */
 void closest_image_interpolation(float* H, int s, ImageFloat imgW, 
                                  ImageFloat imgP, ImageFloat* imgC, 
                                  ImageFloat* imgMask, float* offset_LR,
                                  float* offset_HR)
{
 
        
    
    ImageFloat imgPf, imgMaskPf, imgMaskC, xGrid, yGrid;
    float *coordImgLRsx, *coordImgHRsx;
    float ps;
    int ncs, nrs, i, j;

    /* Cut all frequencies above fcx or fcy:
     * fcx = imgW->ncol*s/(2*UP_RES*512);
     * fcy = imgW->nrow*s/(2*UP_RES*512);
     */
    
    float fcx,fcy;
    
    fcx = roundfi (imgW->ncol * s);
    fcy = roundfi (imgW->nrow * s);
        
    /*Filter to avoid aliasing*/
    imgPf = lpf_image_dct (imgP, (int) fcx, (int) fcy);
        
    /* Image sx Interpolation H_lambda/s v1 */
    ps = 1 / ((float) s);
    
    ncs = (imgW->ncol-1) * s + 1;
    nrs = (imgW->nrow-1) * s + 1;
    
    /*Sampling Grids points*/
    coordImgLRsx = (float *) malloc (nrs * ncs * 2 * sizeof (float));
    coordImgHRsx = (float *) malloc (nrs * ncs * 2 * sizeof (float));
    
    /*Generating the sx-sampling grid */
    for (i = 0; i < nrs; i++)
        for (j = 0; j < ncs; j++)
        {
            /*Add the offset to reach the common part*/
            coordImgLRsx[2 * i * ncs + 2 * j] =   j * ps + offset_LR[0];
            coordImgLRsx[2 * i * ncs + 2 * j + 1] =  i * ps + offset_LR[1];
        }
    
    /*Apply Homography to the sx-sampling grid and then interpolate the 
     *closest image */
    evaluate_homography (H, coordImgLRsx, coordImgHRsx, nrs * ncs);
    
    /*Sampling Grids at the common region*/
    xGrid = new_imageFloat (ncs, nrs);
    yGrid = new_imageFloat (ncs, nrs);
    
    for (i = 0; i < nrs; i++)
        for (j = 0; j < ncs; j++)
        {
            /*Remove the offset to reach the common region*/
            xGrid->val[i * ncs + j] = coordImgHRsx[2 * i * ncs + 2 * j] 
            - offset_HR[0];
            yGrid->val[i * ncs + j] = coordImgHRsx[2 * i * ncs + 2 * j + 1]  
            - offset_HR[1];
        }
    
    
    /*Bicubic interpolation of the filtered closest image at the sampling grid
     *sx the  resolution of the farthest image
     */
    *imgC = bicubic (xGrid, yGrid, imgPf, -0.5);
    
    /*Create a Mask where the interpolation is valid
     *of course recomputing the interpolation  is not optimal but it works.
     */
    
    imgMaskPf = new_imageFloat(imgPf->ncol,imgPf->nrow);
    for(i=0;i<imgMaskPf->ncol*imgMaskPf->nrow;i++) imgMaskPf->val[i] = 1;
    
    /*Mask at the sx grid*/
    imgMaskC = bicubic (xGrid, yGrid, imgMaskPf, -0.5);
    
    
    /*Mask at the 1x grid*/
    *imgMask = new_imageFloat(imgW->ncol,imgW->nrow);
    for(i=0;i< (*imgMask)->nrow;i++)
        for(j=0;j< (*imgMask)->ncol;j++)
            (*imgMask)->val[i * (*imgMask)->ncol +j] = 
            imgMaskC->val[i*s*imgMaskC->ncol+j*s];
    
    
    /*Do the cleaning*/
    free_imageFloat (imgPf);
    free_imageFloat (imgMaskPf);
    free_imageFloat (imgMaskC);
    free_imageFloat (xGrid);
    free_imageFloat (yGrid);
    
    free ((void *) coordImgLRsx);
    free ((void *) coordImgHRsx);
    
    
}