Esempio n. 1
0
static void
median(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *background = NULL;
    MedianBgArgs args;
    gint oldid, newid;
    GQuark dquark;
    gdouble xr, yr;
    gboolean ok = TRUE;

    g_return_if_fail(run & MEDIANBG_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfield && dquark);

    median_load_args(gwy_app_settings_get(), &args);

    /* FIXME: this is bogus for non-square pixels anyway */
    xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield);
    yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield);
    args.pixelsize = hypot(xr, yr);
    args.valform
        = gwy_data_field_get_value_format_xy(dfield,
                                             GWY_SI_UNIT_FORMAT_VFMARKUP, NULL);
    gwy_debug("pixelsize = %g, vf = (%g, %d, %s)",
              args.pixelsize, args.valform->magnitude, args.valform->precision,
              args.valform->units);

    if (run == GWY_RUN_INTERACTIVE) {
        ok = median_dialog(&args);
        median_save_args(gwy_app_settings_get(), &args);
    }

    gwy_si_unit_value_format_free(args.valform);
    if (!ok)
        return;

    gwy_app_wait_start(gwy_app_find_window_for_channel(data, oldid),
                       _("Median-leveling..."));
    background = median_background(GWY_ROUND(args.size), dfield);
    gwy_app_wait_finish();
    if (!background)
        return;

    gwy_app_undo_qcheckpointv(data, 1, &dquark);
    gwy_data_field_subtract_fields(dfield, dfield, background);
    gwy_data_field_data_changed(dfield);
    gwy_app_channel_log_add_proc(data, oldid, oldid);

    if (!args.do_extract) {
        g_object_unref(background);
        return;
    }

    newid = gwy_app_data_browser_add_data_field(background, data, TRUE);
    g_object_unref(background);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_set_data_field_title(data, newid, _("Background"));
    gwy_app_channel_log_add(data, oldid, newid, NULL, NULL);
}
Esempio n. 2
0
static void
sphrev(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *background = NULL;
    Sphrev1DArgs args;
    gint oldid, newid;
    GQuark dquark;
    gdouble xr, yr;
    gboolean ok = TRUE;

    g_return_if_fail(run & SPHREV_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfield && dquark);

    sphrev_load_args(gwy_app_settings_get(), &args);

    /* FIXME: this is bogus for non-square pixels anyway */
    xr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xres(dfield);
    yr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_yres(dfield);
    args.pixelsize = hypot(xr, yr);
    args.valform
        = gwy_data_field_get_value_format_xy(dfield,
                                             GWY_SI_UNIT_FORMAT_VFMARKUP, NULL);
    gwy_debug("pixelsize = %g, vf = (%g, %d, %s)",
              args.pixelsize, args.valform->magnitude, args.valform->precision,
              args.valform->units);

    if (run == GWY_RUN_INTERACTIVE) {
        ok = sphrev_dialog(&args);
        sphrev_save_args(gwy_app_settings_get(), &args);
    }

    gwy_si_unit_value_format_free(args.valform);
    if (!ok)
        return;

    gwy_app_undo_qcheckpointv(data, 1, &dquark);
    switch (args.direction) {
        case SPHREV_HORIZONTAL:
        background = sphrev_horizontal(&args, dfield);
        break;

        case SPHREV_VERTICAL:
        background = sphrev_vertical(&args, dfield);
        break;

        case SPHREV_BOTH: {
            GwyDataField *tmp;

            background = sphrev_horizontal(&args, dfield);
            tmp = sphrev_vertical(&args, dfield);
            gwy_data_field_sum_fields(background, background, tmp);
            g_object_unref(tmp);
            gwy_data_field_multiply(background, 0.5);
        }
        break;

        default:
        g_assert_not_reached();
        break;
    }
    gwy_data_field_subtract_fields(dfield, dfield, background);
    gwy_data_field_data_changed(dfield);

    if (!args.do_extract) {
        g_object_unref(background);
        return;
    }

    newid = gwy_app_data_browser_add_data_field(background, data, TRUE);
    g_object_unref(background);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_set_data_field_title(data, newid, _("Background"));
}
Esempio n. 3
0
static void
level_grains_do(const LevelGrainsArgs *args,
                GwyContainer *data, GQuark dquark, gint id,
                GwyDataField *dfield, GwyDataField *mfield)
{
    GwyDataField *buffer, *background, *invmask;
    gdouble error, cor, maxerr, lastfrac, frac, starterr;
    gdouble *heights, *bgdata;
    gint *grains;
    gboolean cancelled = FALSE;
    gint i, xres, yres, ngrains;

    xres = gwy_data_field_get_xres(mfield);
    yres = gwy_data_field_get_yres(mfield);
    grains = g_new0(gint, xres*yres);

    ngrains = gwy_data_field_number_grains(mfield, grains);
    if (!ngrains) {
        g_free(grains);
        return;
    }

    heights = g_new(gdouble, ngrains+1);
    gwy_data_field_grains_get_values(dfield, heights, ngrains, grains,
                                     args->base);
    heights[0] = 0.0;

    background = gwy_data_field_new_alike(dfield, FALSE);
    bgdata = gwy_data_field_get_data(background);
    for (i = 0; i < xres*yres; i++)
        bgdata[i] = -heights[grains[i]];

    invmask = gwy_data_field_duplicate(mfield);
    gwy_data_field_multiply(invmask, -1.0);
    gwy_data_field_add(invmask, 1.0);

    maxerr = gwy_data_field_get_rms(dfield)/1.0e4;
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, id),
                       _("Laplace interpolation..."));

    g_free(heights);
    g_free(grains);

    buffer = gwy_data_field_new_alike(background, TRUE);
    gwy_data_field_correct_average(background, invmask);

    cor = 0.2;
    error = 0.0;
    lastfrac = 0.0;
    starterr = 0.0;
    for (i = 0; i < 5000; i++) {
        gwy_data_field_correct_laplace_iteration(background, invmask, buffer,
                                                 cor, &error);
        if (error < maxerr)
            break;
        if (!i)
            starterr = error;

        frac = log(error/starterr)/log(maxerr/starterr);
        if ((i/(gdouble)(5000)) > frac)
            frac = i/(gdouble)(5000);
        if (lastfrac > frac)
            frac = lastfrac;

        if (!gwy_app_wait_set_fraction(frac)) {
            cancelled = TRUE;
            break;
        }
        lastfrac = frac;
    }
    gwy_app_wait_finish();

    if (!cancelled) {
        gwy_data_field_invert(background, FALSE, FALSE, TRUE);
        gwy_app_undo_qcheckpointv(data, 1, &dquark);
        gwy_data_field_subtract_fields(dfield, dfield, background);
        gwy_data_field_data_changed(dfield);

        if (args->do_extract) {
            gint newid;

            newid = gwy_app_data_browser_add_data_field(background, data, TRUE);
            gwy_app_sync_data_items(data, data, id, newid, FALSE,
                                    GWY_DATA_ITEM_GRADIENT,
                                    0);
            gwy_app_set_data_field_title(data, newid, _("Background"));
        }
    }
    g_object_unref(buffer);
    g_object_unref(invmask);
    g_object_unref(background);
}