Beispiel #1
0
static void
immerse_correlate(GwyDataField *image,
                  GwyDataField *kernel,
                  gint *col,
                  gint *row)
{
    GwyDataField *subimage, *subkernel, *score, *imagearea;
    gdouble factor;
    gint ixres, iyres, kxres, kyres;
    gint sixres, siyres, skxres, skyres;
    gint xfrom, yfrom, xto, yto;
    gint sx, sy, delta;

    ixres = gwy_data_field_get_xres(image);
    iyres = gwy_data_field_get_yres(image);
    kxres = gwy_data_field_get_xres(kernel);
    kyres = gwy_data_field_get_yres(kernel);
    gwy_debug("kernel: %dx%d, image: %dx%d", kxres, kyres, ixres, iyres);

    factor = MAX(downsample_factor, downsample_limit/sqrt(kxres*kyres));
    factor = MIN(factor, 1.0);

    skxres = GWY_ROUND(factor*kxres);
    skyres = GWY_ROUND(factor*kyres);
    sixres = GWY_ROUND(factor*ixres);
    siyres = GWY_ROUND(factor*iyres);
    gwy_debug("skernel: %dx%d, simage: %dx%d", skxres, skyres, sixres, siyres);

    subimage = gwy_data_field_new_resampled(image, sixres, siyres,
                                            GWY_INTERPOLATION_LINEAR);
    score = gwy_data_field_new_alike(subimage, FALSE);
    subkernel = gwy_data_field_new_resampled(kernel, skxres, skyres,
                                             GWY_INTERPOLATION_LINEAR);

    gwy_data_field_correlate(subimage, subkernel, score,
                             GWY_CORRELATION_NORMAL);
    immerse_find_maximum(score, &sx, &sy);
    gwy_debug("sx: %d, sy: %d", sx, sy);
    g_object_unref(score);
    g_object_unref(subkernel);
    g_object_unref(subimage);

    /* Top left corner coordinate */
    sx -= (skxres - 1)/2;
    sy -= (skyres - 1)/2;
    /* Upscaled to original size */
    sx = GWY_ROUND((gdouble)ixres/sixres*sx);
    sy = GWY_ROUND((gdouble)iyres/siyres*sy);
    /* Uncertainty margin */
    delta = GWY_ROUND(1.5/factor + 1);
    /* Subarea to search */
    xfrom = MAX(sx - delta, 0);
    yfrom = MAX(sy - delta, 0);
    xto = MIN(sx + kxres + delta, ixres);
    yto = MIN(sy + kyres + delta, iyres);

    imagearea = gwy_data_field_area_extract(image,
                                            xfrom, yfrom,
                                            xto - xfrom, yto - yfrom);
    score = gwy_data_field_new_alike(imagearea, FALSE);
    gwy_data_field_correlate(imagearea, kernel, score,
                             GWY_CORRELATION_NORMAL);
    immerse_find_maximum(score, &sx, &sy);
    g_object_unref(score);
    g_object_unref(imagearea);

    *col = sx + xfrom - (kxres - 1)/2;
    *row = sy + yfrom - (kyres - 1)/2;
}
Beispiel #2
0
static void
maskcor_do(MaskcorArgs *args)
{
    enum { WORK_PER_UPDATE = 50000000 };
    GwyDataField *dfield, *kernel, *retfield, *score;
    GwyContainer *data, *kerneldata;
    GwyComputationState *state;
    GQuark quark;
    gint newid, work, wpi;

    kerneldata = gwy_app_data_browser_get(args->kernel.datano);
    quark = gwy_app_get_data_key_for_id(args->kernel.id);
    kernel = GWY_DATA_FIELD(gwy_container_get_object(kerneldata, quark));

    data = gwy_app_data_browser_get(args->data.datano);
    quark = gwy_app_get_data_key_for_id(args->data.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    retfield = gwy_data_field_new_alike(dfield, FALSE);

    /* FIXME */
    if (args->method == GWY_CORRELATION_NORMAL) {
        gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->data.id),
                           _("Initializing..."));
        state = gwy_data_field_correlate_init(dfield, kernel, retfield);
        gwy_app_wait_set_message(_("Correlating..."));
        work = 0;
        wpi = gwy_data_field_get_xres(kernel)*gwy_data_field_get_yres(kernel);
        wpi = MIN(wpi, WORK_PER_UPDATE);
        do {
            gwy_data_field_correlate_iteration(state);
            work += wpi;
            if (work > WORK_PER_UPDATE) {
                work -= WORK_PER_UPDATE;
                if (!gwy_app_wait_set_fraction(state->fraction)) {
                    gwy_data_field_correlate_finalize(state);
                    gwy_app_wait_finish();
                    g_object_unref(retfield);
                    return;
                }
            }
        } while (state->state != GWY_COMPUTATION_STATE_FINISHED);
        gwy_data_field_correlate_finalize(state);
        gwy_app_wait_finish();
    }
    else
        gwy_data_field_correlate(dfield, kernel, retfield, args->method);

    /* score - do new data with score */
    if (args->result == GWY_MASKCOR_SCORE) {
        score = gwy_data_field_duplicate(retfield);
        newid = gwy_app_data_browser_add_data_field(score, data, TRUE);
        gwy_app_sync_data_items(data, data,
                                args->data.id, newid, FALSE,
                                GWY_DATA_ITEM_GRADIENT, 0);
        gwy_app_set_data_field_title(data, newid,
                                     _("Correlation score"));
        g_object_unref(score);
        gwy_app_channel_log_add_proc(data, args->data.id, newid);
    }
    else {
        /* add mask */
        quark = gwy_app_get_mask_key_for_id(args->data.id);
        gwy_app_undo_qcheckpointv(data, 1, &quark);
        if (args->result == GWY_MASKCOR_OBJECTS)
            plot_correlated(retfield,
                            gwy_data_field_get_xres(kernel),
                            gwy_data_field_get_yres(kernel),
                            args->threshold);
        else if (args->result == GWY_MASKCOR_MAXIMA)
            gwy_data_field_threshold(retfield, args->threshold, 0.0, 1.0);

        gwy_container_set_object(data, quark, retfield);
        gwy_app_channel_log_add_proc(data, args->data.id, args->data.id);
    }
    g_object_unref(retfield);
}