コード例 #1
0
ファイル: vertex_hashtable.c プロジェクト: AntonioCS/Corange
vertex_hashtable* vertex_hashtable_new(int table_size) {

  vertex_hashtable* ht = malloc(sizeof(vertex_hashtable));
  
  ht->items =  malloc( sizeof(vertex_bucket) * table_size );
  ht->table_size = table_size;
  
  for(int i = 0; i < ht->table_size; i++) {
    ht->items[i].keys = vertex_list_new();
    ht->items[i].values = int_list_new();
  }
  
  return ht;

}
コード例 #2
0
static void
inscribed_discs_and_friends(gdouble *inscrdrvalues,
                            gdouble *inscrdxvalues,
                            gdouble *inscrdyvalues,
                            gdouble *edmeanvalues,
                            const gdouble *xvalues,
                            const gdouble *yvalues,
                            const guint *grains,
                            const guint *sizes,
                            guint ngrains,
                            const GwyMaskField *mask,
                            gdouble dx, gdouble dy)
{
    enum { NCAND_MAX = 15 };

    g_return_if_fail(grains);
    g_return_if_fail(sizes);
    g_return_if_fail(xvalues);
    g_return_if_fail(yvalues);
    g_return_if_fail(GWY_IS_MASK_FIELD(mask));
    g_return_if_fail(inscrdrvalues || inscrdxvalues || inscrdyvalues
                     || edmeanvalues);

    const GwyFieldPart *bbox = gwy_mask_field_grain_bounding_boxes(mask);
    guint xres = mask->xres;
    gdouble qgeom = sqrt(dx*dy);
    gboolean nodiscs = !inscrdrvalues && !inscrdxvalues && !inscrdyvalues;

    guint *grain = NULL, *workspace = NULL;
    guint grainsize = 0;
    IntList *inqueue = int_list_new(0);
    IntList *outqueue = int_list_new(0);
    GArray *candidates = g_array_new(FALSE, FALSE, sizeof(FooscribedDisc));
    GArray *vertices = g_array_new(FALSE, FALSE, sizeof(guint));
    EdgeList edges = { 0, 0, NULL };

    /*
     * For each grain:
     *    Extract it, find all boundary pixels.
     *    Use (octagnoal) erosion to find disc centre candidate(s).
     *    For each candidate:
     *       Find maximum disc that fits with this centre.
     *       By expanding/moving try to find a larger disc until we cannot
     *       improve it.
     */
    for (guint gno = 1; gno <= ngrains; gno++) {
        guint w = bbox[gno].width, h = bbox[gno].height;
        gdouble xoff = dx*bbox[gno].col, yoff = dy*bbox[gno].row;

        /* If the grain is rectangular, calculate the properties directly.
         * Large rectangular grains are rare but the point is to catch
         * grains with width or height of 1 here. */
        if (sizes[gno] == w*h) {
            gdouble sdx = 0.5*w*dx, sdy = 0.5*h*dy;
            gdouble Lmax = fmax(sdx, sdy), Lmin = fmin(sdx, sdy);
            if (inscrdrvalues)
                inscrdrvalues[gno] = 0.999999*Lmin;
            if (inscrdxvalues)
                inscrdxvalues[gno] = sdx + xoff;
            if (inscrdyvalues)
                inscrdyvalues[gno] = sdy + yoff;
            if (edmeanvalues)
                edmeanvalues[gno] = Lmin/6.0*(3.0 - Lmin/Lmax);
            continue;
        }

        /* Upsampling twice combined with octagonal erosion has the nice
         * property that we get candidate pixels in places such as corners
         * or junctions of one-pixel thin lines. */
        guint width, height, wspsize = grainsize;
        grain = extract_upsampled_square_pixel_grain(grains, xres, gno,
                                                     bbox + gno,
                                                     grain, &grainsize,
                                                     &width, &height,
                                                     dx, dy);
        workspace = grain_maybe_realloc(workspace, width, height, &wspsize);
        g_assert(wspsize == grainsize);
        /* Size of upsampled pixel in original squeezed pixel coordinates.
         * Normally equal to 1/2 and always approximately 1:1. */
        gdouble sdx = w*(dx/qgeom)/width;
        gdouble sdy = h*(dy/qgeom)/height;
        /* Grain centre in squeezed pixel coordinates within the bbox. */
        gdouble centrex = (xvalues[gno] + 0.5)*(dx/qgeom);
        gdouble centrey = (yvalues[gno] + 0.5)*(dy/qgeom);

        _gwy_distance_transform_raw(grain, workspace, width, height, TRUE,
                                    inqueue, outqueue);

        if (edmeanvalues) {
            edmeanvalues[gno] = mean_euclidean_distance(grain, width*height,
                                                        w*dx/width,
                                                        h*dy/height);
        }
        if (nodiscs)
            continue;

#if 0
        g_printerr("Grain #%u, orig %ux%u, resampled to %ux%u\n",
                   gno, bbox[gno].width, bbox[gno].height, width, height);
        for (guint i = 0; i < height; i++) {
            for (guint j = 0; j < width; j++) {
                if (!grain[i*width + j])
                    g_printerr("..");
                else
                    g_printerr("%02u", grain[i*width + j]);
                g_printerr("%c", j == width-1 ? '\n' : ' ');
            }
        }
#endif
        double dist = find_disc_centre_candidates(candidates, NCAND_MAX,
                                                  grain, width, height,
                                                  sdx, sdy,
                                                  centrex, centrey);
        find_all_edges(&edges, vertices, grains, xres, gno, bbox + gno,
                       dx/qgeom, dy/qgeom);

        /* Try a few first candidates for the inscribed disc centre. */
        FooscribedDisc *cand;
        for (guint i = 0; i < candidates->len; i++) {
            cand = &g_array_index(candidates, FooscribedDisc, i);
            improve_inscribed_disc(cand, &edges, dist);
        }

        cand = &g_array_index(candidates, FooscribedDisc, 0);
        for (guint i = 1; i < candidates->len; i++) {
            if (g_array_index(candidates, FooscribedDisc, i).R2 > cand->R2)
                cand = &g_array_index(candidates, FooscribedDisc, i);
        }

        if (inscrdrvalues)
            inscrdrvalues[gno] = sqrt(cand->R2)*qgeom;
        if (inscrdxvalues)
            inscrdxvalues[gno] = cand->x*qgeom + xoff;
        if (inscrdyvalues)
            inscrdyvalues[gno] = cand->y*qgeom + yoff;

        //g_printerr("[%u] %g %g %g\n", gno, sqrt(cand->R2)*qgeom, cand->x*qgeom + xoff, cand->y*qgeom + yoff);
    }

    g_free(workspace);
    g_free(grain);
    int_list_free(inqueue);
    int_list_free(outqueue);
    g_free(edges.edges);
    g_array_free(vertices, TRUE);
    g_array_free(candidates, TRUE);
}