Пример #1
0
static void
poly_level_do(GwyContainer *data,
              GwyDataField *dfield,
              GwyDataField *mfield,
              GQuark quark,
              gint oldid,
              const PolyLevelArgs *args)
{
    GwyDataField *bg = NULL;
    gint newid;

    gwy_app_undo_qcheckpointv(data, 1, &quark);
    if (args->do_extract)
        bg = gwy_data_field_new_alike(dfield, TRUE);

    if (mfield && args->masking != GWY_MASK_IGNORE)
        poly_level_do_with_mask(dfield, mfield, dfield, bg, args);
    else if (args->independent)
        poly_level_do_independent(dfield, dfield, bg,
                                  args->col_degree, args->row_degree);
    else
        poly_level_do_maximum(dfield, dfield, bg, args->max_degree);

    if (!args->do_extract)
        return;

    newid = gwy_app_data_browser_add_data_field(bg, data, TRUE);
    g_object_unref(bg);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_set_data_field_title(data, newid, _("Background"));
}
Пример #2
0
static void
psdflp(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *lpsdf;
    PSDFLPArgs args;
    gboolean ok;
    gint id, newid;

    g_return_if_fail(run & PSDFLP_RUN_MODES);

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    g_return_if_fail(dfield);

    psdflp_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = psdflp_dialog(&args);
        psdflp_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    lpsdf = gwy_data_field_new(1, 1, 1.0, 1.0, FALSE);
    psdflp_do(&args, dfield, lpsdf);

    newid = gwy_app_data_browser_add_data_field(lpsdf, data, TRUE);
    g_object_unref(lpsdf);
    gwy_app_set_data_field_title(data, newid, "Log-phi PSDF");
    gwy_app_channel_log_add_proc(data, id, newid);
}
Пример #3
0
static void
mask_extract(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield;
    GwySIUnit *siunit;
    gint oldid, newid;

    g_return_if_fail(run & MASKOPS_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_MASK_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfield);

    dfield = gwy_data_field_duplicate(dfield);
    gwy_data_field_clamp(dfield, 0.0, 1.0);

    /* Other functions should set the units correctly, but do not trust them */
    siunit = gwy_si_unit_new("");
    gwy_data_field_set_si_unit_z(dfield, siunit);
    g_object_unref(siunit);

    newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
    g_object_unref(dfield);
    gwy_app_set_data_field_title(data, newid, _("Mask"));
    gwy_app_channel_log_add_proc(data, oldid, newid);
}
Пример #4
0
static void
dwt(GwyContainer *data, GwyRunType run)
{
    GtkWidget *dialog;
    GwyDataField *dfield;
    GwyDataLine *wtcoefs;
    DWTArgs args;
    gboolean ok;
    gint xsize, ysize, newsize, newid, oldid, i;

    g_return_if_fail(run & DWT_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfield);

    xsize = gwy_data_field_get_xres(dfield);
    ysize = gwy_data_field_get_yres(dfield);
    if (xsize != ysize) {
        dialog = gtk_message_dialog_new
            (gwy_app_find_window_for_channel(data, oldid),
             GTK_DIALOG_DESTROY_WITH_PARENT,
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_OK,
             _("%s: Data must be square."), "DWT");
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    for (newsize = 1, i = xsize-1; i; i >>= 1, newsize <<= 1)
        ;

    dwt_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = dwt_dialog(&args, xsize, newsize);
        dwt_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfield = gwy_data_field_new_resampled(dfield, newsize, newsize,
                                          args.interp);
    gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield));

    wtcoefs = GWY_DATA_LINE(gwy_data_line_new(10, 10, TRUE));
    wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet);
    gwy_data_field_dwt(dfield, wtcoefs, 1, 4);

    newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
    g_object_unref(dfield);
    gwy_app_set_data_field_title(data, newid, _("DWT"));
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_PALETTE, 0);

    g_object_unref(wtcoefs);
}
Пример #5
0
static void
create_merged_field(GwyContainer *data, gint id1,
                    GwyDataField *dfield1, GwyDataField *dfield2,
                    gint px1, gint py1, gint px2, gint py2,
                    GwyMergeBoundaryType boundary, GwyMergeDirectionType dir,
                    gboolean create_mask, gboolean crop_to_rectangle)
{
    GwyDataField *result, *outsidemask = NULL;
    gint newxres, newyres, newid;

    gwy_debug("field1 %dx%d", dfield1->xres, dfield1->yres);
    gwy_debug("field2 %dx%d", dfield2->xres, dfield2->yres);
    gwy_debug("px1: %d, py1: %d, px2: %d, py2: %d", px1, py1, px2, py2);

    result = gwy_data_field_new_alike(dfield1, FALSE);

    newxres = MAX(dfield1->xres + px1, dfield2->xres + px2);
    newyres = MAX(dfield1->yres + py1, dfield2->yres + py2);

    gwy_data_field_resample(result, newxres, newyres, GWY_INTERPOLATION_NONE);
    if (create_mask && !crop_to_rectangle) {
        outsidemask = gwy_data_field_new_alike(result, FALSE);
        gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(outsidemask),
                                    NULL);
    }
    put_fields(dfield1, dfield2, result, outsidemask,
               boundary, px1, py1, px2, py2);

    if (crop_to_rectangle) {
        GwyOrientation orientation = GWY_ORIENTATION_HORIZONTAL;
        if (dir == GWY_MERGE_DIRECTION_UP || dir == GWY_MERGE_DIRECTION_DOWN)
            orientation = GWY_ORIENTATION_VERTICAL;

        crop_result(result, dfield1, dfield2, orientation, px1, py1, px2, py2);
    }

    gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_set_data_field_title(data, newid, _("Merged images"));
    gwy_app_sync_data_items(data, data, id1, newid,
                            FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            GWY_DATA_ITEM_RANGE,
                            0);

    if (outsidemask) {
        if (gwy_data_field_get_max(outsidemask) > 0.0) {
            GQuark quark = gwy_app_get_mask_key_for_id(newid);
            gwy_container_set_object(data, quark, outsidemask);
        }
        g_object_unref(outsidemask);
    }

    gwy_app_channel_log_add_proc(data, -1, newid);
    g_object_unref(result);
}
Пример #6
0
static void
tip_model_do(TipModelArgs *args,
             TipModelControls *controls)
{
    gint newid;

    newid = gwy_app_data_browser_add_data_field(controls->tip,
                                                args->object.data,
                                                TRUE);
    g_object_unref(controls->tip);
    gwy_app_sync_data_items(args->object.data, args->object.data,
                            args->object.id, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT, 0);
    gwy_app_set_data_field_title(args->object.data, newid, _("Modelled tip"));
    controls->tipdone = TRUE;
}
Пример #7
0
static void
presentation_extract(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield;
    GQuark quark;
    gint oldid, newid;

    g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_ID, &oldid,
                                     GWY_APP_SHOW_FIELD_KEY, &quark,
                                     GWY_APP_SHOW_FIELD, &dfield,
                                     0);
    g_return_if_fail(dfield && quark);

    dfield = gwy_data_field_duplicate(dfield);
    newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
    g_object_unref(dfield);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_set_data_field_title(data, newid, NULL);
    gwy_app_channel_log_add_proc(data, oldid, newid);
}
Пример #8
0
static void
immerse_do(ImmerseArgs *args)
{
    GwyDataField *resampled, *image, *detail, *result;
    GwyContainer *data;
    gint newid;
    gint kxres, kyres;
    gint x, y, w, h;
    gdouble iavg, davg;
    GQuark quark;

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

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

    kxres = gwy_data_field_get_xres(detail);
    kyres = gwy_data_field_get_yres(detail);

    switch (args->sampling) {
        case GWY_IMMERSE_SAMPLING_DOWN:
        result = gwy_data_field_duplicate(image);
        x = gwy_data_field_rtoj(image, args->xpos);
        y = gwy_data_field_rtoi(image, args->ypos);
        w = GWY_ROUND(gwy_data_field_get_xreal(detail)
                      /gwy_data_field_get_xmeasure(image));
        h = GWY_ROUND(gwy_data_field_get_yreal(detail)
                      /gwy_data_field_get_ymeasure(image));
        w = MAX(w, 1);
        h = MAX(h, 1);
        gwy_debug("w: %d, h: %d", w, h);
        resampled = gwy_data_field_new_resampled(detail, w, h,
                                                 GWY_INTERPOLATION_LINEAR);
        if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) {
            iavg = gwy_data_field_area_get_avg(result, NULL, x, y, w, h);
            gwy_data_field_add(resampled, iavg - davg);
        }
        gwy_data_field_area_copy(resampled, result, 0, 0, w, h, x, y);
        g_object_unref(resampled);
        break;

        case GWY_IMMERSE_SAMPLING_UP:
        w = GWY_ROUND(gwy_data_field_get_xreal(image)
                      /gwy_data_field_get_xmeasure(detail));
        h = GWY_ROUND(gwy_data_field_get_yreal(image)
                      /gwy_data_field_get_ymeasure(detail));
        gwy_debug("w: %d, h: %d", w, h);
        result = gwy_data_field_new_resampled(image, w, h,
                                              GWY_INTERPOLATION_LINEAR);
        x = gwy_data_field_rtoj(result, args->xpos);
        y = gwy_data_field_rtoi(result, args->ypos);
        if (args->leveling == GWY_IMMERSE_LEVEL_MEAN) {
            iavg = gwy_data_field_area_get_avg(result, NULL,
                                               x, y, kxres, kyres);
            gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y);
            gwy_data_field_area_add(result, x, y, kxres, kyres, iavg - davg);
        }
        else
            gwy_data_field_area_copy(detail, result, 0, 0, kxres, kyres, x, y);
        break;

        default:
        g_return_if_reached();
        break;
    }

    gwy_app_data_browser_get_current(GWY_APP_CONTAINER, &data, 0);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_set_data_field_title(data, newid, _("Immersed detail"));
    g_object_unref(result);
    gwy_app_channel_log_add_proc(data, args->image.id, newid);
}
Пример #9
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"));
}
Пример #10
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);
}
Пример #11
0
static void
run_noninteractive(NoiseSynthArgs *args,
                   const GwyDimensionArgs *dimsargs,
                   GwyContainer *data,
                   GwyDataField *dfield,
                   gint oldid,
                   GQuark quark)
{
    GwySIUnit *siunit;
    gboolean replace = dimsargs->replace && dfield;
    gboolean add = dimsargs->add && dfield;
    gint newid;

    if (args->randomize)
        args->seed = g_random_int() & 0x7fffffff;

    if (replace) {
        /* Always take a reference so that we can always unref. */
        g_object_ref(dfield);

        gwy_app_undo_qcheckpointv(data, 1, &quark);
        if (!add)
            gwy_data_field_clear(dfield);

        gwy_app_channel_log_add_proc(data, oldid, oldid);
    }
    else {
        if (add)
            dfield = gwy_data_field_duplicate(dfield);
        else {
            gdouble mag = pow10(dimsargs->xypow10) * dimsargs->measure;
            dfield = gwy_data_field_new(dimsargs->xres, dimsargs->yres,
                                        mag*dimsargs->xres, mag*dimsargs->yres,
                                        TRUE);

            siunit = gwy_data_field_get_si_unit_xy(dfield);
            gwy_si_unit_set_from_string(siunit, dimsargs->xyunits);

            siunit = gwy_data_field_get_si_unit_z(dfield);
            gwy_si_unit_set_from_string(siunit, dimsargs->zunits);
        }
    }

    noise_synth_do(args, dimsargs, dfield);

    if (replace)
        gwy_data_field_data_changed(dfield);
    else {
        if (data) {
            newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
            if (oldid != -1)
                gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                                        GWY_DATA_ITEM_GRADIENT,
                                        0);
        }
        else {
            newid = 0;
            data = gwy_container_new();
            gwy_container_set_object(data, gwy_app_get_data_key_for_id(newid),
                                     dfield);
            gwy_app_data_browser_add(data);
            gwy_app_data_browser_reset_visibility(data,
                                                  GWY_VISIBILITY_RESET_SHOW_ALL);
            g_object_unref(data);
        }

        gwy_app_set_data_field_title(data, newid, _("Generated"));
        gwy_app_channel_log_add_proc(data, add ? oldid : -1, newid);
    }
    g_object_unref(dfield);
}
Пример #12
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);
}
Пример #13
0
static gboolean
xydenoise_do(XYdenoiseArgs *args)
{
    GwyContainer *data;
    GwyDataField *dfieldx, *rx, *ix, *dfieldy, *ry, *iy, *result, *iresult;
    gint i, newid, xres, yres;
    gdouble *rxdata, *rydata, *ixdata, *iydata;
    GwyWindowingType window = GWY_WINDOWING_NONE;
    GwyInterpolationType interp = GWY_INTERPOLATION_LINEAR;

    GQuark quark;

    data = gwy_app_data_browser_get(args->op1.datano);
    gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->op1.id),
                       _("Initializing..."));

    quark = gwy_app_get_data_key_for_id(args->op1.id);
    dfieldx = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

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

    xres = gwy_data_field_get_xres(dfieldx);
    yres = gwy_data_field_get_yres(dfieldy);
    result = gwy_data_field_new_alike(dfieldx, TRUE);
    iresult = gwy_data_field_new_alike(dfieldx, TRUE);
    rx = gwy_data_field_new_alike(dfieldx, TRUE);
    ix = gwy_data_field_new_alike(dfieldx, TRUE);
    ry = gwy_data_field_new_alike(dfieldx, TRUE);
    iy = gwy_data_field_new_alike(dfieldx, TRUE);

    gwy_app_wait_set_fraction(0.1);
    gwy_app_wait_set_message(_("Computing forward FFTs..."));

    gwy_data_field_2dfft(dfieldx, NULL, rx, ix,
                         window, GWY_TRANSFORM_DIRECTION_FORWARD, interp,
                         FALSE, 0);

    gwy_data_field_2dfft(dfieldy, NULL, ry, iy,
                         window, GWY_TRANSFORM_DIRECTION_FORWARD, interp,
                         FALSE, 0);

    rxdata = gwy_data_field_get_data(rx);
    rydata = gwy_data_field_get_data(ry);
    ixdata = gwy_data_field_get_data(ix);
    iydata = gwy_data_field_get_data(iy);

    gwy_app_wait_set_fraction(0.3);
    gwy_app_wait_set_message(_("Computing image..."));

    for (i = 0; i < xres*yres; i++) {
        gdouble xmodule = sqrt(rxdata[i]*rxdata[i] + ixdata[i]*ixdata[i]);
        gdouble xphase = atan2(ixdata[i],rxdata[i]);
        gdouble ymodule = sqrt(rydata[i]*rydata[i] + iydata[i]*iydata[i]);
        /*gdouble yphase = atan2(iydata[i],rydata[i]);*/
        rxdata[i] = MIN(xmodule, ymodule)*cos(xphase);
        ixdata[i] = MIN(xmodule, ymodule)*sin(xphase);
    }

    gwy_app_wait_set_fraction(0.7);
    gwy_app_wait_set_message(_("Computing backward FFT..."));
    gwy_data_field_2dfft(rx, ix, result, iresult,
                         window, GWY_TRANSFORM_DIRECTION_BACKWARD, interp,
                         FALSE, 0);

    gwy_app_wait_set_fraction(0.9);

    data = gwy_app_data_browser_get(args->op1.datano);
    newid = gwy_app_data_browser_add_data_field(result, data, TRUE);
    gwy_app_sync_data_items(data, data, args->op1.id, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT, 0);

    gwy_app_set_data_field_title(data, newid, _("Denoised"));
    gwy_app_channel_log_add_proc(data, -1, newid);
    gwy_app_wait_finish();

    g_object_unref(result);
    g_object_unref(iresult);
    g_object_unref(rx);
    g_object_unref(ix);
    g_object_unref(ry);
    g_object_unref(iy);

    return TRUE;
}
Пример #14
0
static void
dwt_denoise(GwyContainer *data, GwyRunType run)
{
    GtkWidget *dialog;
    GwyDataField *dfield;
    GwyDataLine *wtcoefs;
    DWTDenoiseArgs args;
    gboolean ok;
    gint xsize, ysize, newsize;
    gint oldid, newid;

    g_return_if_fail(run & DWT_DENOISE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfield);

    xsize = gwy_data_field_get_xres(dfield);
    ysize = gwy_data_field_get_yres(dfield);
    if (xsize != ysize) {
        dialog = gtk_message_dialog_new
            (GTK_WINDOW(gwy_app_data_window_get_current()),
             GTK_DIALOG_DESTROY_WITH_PARENT,
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_OK,
             _("%s: Data must be square."), _("DWT Denoise"));
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    dwt_denoise_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = dwt_denoise_dialog(&args);
        dwt_denoise_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfield = gwy_data_field_duplicate(dfield);

    newsize = gwy_fft_find_nice_size(xsize);
    gwy_data_field_add(dfield, -gwy_data_field_get_avg(dfield));
    gwy_data_field_resample(dfield, newsize, newsize,
                            GWY_INTERPOLATION_BILINEAR);

    wtcoefs = gwy_data_line_new(10, 10, TRUE);
    wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet);
    gwy_data_field_dwt_denoise(dfield, wtcoefs, TRUE, 20, args.method);

    if (args.preserve)
        gwy_data_field_resample(dfield, xsize, ysize, args.interp);


    newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
    gwy_app_copy_data_items(data, data, oldid, newid,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);

    g_object_unref(dfield);
    gwy_app_set_data_field_title(data, newid, _("DWT denoised"));

    g_object_unref(wtcoefs);
}
Пример #15
0
static void
cwt(GwyContainer *data, GwyRunType run)
{
    GtkWidget *dialog;
    GwyDataField *dfield;
    CWTArgs args;
    gboolean ok;
    gint xsize, ysize;
    gint newsize;
    gint oldid, newid;

    g_return_if_fail(run & CWT_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfield);

    xsize = gwy_data_field_get_xres(dfield);
    ysize = gwy_data_field_get_yres(dfield);

    if (xsize != ysize) {
        dialog = gtk_message_dialog_new
            (gwy_app_find_window_for_channel(data, oldid),
             GTK_DIALOG_DESTROY_WITH_PARENT,
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_OK,
             _("%s: Data must be square."), "CWT");
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    cwt_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = cwt_dialog(&args);
        cwt_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfield = gwy_data_field_duplicate(dfield);
    newsize = gwy_fft_find_nice_size(xsize);
    gwy_data_field_resample(dfield, newsize, newsize, args.interp);

    gwy_data_field_cwt(dfield,
                       args.interp,
                       args.scale,
                       args.wavelet);

    if (args.preserve)
        gwy_data_field_resample(dfield, xsize, ysize, args.interp);



    newid = gwy_app_data_browser_add_data_field(dfield, data, TRUE);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);

    g_object_unref(dfield);
    gwy_app_set_data_field_title(data, newid, _("CWT"));
}
Пример #16
0
static void
scale(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfields[3];
    GQuark quark;
    gint oldid, newid;
    ScaleArgs args;
    gboolean ok;

    g_return_if_fail(run & SCALE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0,
                                     GWY_APP_MASK_FIELD, dfields + 1,
                                     GWY_APP_SHOW_FIELD, dfields + 2,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfields[0]);

    scale_load_args(gwy_app_settings_get(), &args);
    args.org_xres = gwy_data_field_get_xres(dfields[0]);
    args.org_yres = gwy_data_field_get_yres(dfields[0]);
    args.xres = ROUND(args.ratio*args.org_xres);
    if (args.proportional)
        args.aspectratio = 1.0;
    args.yres = ROUND(args.aspectratio*args.ratio*args.org_yres);

    if (run == GWY_RUN_INTERACTIVE) {
        ok = scale_dialog(&args);
        scale_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfields[0] = gwy_data_field_new_resampled(dfields[0],
                                              ROUND(args.xres),
                                              ROUND(args.yres),
                                              args.interp);
    if (dfields[1]) {
        dfields[1] = gwy_data_field_new_resampled(dfields[1],
                                                  ROUND(args.xres),
                                                  ROUND(args.yres),
                                                  args.interp);
    }
    if (dfields[2]) {
        dfields[2] = gwy_data_field_new_resampled(dfields[2],
                                                  ROUND(args.xres),
                                                  ROUND(args.yres),
                                                  args.interp);
    }

    newid = gwy_app_data_browser_add_data_field(dfields[0], data, TRUE);
    g_object_unref(dfields[0]);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    if (dfields[1]) {
        quark = gwy_app_get_mask_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[1]);
        g_object_unref(dfields[1]);
    }
    if (dfields[2]) {
        quark = gwy_app_get_show_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[2]);
        g_object_unref(dfields[2]);
    }

    gwy_app_set_data_field_title(data, newid, _("Scaled Data"));
}
Пример #17
0
static void
rotate(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfields[3];
    GQuark quark;
    gint oldid, newid;
    RotateArgs args;
    gboolean ok;

    g_return_if_fail(run & ROTATE_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, dfields + 0,
                                     GWY_APP_MASK_FIELD, dfields + 1,
                                     GWY_APP_SHOW_FIELD, dfields + 2,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);
    g_return_if_fail(dfields[0]);

    rotate_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = rotate_dialog(&args, data);
        rotate_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

    dfields[0] = gwy_data_field_duplicate(dfields[0]);
    rotate_datafield(dfields[0], &args);
    if (dfields[1]) {
        GwyInterpolationType interp = args.interp;

        dfields[1] = gwy_data_field_duplicate(dfields[1]);
        args.interp = GWY_INTERPOLATION_ROUND;
        rotate_datafield(dfields[1], &args);
        args.interp = interp;
    }
    if (dfields[2]) {
        dfields[2] = gwy_data_field_duplicate(dfields[2]);
        rotate_datafield(dfields[2], &args);
    }

    newid = gwy_app_data_browser_add_data_field(dfields[0], data, TRUE);
    g_object_unref(dfields[0]);
    gwy_app_sync_data_items(data, data, oldid, newid, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    if (dfields[1]) {
        quark = gwy_app_get_mask_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[1]);
        g_object_unref(dfields[1]);
    }
    if (dfields[2]) {
        quark = gwy_app_get_show_key_for_id(newid);
        gwy_container_set_object(data, quark, dfields[2]);
        g_object_unref(dfields[2]);
    }

    gwy_app_set_data_field_title(data, newid, _("Rotated Data"));
    gwy_app_channel_log_add_proc(data, oldid, newid);
}
Пример #18
0
static void
deposit_dialog(DepositArgs *args,
            GwyContainer *data,
            GwyDataField *dfield,
            gint id)
{
    GtkWidget *dialog, *table, *hbox, *label, *pivot;
    DepositControls controls;
    gint response;
    GwyPixmapLayer *layer;
    gint row, newid;
    GwyDataField *rfield;

    controls.args = args;
    dialog = gtk_dialog_new_with_buttons(_("Deposit spherical particles"), NULL, 0,
                                         NULL);
    gtk_dialog_add_action_widget(GTK_DIALOG(dialog),
                                 gwy_stock_like_button_new(_("_Start"),
                                                           GTK_STOCK_EXECUTE),
                                 RESPONSE_PREVIEW);
    gtk_dialog_add_button(GTK_DIALOG(dialog), _("_Reset"), RESPONSE_RESET);
    gtk_dialog_add_button(GTK_DIALOG(dialog),
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
    gtk_dialog_add_button(GTK_DIALOG(dialog),
                          GTK_STOCK_OK, GTK_RESPONSE_OK);
    gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    controls.dialog = dialog;

    hbox = gtk_hbox_new(FALSE, 2);

    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox,
                       FALSE, FALSE, 4);

    controls.mydata = gwy_container_duplicate_by_prefix(data,
                                                        "/0/data/",
                                                        "/0/base/palette",
                                                        "/0/base/range-type",
                                                        "/0/base/", NULL);
    gwy_container_set_object_by_name(controls.mydata, "/0/data", gwy_data_field_duplicate(dfield));
    controls.old_dfield = gwy_data_field_duplicate(dfield);

    controls.view = gwy_data_view_new(controls.mydata);
    layer = gwy_layer_basic_new();
    g_object_set(layer,
                 "data-key", "/0/data",
                 "gradient-key", "/0/base/palette",
                 "range-type-key", "/0/base/range-type",
                 "min-max-key", "/0/base",
                 NULL);
    gwy_data_view_set_data_prefix(GWY_DATA_VIEW(controls.view), "/0/data");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);
    gwy_set_data_preview_size(GWY_DATA_VIEW(controls.view), PREVIEW_SIZE);

    gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4);

    table = gtk_table_new(10, 4, FALSE);
    gtk_table_set_row_spacings(GTK_TABLE(table), 2);
    gtk_table_set_col_spacings(GTK_TABLE(table), 6);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    gtk_box_pack_start(GTK_BOX(hbox), table, TRUE, TRUE, 4);
    row = 0;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Deposition parameters:")),
                     0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    table_attach_threshold(table, &row, _("_Size"),
                           &controls.size, args->size,
                           &controls);
    pivot = gwy_table_hscale_get_scale(controls.size);

    controls.value_size = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(controls.value_size), 1.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), controls.value_size,
                     2, 3, row, row+1, GTK_FILL, 0, 0, 0);
    g_signal_connect_swapped(controls.size, "value-changed",
                             G_CALLBACK(update_threshold_size), &controls);
    gwy_widget_sync_sensitivity(pivot, controls.value_size);

    controls.format_size
        = gwy_data_field_get_value_format_z(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP,
                                            NULL);
    label = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_label_set_markup(GTK_LABEL(label), controls.format_size->units);
    gtk_table_attach(GTK_TABLE(table), label,
                     3, 4, row, row+1, GTK_FILL, 0, 0, 0);
    gwy_widget_sync_sensitivity(pivot, label);

    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    /*
    table_attach_threshold(table, &row, _("_Distribution width"),
                           &controls.width, args->width,
                           &controls);
    pivot = gwy_table_hscale_get_scale(controls.width);

    controls.value_width = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(controls.value_width), 1.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), controls.value_width,
                     2, 3, row, row+1, GTK_FILL, 0, 0, 0);
    g_signal_connect_swapped(controls.width, "value-changed",
                             G_CALLBACK(update_threshold_width), &controls);
    gwy_widget_sync_sensitivity(pivot, controls.value_width);

    controls.format_width
        = gwy_data_field_get_value_format_z(dfield, GWY_SI_UNIT_FORMAT_VFMARKUP,
                                            NULL);
    label = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_label_set_markup(GTK_LABEL(label), controls.format_width->units);
    gtk_table_attach(GTK_TABLE(table), label,
                     3, 4, row, row+1, GTK_FILL, 0, 0, 0);
    gwy_widget_sync_sensitivity(pivot, label);

    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;
    */


    table_attach_threshold(table, &row, _("_Coverage:"),
                           &controls.coverage, args->coverage,
                           &controls);

    table_attach_threshold(table, &row, _("_Revise after settle"),
                           &controls.revise, args->revise,
                           &controls);

    gtk_table_set_row_spacing(GTK_TABLE(table), row-1, 8);


    deposit_invalidate(&controls);
    update_threshold_size(&controls);
    //update_threshold_width(&controls);

    /* finished initializing, allow instant updates */
    controls.in_init = FALSE;

    /* show initial preview if instant updates are on */
    gtk_widget_show_all(dialog);
    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            deposit_dialog_update_values(&controls, args);
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            g_object_unref(controls.mydata);
            gwy_si_unit_value_format_free(controls.format_size);
            //gwy_si_unit_value_format_free(controls.format_width);
            return;
            break;

            case GTK_RESPONSE_OK:
            break;

            case RESPONSE_RESET:
            *args = deposit_defaults;
            deposit_dialog_update_controls(&controls, args);
            controls.in_init = TRUE;
            preview(&controls, args);
            controls.in_init = FALSE;
            break;

            case RESPONSE_PREVIEW:
            deposit_dialog_update_values(&controls, args);
            preview(&controls, args);
            break;

            default:
            g_assert_not_reached();
            break;
        }
    } while (response != GTK_RESPONSE_OK);

    deposit_dialog_update_values(&controls, args);
    gwy_app_sync_data_items(controls.mydata, data, 0, id, FALSE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    gtk_widget_destroy(dialog);
    gwy_si_unit_value_format_free(controls.format_size);
    //gwy_si_unit_value_format_free(controls.format_width);

    if (args->computed) {
        rfield = gwy_container_get_object_by_name(controls.mydata, "/0/data");

        newid = gwy_app_data_browser_add_data_field(rfield,
                                                    data, TRUE);
        gwy_app_sync_data_items(data, data,
          id, newid, FALSE,
          GWY_DATA_ITEM_GRADIENT,
          GWY_DATA_ITEM_MASK_COLOR,
          GWY_DATA_ITEM_REAL_SQUARE,
          GWY_DATA_ITEM_SELECTIONS,
          0);
        gwy_app_set_data_field_title(data, newid, _("Particles"));

        g_object_unref(controls.mydata);
    }
}
Пример #19
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);
}