Ejemplo n.º 1
0
void
test_query_from_file(int verbose)
{
    VlKDForest *forest;
    int i;
    float *data, *query;
    vl_size dim;
    vl_size num;

    /*
     * load
     */
    data = load_data("data.bin", &dim, &num);
    forest = load_VlKDForest("forest.bin");
    forest->data = data;

    if((query = (float *)malloc(dim * sizeof(float))) == NULL){
        printf("not enough memoey\n");
        exit(1);
    }
    for(i = 0;i < dim; i++) query[i] = 0.5;
    if(verbose) printf("has created a query\n");

    /*
     * search neighbors
     */
    vl_size numNeighbors = 10;
    unsigned int numComparisons = 0 ;
    unsigned int maxNumComparisons = 0 ;
    VlKDForestNeighbor * neighbors ;

    vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ;
    neighbors = vl_malloc (sizeof(VlKDForestNeighbor) * numNeighbors) ;

    numComparisons = vl_kdforest_query (forest, neighbors, numNeighbors,
                                        query);

    for(i = 0;i < numNeighbors; i++){
        printf("%d %f\n",
               neighbors[i].index + 1, neighbors[i].distance);

        /* check distance */
        if(fabs(
                dist_l2(dim, query, &data[neighbors[i].index * dim]) -
                neighbors[i].distance) > 1e-6){
            printf("%d distance is different. %f\n",
                  dist_l2(dim, query, &data[neighbors[i].index * dim]) );
        }
        /* check order */
        if(i != 0 && neighbors[i-1].distance > neighbors[i].distance){
            printf("order is wrong.\n");
        }
    }

    vl_free(neighbors);

    vl_kdforest_delete(forest);
    free(data);
    free(query);
}
Ejemplo n.º 2
0
/**
 *  @brief Camera Response Function Correction
 */
ImageFloat crf_correction (ImageFloat in, ThinPlate tp)
{
    /*Iterative adjustment to generate an image of mean(noise_part) = 0.5
     * This module supposes that the image is normalized between 0 and 1, where
     * 0 is the black value and 1 the white value.
     * */

    float mean, power, a;
    int i;
    float center_sharp[2], center_blur[2];
    float top_sharp[2], top_blur[2];
    int wsize;
    ImageFloat out;

    out = new_imageFloat (in->ncol, in->nrow);

    /*Calculating the center of the pattern in the blur image */
    pattern_center (center_sharp);
    evaluate_thinPlate (tp, center_sharp, center_blur, 1);

    pattern_top_center(top_sharp);
    evaluate_thinPlate (tp, top_sharp, top_blur, 1);

    /* approx 0.85 half the size of the noise region in the blur image*/
    wsize = (int)(0.85 * dist_l2(top_blur[0],top_blur[1],
                                 center_blur[0],center_blur[1]));


    /*A parabolic function is estimated as:
     * y = ax^2 + (1-a)x
     *  This parabola maps 0 -> 0, 1-> 1
     *  a is set in order that yM -> 0.5
     *  so a = (0.5-mean(x))/(mean(x^2) - mean(x))
     */

    mean = mean_subpx_window (in, wsize, center_blur[0], center_blur[1]);
    power = power_subpx_window (in, wsize, center_blur[0], center_blur[1]);
    a = (0.5 - mean) / (power - mean);

    for (i = 0; i < in->ncol * in->nrow; i++)
        out->val[i] = a * in->val[i] * in->val[i] + (1 - a) * in->val[i];

    return out;
}
Ejemplo n.º 3
0
/**
 * @brief Coarse detection of the pattern by using segments detected from LSD
 * @param in - input image float
 * @return Array of floats containing the OPQR 2D point positions of the
 *         pattern
 */
static float *detect_pattern_coarse(ImageFloat in)
{
    image_double in_lsd;
    ntuple_list seg;
    float min_val, max_val;
    double *seg_length, *seg_midpoint_x, *seg_midpoint_y;
    char is_in_distance;
    double xO, xP, xQ, xR, yO, yQ, yP, yR, l;
    int *has_seg, *has_all_seg, point;

    /* To keep track of the error from the optimal segment position
     * just to choose the closest segment to the optimal location
     */
    double seg_error[NUM_SEG];

    double xi1, xi2, yi1, yi2, xj1, xj2, yj1, yj2, xjN1, xjN2, yjN1, yjN2;
    double xoMp, xpMq, xqMr, xrMo, yoMp, ypMq, yqMr, yrMo;
    double xC, yC;

    /* Structure of the Pattern  Seg0,Seg1,...,Seg10,Seg_Orient0,Seg_Orient1 */
    const double x1S[] = { 3, 6, 7, 7, 7, 6, 3, 0, -2, -2, -2, 1, 8 };
    const double y1S[] = { 0, 0, -1, -4, -7, -9, -9, -9, -7, -4, -1, 1, 0 };
    const double x2S[] = { 3, 6, 8, 8, 8, 6, 3, 0, -1, -1, -1, 1, 7 };
    const double y2S[] = { 1, 1, -1, -4, -7, -8, -8, -8, -7, -4, -1, 0, 0 };


    int i = 0, j = 0, k = 0, c = 0;

    double errorc;
    double actual_scale;
    char ready;

    float *opqr = (float *) malloc(8 * sizeof(float));


    /* Execute LSD */
    /* Convert between images types and renormalize the image to [0,255]*/
    min_val = BIG_NUMBER;
    max_val = 0;
    for (i=0; i< in->ncol *in->nrow;i++)
    {
        if(in->val[i] < min_val) min_val = in->val[i];
        if(in->val[i] > max_val) max_val = in->val[i];
    }

    in_lsd = new_image_double((unsigned int) in->ncol,
                               (unsigned int) in->nrow);
    for (i = 0; i < in->ncol * in->nrow; i++)
        in_lsd->data[i] = (double) 255/(max_val-min_val)*(in->val[i]-min_val);

    /* We do a LOOP from INITIAL_SCALE_LSD to MAX_SCALE_LSD */
    actual_scale = INITIAL_SCALE_LSD;
    ready = 0;

    while (actual_scale < MAX_SCALE_LSD && !ready)
    {
        printf(" -->LSD scale =%f\n",actual_scale);
        seg = lsd_scale(in_lsd, actual_scale);

        /* allocate the array or exit with an error */
        if ((seg_length = (double *) malloc(seg->size * sizeof(double)))
                  == NULL
            || (seg_midpoint_x = (double *) malloc(seg->size * sizeof(double)))
                  == NULL
            || (seg_midpoint_y = (double *) malloc(seg->size * sizeof(double)))
                  == NULL)
        {
            error("PSF_ESTIM - Unable to allocate double array space");
            exit(EXIT_FAILURE);
        }

        /*
         The i component, of the n-tuple number j, of an n-tuple list 'ntl'
         is accessed with:
         */
        for (i = 0; i < (int) seg->size; i++)
        {

            /* segment length */
            seg_length[i] = dist_l2(seg->values[i * seg->dim],
                  seg->values[i * seg->dim + 1],
                  seg->values[i * seg->dim + 2],
                  seg->values[i * seg->dim + 3]);

            /* segment midpoint */
            seg_midpoint_x[i] =
                0.5 * (seg->values[i * seg->dim]
                + seg->values[i * seg->dim + 2]);

            seg_midpoint_y[i] =
                0.5 * (seg->values[i * seg->dim + 1]
                + seg->values[i * seg->dim + 3]);
        }

        /* Accessing to segment j=0...12 associated to segment i
         * has_seg[NUM_SEG*i+j], initialization default to 0
         */

        if ((has_seg =
             (int *) malloc(NUM_SEG * seg->size * sizeof(int))) == NULL
            || (has_all_seg =
                (int *) malloc(seg->size * sizeof(int))) == NULL)
        {
            error("PSF_ESTIM - Unable to allocate double array space");
            exit(EXIT_FAILURE);
        }

        /* has_seg[], Initialization default to -1 */
        for (i = 0; i < NUM_SEG * (int) seg->size; i++)
        {
            has_seg[i] = -1;
        }

        /* has_all_seg[], Initialization default to 0 */
        /* First pass */
        for (i = 0; i < (int) seg->size; i++)
        {
            xi1 = seg->values[i * seg->dim];
            xi2 = seg->values[i * seg->dim + 2];
            yi1 = seg->values[i * seg->dim + 1];
            yi2 = seg->values[i * seg->dim + 3];

            /* Reinitialize the error track */
            for (j = 0; j < NUM_SEG;  j++)
            {
                seg_error[j] = BIG_NUMBER;
            }

            for (j = 0; j < (int) seg->size; j++)
            {
                xj1 = seg->values[j * seg->dim];
                xj2 = seg->values[j * seg->dim + 2];
                yj1 = seg->values[j * seg->dim + 1];
                yj2 = seg->values[j * seg->dim + 3];

                /* Convert the (x,y) coordinates to a new Coordinate System
                 * (xN, yN) having:
                 * (xi1,yi1) at (0,0)
                 * (xi2,yi2) at (0,1)
                 *  The vectors x1s,y1s,x2s,y2s are given within this
                 *  new (xN,yN) coordinate system
                 */
                l = seg_length[i];
                xjN1 =
                    1 / (l * l) * ((yi2 - yi1) * (xj1 - xi1)
                                   - (xi2 - xi1) * (yj1 - yi1));
                yjN1 =
                    1 / (l * l) * ((xi2 - xi1) * (xj1 - xi1)
                                   + (yi2 - yi1) * (yj1 - yi1));
                xjN2 =
                    1 / (l * l) * ((yi2 - yi1) * (xj2 - xi1)
                                   - (xi2 - xi1) * (yj2 - yi1));
                yjN2 =
                    1 / (l * l) * ((xi2 - xi1) * (xj2 - xi1)
                                   + (yi2 - yi1) * (yj2 - yi1));

                for (c = 0; c < NUM_SEG; c++)
                {
                    is_in_distance =
                        (fabs(xjN1 - x1S[c]) < TOL * (2 + fabs(x1S[c])))
                        && (fabs(yjN1 - y1S[c]) < TOL * (2 + fabs(y1S[c])))
                        && (fabs(xjN2 - x2S[c]) < TOL * (2 + fabs(x2S[c])))
                        && (fabs(yjN2 - y2S[c]) < TOL * (2 + fabs(y2S[c])));
                    if (is_in_distance)
                    {
                        /* Need to check that there isn't a previous segment
                         * closer to the optimal location and already marked
                         * as good (errorc). I just keep the segment with
                         * minimum total error l1.
                         */
                        errorc = fabs(xjN1 - x1S[c]) + fabs(yjN1 - y1S[c])
                            + fabs(xjN2 - x2S[c]) + fabs(yjN2 - y2S[c]);
                        if (errorc < seg_error[c])
                        {
                            has_seg[i * NUM_SEG + c] = j;
                            seg_error[c] = errorc;
                        }
                    }
                }
            }


            /*has_all_seg[i] will be one if all segments are present */
            has_all_seg[i] = 1;
            for (j=0;j< NUM_SEG;j++)
            {
                has_all_seg[i] =
                     has_all_seg[i] && (has_seg[i * NUM_SEG + j] >= 0);
            }

            if (has_all_seg[i])
            {
                point = i;
                k++;
            }
        }
        ready = (k==1);
        actual_scale *= 1.15;
    }

    if (k > 1)
    {
        printf("More than one pattern was detected.");
        printf("\nCrop the image surounding the desired pattern and re-run.");
        exit(EXIT_SEVERAL_PATTERNS_DETECTED);
    }

    else if(k<1)
    {
        printf("No pattern was detected. Use another image");
        exit(EXIT_NO_PATTERN_DETECTED);
    }


    /*Calculate C - center, u = unit_length, theta = angle */
    /* 1/3*(DET + 0 + 1) = oMp */
    xoMp = 0.33333 * (seg_midpoint_x[point]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 0]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 1]]);

    yoMp = 0.33333 * (seg_midpoint_y[point]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 0]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 1]]);

    /* 1/3*(2 + 3 + 4) = pMq */
    xpMq = 0.33333 * (seg_midpoint_x[has_seg[point * NUM_SEG + 2]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 3]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 4]]);

    ypMq = 0.33333 * (seg_midpoint_y[has_seg[point * NUM_SEG + 2]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 3]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 4]]);

    /* 1/3*(5 + 6 + 7) = qMr */
    xqMr = 0.33333 * (seg_midpoint_x[has_seg[point * NUM_SEG + 5]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 6]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 7]]);

    yqMr = 0.33333 * (seg_midpoint_y[has_seg[point * NUM_SEG + 5]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 6]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 7]]);

    /* 1/3*(8 + 9 + 10) = rMo */
    xrMo = 0.33333 * (seg_midpoint_x[has_seg[point * NUM_SEG + 8]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 9]]
                      + seg_midpoint_x[has_seg[point * NUM_SEG + 10]]);

    yrMo = 0.33333 * (seg_midpoint_y[has_seg[point * NUM_SEG + 8]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 9]]
                      + seg_midpoint_y[has_seg[point * NUM_SEG + 10]]);

    /*Center */
    xC = 0.25 * (xoMp + xpMq + xqMr + xrMo);
    yC = 0.25 * (yoMp + ypMq + yqMr + yrMo);

    /*O = C + CoMr + CoMp */
    xO = xC + (xrMo - xC) + (xoMp - xC);
    yO = yC + (yrMo - yC) + (yoMp - yC);

    /*P = C + CpMq + CoMp */
    xP = xC + (xpMq - xC) + (xoMp - xC);
    yP = yC + (ypMq - yC) + (yoMp - yC);

    /*Q = C + CqMr + CpMq */
    xQ = xC + (xqMr - xC) + (xpMq - xC);
    yQ = yC + (yqMr - yC) + (ypMq - yC);

    /*R = C + CrMo + CqMr */
    xR = xC + (xrMo - xC) + (xqMr - xC);
    yR = yC + (yrMo - yC) + (yqMr - yC);

    /*Array of OPQR coordinates*/
    opqr[0] = (float) xO;
    opqr[1] = (float) yO;
    opqr[2] = (float) xP;
    opqr[3] = (float) yP;
    opqr[4] = (float) xQ;
    opqr[5] = (float) yQ;
    opqr[6] = (float) xR;
    opqr[7] = (float) yR;

    /* free memory */
    free_image_double(in_lsd);

    free_ntuple_list(seg);
    free(seg_length);
    free(seg_midpoint_y);
    free(seg_midpoint_x);
    free(has_seg);
    free(has_all_seg);

    return opqr;
}
Ejemplo n.º 4
0
void
test_simple(int verbose)
{
    VlKDForest *forest;
    int i, j;
    float *data, *query;
    vl_size dim = 128;
    vl_size num = 10000;
    vl_size numTrees = 1;

    /*
     * create a test data
     */
    if((data = create_data(dim ,num)) == NULL){
        printf("not enough memoey\n");
        exit(1);
    }
    if(verbose) printf("has created a test data\n");

    if((query = (float *)malloc(dim * sizeof(float))) == NULL){
        printf("not enough memoey\n");
        exit(1);
    }
    for(i = 0;i < dim; i++) query[i] = 0.5;
    if(verbose) printf("has created a query\n");

    /*
     * build a kd-tree forest
     */
    forest = kdtreebuild(1, dim, numTrees, VL_KDTREE_MEDIAN, num, data);
    if(verbose) printf("has created a forest\n");
    
    if(verbose && 0){
        for(j = 0;j < numTrees; j++){
            printf("dataIndex[%d] = [", j);
            for(i = 0;i < forest->numData; i++){
                printf("%d ",
                       forest->trees[j]->dataIndex[i].index + 1);
            }
            printf("]\n");
        }
    }

    /*
     * save
     */
    save_data("data.bin", data, dim, num);
    save_VlKDForest("forest.bin", forest);

    /*
     * search neighbors
     */
    vl_size numNeighbors = 10;
    unsigned int numComparisons = 0 ;
    unsigned int maxNumComparisons = 0 ;
    VlKDForestNeighbor * neighbors ;

    vl_kdforest_set_max_num_comparisons (forest, maxNumComparisons) ;
    neighbors = vl_malloc (sizeof(VlKDForestNeighbor) * numNeighbors) ;

    numComparisons = vl_kdforest_query (forest, neighbors, numNeighbors,
                                        query);

    for(i = 0;i < numNeighbors; i++){
        printf("%d %f\n",
               neighbors[i].index + 1, neighbors[i].distance);

        /* check distance */
        if(fabs(
                dist_l2(dim, query, &data[neighbors[i].index * dim]) -
                neighbors[i].distance) > 1e-6){
            printf("%d distance is different. %f\n",
                  dist_l2(dim, query, &data[neighbors[i].index * dim]) );
        }
        /* check order */
        if(i != 0 && neighbors[i-1].distance > neighbors[i].distance){
            printf("order is wrong.\n");
        }
    }

    vl_free(neighbors);
    vl_kdforest_delete(forest);
    free(data);
    free(query);
}
Ejemplo n.º 5
0
/**
 * @brief Detection of a X corner in the imput image
 * @param in - input image float
 * @param ptx - approximate x coord. of the X corner; (output) refined position
 * @param pty - approximate y coord. of the X corner; (output) refined position
 * @return int - 0 if no error
 */
static int detect_xcorner(ImageFloat in, float *ptx, float *pty)
{

    ImageFloat mask, src_buff, gx_buff, gy_buff;
    float coeff;
    int i, j, k, y, x;
    float cx = *ptx;
    float cy = *pty;
    float c2x, c2y;

    int max_iters = 400;

    float eps = 0.00001;
    int wsize = 3;
    float a11, a12, a22, p, q, d;
    int iter = 0;
    float err;
    float py, px;
    float tgx, tgy, gxx, gxy, gyy, m;

    float *mask1D;


    /*mask1D = new_vector(2*wsize+1); */

    mask1D = (float *) malloc((2 * wsize + 1) * sizeof(float));

    mask = new_imageFloat(2 * wsize + 1, 2 * wsize + 1);

    coeff = 1. / (mask->ncol * mask->nrow);

    /* calculate mask */
    for (i = -wsize, k = 0; i <= wsize; i++, k++)
    {
        mask1D[k] = exp(-i * i * coeff);
    }

    for (i = 0; i < (int) mask->nrow; i++)
    {
        for (j = 0; j < (int) mask->ncol; j++)
        {
            mask->val[i * mask->nrow + j] = mask1D[j] * mask1D[i];
        }
    }


    do {
        src_buff = extract_subpx_window(in, wsize, cx, cy);
        gx_buff = gradx(src_buff);
        gy_buff = grady(src_buff);
        a11 = a12 = a22 = p = q = 0;

        /* process gradient */
        for (y = -wsize, k = 0; y <= wsize; y++)
        {
            py = cy + (float) y;

            for (x = -wsize; x <= wsize; x++, k++)
            {
                m = mask->val[k];
                tgx = gx_buff->val[k];
                tgy = gy_buff->val[k];
                gxx = tgx * tgx * m;
                gxy = tgx * tgy * m;
                gyy = tgy * tgy * m;
                px = cx + (float) x;

                a11 += gxx;
                a12 += gxy;
                a22 += gyy;

                p += gxx * px + gxy * py;
                q += gxy * px + gyy * py;
            }
        }

        d = a11 * a22 - a12 * a12;
        c2x = 1 / d * (a22 * p - a12 * q);
        c2y = 1 / d * (-a12 * p + a11 * q);

        err = dist_l2(cx, cy, c2x, c2y);
        cx = c2x;
        cy = c2y;

        free_imageFloat(src_buff);
        free_imageFloat(gx_buff);
        free_imageFloat(gy_buff);
    } while (++iter < max_iters && err > eps);


    *ptx = cx;
    *pty = cy;

    free_imageFloat(mask);
    free((void *) mask1D);

    return 0;
}