예제 #1
0
파일: tip.c 프로젝트: svn2github/gwyddion
static GwyDataField*
get_right_tip_field(GwyDataField *tip,
                    GwyDataField *surface,
                    gboolean *freetip)
{
    GwyDataField *buffer;
    gdouble tipxstep, tipystep;
    gdouble surfxstep, surfystep;

    *freetip = FALSE;
    tipxstep = tip->xreal/tip->xres;
    surfxstep = surface->xreal/surface->xres;
    tipystep = tip->yreal/tip->yres;
    surfystep = surface->yreal/surface->yres;

    if (fabs(tipxstep/surfxstep - 1.0) > 0.01
        || fabs(tipystep/surfystep - 1.0) > 0.01) {
        buffer = GWY_DATA_FIELD(gwy_data_field_new(tip->xres, tip->yres,
                                                   tip->xreal, tip->yreal,
                                                   FALSE));
        gwy_data_field_copy(tip, buffer);

        gwy_data_field_resample(buffer, tip->xres/surfxstep*tipxstep,
                                tip->yres/surfystep*tipystep,
                                GWY_INTERPOLATION_BILINEAR);
        *freetip = TRUE;
        return buffer;
    }
    else
        return tip;
}
예제 #2
0
static gboolean
prepare_fields(GwyDataField *tipfield,
               GwyDataField *surface,
               gint xres, gint yres)
{
    gint xoldres, yoldres;

    /*set real sizes corresponding to actual data*/
    gwy_data_field_set_xreal(tipfield,
                             gwy_data_field_get_xmeasure(surface)
                             *gwy_data_field_get_xres(tipfield));
    gwy_data_field_set_yreal(tipfield,
                             gwy_data_field_get_ymeasure(surface)
                             *gwy_data_field_get_yres(tipfield));

    /*if user has changed tip size, change it*/
    if ((xres != gwy_data_field_get_xres(tipfield))
        || (yres != gwy_data_field_get_yres(tipfield))) {
        xoldres = gwy_data_field_get_xres(tipfield);
        yoldres = gwy_data_field_get_yres(tipfield);
        gwy_data_field_resample(tipfield, xres, yres,
                                GWY_INTERPOLATION_NONE);
        gwy_data_field_set_xreal(tipfield,
                                 gwy_data_field_get_xreal(tipfield)
                                 /xoldres*xres);
        gwy_data_field_set_yreal(tipfield,
                                 gwy_data_field_get_yreal(tipfield)
                                 /yoldres*yres);
        gwy_data_field_clear(tipfield);
        return FALSE;
    }

    return TRUE;
}
예제 #3
0
static gboolean
prewitt_vertical(GwyContainer *data, GwyRunType run)
{
    GObject *shadefield;
    GwyDataField *dfield;

    g_assert(run & GRADIENT_RUN_MODES);
    
    dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(data, "/0/data"));
    gwy_app_undo_checkpoint(data, "/0/show", NULL);
    if (gwy_container_gis_object_by_name(data, "/0/show", &shadefield)) {
        gwy_data_field_resample(GWY_DATA_FIELD(shadefield),
                                gwy_data_field_get_xres(dfield),
                                gwy_data_field_get_yres(dfield),
                                GWY_INTERPOLATION_NONE);
    }
    else {
        shadefield = gwy_serializable_duplicate(G_OBJECT(dfield));
        gwy_container_set_object_by_name(data, "/0/show", shadefield);
        g_object_unref(shadefield);
    }

    gwy_data_field_area_copy(dfield, GWY_DATA_FIELD(shadefield), 
                             0, 0, gwy_data_field_get_xres(dfield),
                             gwy_data_field_get_yres(dfield), 0, 0);
    
    gwy_data_field_area_filter_prewitt(GWY_DATA_FIELD(shadefield), GTK_ORIENTATION_VERTICAL, 
                                     0, 0,
                                     gwy_data_field_get_xres(dfield),
                                     gwy_data_field_get_yres(dfield));
    return TRUE;
}
예제 #4
0
static void
flip_xy(GwyDataField *source, GwyDataField *dest, gboolean minor)
{
    gint xres, yres, i, j;
    gdouble *dd;
    const gdouble *sd;

    xres = gwy_data_field_get_xres(source);
    yres = gwy_data_field_get_yres(source);
    gwy_data_field_resample(dest, yres, xres, GWY_INTERPOLATION_NONE);
    sd = gwy_data_field_get_data_const(source);
    dd = gwy_data_field_get_data(dest);
    if (minor) {
        for (i = 0; i < xres; i++) {
            for (j = 0; j < yres; j++) {
                dd[i*yres + j] = sd[j*xres + (xres - 1 - i)];
            }
        }
    }
    else {
        for (i = 0; i < xres; i++) {
            for (j = 0; j < yres; j++) {
                dd[i*yres + (yres - 1 - j)] = sd[j*xres + i];
            }
        }
    }
    gwy_data_field_set_xreal(dest, gwy_data_field_get_yreal(source));
    gwy_data_field_set_yreal(dest, gwy_data_field_get_xreal(source));
}
예제 #5
0
static void
presentation_logscale(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *sfield;
    GQuark squark;
    gdouble *d;
    gdouble min, max, m0;
    gint xres, yres, i, zeroes, id;

    g_return_if_fail(run & PRESENTATIONOPS_RUN_MODES);
    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_SHOW_FIELD_KEY, &squark,
                                     GWY_APP_SHOW_FIELD, &sfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     0);
    g_return_if_fail(dfield && squark);

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    gwy_app_undo_qcheckpointv(data, 1, &squark);
    if (!sfield) {
        sfield = gwy_data_field_duplicate(dfield);
        gwy_container_set_object(data, squark, sfield);
        g_object_unref(sfield);
    }
    else {
        gwy_data_field_resample(sfield, xres, yres, GWY_INTERPOLATION_NONE);
        gwy_data_field_copy(dfield, sfield, FALSE);
    }

    d = gwy_data_field_get_data(sfield);
    zeroes = 0;
    max = 0;
    min = G_MAXDOUBLE;
    for (i = 0; i < xres*yres; i++) {
        d[i] = ABS(d[i]);
        if (G_UNLIKELY(d[i] > max))
            max = d[i];
        if (d[i] == 0.0)
            zeroes++;
        else if (G_UNLIKELY(d[i] < min))
            min = d[i];
    }
    if (min == max || zeroes == xres*yres)
        return;

    if (!zeroes) {
        for (i = 0; i < xres*yres; i++)
            d[i] = log(d[i]);
    }
    else {
        m0 = log(min) - log(max/min)/512.0;
        for (i = 0; i < xres*yres; i++)
            d[i] = d[i] ? log(d[i]) : m0;
    }

    gwy_data_field_data_changed(sfield);
    gwy_app_channel_log_add_proc(data, id, id);
}
예제 #6
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);
}
예제 #7
0
static void
tip_process(TipModelArgs *args,
            TipModelControls *controls)
{
    const GwyTipModelPreset *preset;
    GwyDataField *dfield;
    GwyDataField *sfield;
    GQuark quark;
    gchar label[64];
    gint xres, yres;
    gdouble xstep, ystep, min, max, zrange;
    gdouble params[2];

    preset = gwy_tip_model_get_preset(args->type);
    g_return_if_fail(preset);

    tip_model_dialog_update_values(controls, args);

    /* estimate x and y size */
    dfield = controls->tip;
    quark = gwy_app_get_data_key_for_id(args->object.id);
    sfield = GWY_DATA_FIELD(gwy_container_get_object(args->object.data, quark));

    gwy_data_field_set_xreal(dfield,
                             gwy_data_field_get_xmeasure(sfield)
                             *gwy_data_field_get_xres(dfield));
    gwy_data_field_set_yreal(dfield,
                             gwy_data_field_get_ymeasure(sfield)
                             *gwy_data_field_get_yres(dfield));

    params[0] = args->nsides;
    params[1] = args->angle*G_PI/180;
    gwy_data_field_get_min_max(sfield, &min, &max);
    zrange = max - min;
    preset->guess(sfield, zrange, args->radius, params, &xres, &yres);

    /* process tip */
    /* FIXME: this must be solved within guess functions */
    xres = CLAMP(xres, 20, 1000);
    yres = CLAMP(yres, 20, 1000);

    g_snprintf(label, sizeof(label), _("Tip resolution: %d × %d pixels"),
               xres, yres);
    gtk_label_set_text(GTK_LABEL(controls->labsize), label);

    xstep = gwy_data_field_get_xmeasure(dfield);
    ystep = gwy_data_field_get_ymeasure(dfield);
    gwy_data_field_resample(dfield, xres, yres, GWY_INTERPOLATION_NONE);
    gwy_data_field_set_xreal(dfield, xstep*xres);
    gwy_data_field_set_yreal(dfield, ystep*yres);

    preset->func(dfield, zrange, args->radius, args->theta*G_PI/180, params);
    tip_update(controls, args);
}
예제 #8
0
파일: tip.c 프로젝트: svn2github/gwyddion
/**
 * gwy_tip_erosion:
 * @tip: Tip data.
 * @surface: Surface to be eroded.
 * @result: Data field where to store dilated surface to.
 * @set_fraction: Function that sets fraction to output (or %NULL).
 * @set_message: Function that sets message to output (or %NULL).
 *
 * Performs surface reconstruction (erosion) algorithm published by
 * Villarrubia. This function converts all fields into form requested by
 * "morph_lib.c" library, that is almost identical with original Villarubia's
 * library.
 *
 * Returns: Reconstructed (eroded) surface, i.e. @result, on success.  May
 *          return %NULL if aborted.
 **/
GwyDataField*
gwy_tip_erosion(GwyDataField *tip,
                GwyDataField *surface,
                GwyDataField *result,
                GwySetFractionFunc set_fraction,
                GwySetMessageFunc set_message)
{
    gdouble **ftip;
    gdouble **fsurface;
    gdouble **fresult;
    GwyDataField *buffertip;
    gboolean freetip;

    /*if tip and surface have different spacings, make new, resampled tip*/
    buffertip = get_right_tip_field(tip, surface, &freetip);
    /*invert tip (as necessary by dilation algorithm)*/
    gwy_data_field_invert(buffertip, TRUE, TRUE, FALSE);

    /*make auxiliary data arrays expected by Villarubia's algorithms*/
    ftip = datafield_to_field(buffertip, TRUE);
    fsurface = datafield_to_field(surface, FALSE);

    fresult = _gwy_morph_lib_derosion(fsurface, surface->yres, surface->xres,
                                      ftip, buffertip->yres, buffertip->xres,
                                      buffertip->yres/2, buffertip->xres/2,
                                      set_fraction, set_message);

    /*convert result back from auxiliary array*/
    if (fresult) {
        gwy_data_field_resample(result, surface->xres, surface->yres,
                                GWY_INTERPOLATION_NONE);
        result = field_to_datafield(fresult, result);
    }
    else
        result = NULL;

    /*free auxiliary data arrays*/
    _gwy_morph_lib_dfreematrix(ftip, buffertip->xres);
    _gwy_morph_lib_dfreematrix(fsurface, surface->xres);
    if (fresult)
        _gwy_morph_lib_dfreematrix(fresult, result->xres);
    if (freetip)
        g_object_unref(buffertip);
    else
        gwy_data_field_invert(buffertip, TRUE, TRUE, FALSE);

    return result;
}
예제 #9
0
static void
tip_update(TipModelControls *controls,
           G_GNUC_UNUSED TipModelArgs *args)
{
   GwyDataField *vtipfield, *buffer;

   buffer = gwy_data_field_duplicate(controls->tip);
   gwy_data_field_resample(buffer, controls->vxres, controls->vyres,
                           GWY_INTERPOLATION_ROUND);

   vtipfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->vtip,
                                                               "/0/data"));
   gwy_data_field_copy(buffer, vtipfield, FALSE);
   g_object_unref(buffer);
   gwy_data_field_data_changed(vtipfield);
}
예제 #10
0
static void
preview(WshedControls *controls,
        WshedArgs *args)
{
    GwyDataField *maskfield, *dfield;
    GwyPixmapLayer *layer;

    dfield = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata,
                                                             "/0/data"));

    /*set up the mask*/
    if (gwy_container_contains_by_name(controls->mydata, "/0/mask")) {
        maskfield
            = GWY_DATA_FIELD(gwy_container_get_object_by_name(controls->mydata,
                                                              "/0/mask"));
        gwy_data_field_resample(maskfield,
                                gwy_data_field_get_xres(dfield),
                                gwy_data_field_get_yres(dfield),
                                GWY_INTERPOLATION_NONE);
        gwy_data_field_copy(dfield, maskfield);

        if (!gwy_data_view_get_alpha_layer(GWY_DATA_VIEW(controls->view))) {
            layer = GWY_PIXMAP_LAYER(gwy_layer_mask_new());
            gwy_data_view_set_alpha_layer(GWY_DATA_VIEW(controls->view),
                                          layer);
        }
    }
    else {
        maskfield
            = GWY_DATA_FIELD(gwy_serializable_duplicate(G_OBJECT(dfield)));
        gwy_container_set_object_by_name(controls->mydata, "/0/mask",
                                         G_OBJECT(maskfield));
        g_object_unref(maskfield);
        layer = GWY_PIXMAP_LAYER(gwy_layer_mask_new());
        gwy_data_view_set_alpha_layer(GWY_DATA_VIEW(controls->view),
                                 layer);

    }

    wshed_dialog_update_values(controls, args);
    controls->computed = mask_process(dfield, maskfield, args,
                                      controls->dialog);

    if (controls->computed)
        gwy_data_view_update(GWY_DATA_VIEW(controls->view));

}
예제 #11
0
static void
rotate_datafield(GwyDataField *dfield,
                 RotateArgs *args)
{
    gint xres, yres, xborder, yborder;
    gdouble xreal, yreal, phi, min;
    GwyDataField *df;

    if (!args->expand) {
        gwy_data_field_rotate(dfield, args->angle, args->interp);
        return;
    }

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);
    min = gwy_data_field_get_min(dfield);
    phi = args->angle;
    xborder = fabs(xres/2.0 * cos(phi)) + fabs(yres/2.0 * sin(phi));
    xborder -= xres/2;
    yborder = fabs(yres/2.0 * cos(phi)) + fabs(xres/2.0 * sin(phi));
    yborder -= yres/2;
    df = gwy_data_field_new(xres + fabs(2*xborder), yres + fabs(2*yborder), 1.0, 1.0,
                            FALSE);
    gwy_data_field_fill(df, min);
    gwy_data_field_area_copy(dfield, df, 0, 0, xres, yres, fabs(xborder), fabs(yborder));
    gwy_data_field_rotate(df, args->angle, args->interp);
    gwy_data_field_resample(dfield, xres + 2*xborder, yres + 2*yborder,
                            GWY_INTERPOLATION_NONE);
    if (xborder <= 0)
        gwy_data_field_area_copy(df, dfield, fabs(2*xborder), 0, xres + 2*xborder, yres + 2*yborder, 0, 0);
    else {
          if (yborder <= 0)
              gwy_data_field_area_copy(df, dfield, 0, fabs(2*yborder), xres + 2*xborder, yres + 2*yborder, 0, 0);
          else
            gwy_data_field_area_copy(df, dfield, 0, 0, xres + 2*xborder, yres + 2*yborder, 0, 0);
    }
    gwy_data_field_set_xreal(dfield, xreal*(xres + 2.0*xborder)/xres);
    gwy_data_field_set_yreal(dfield, yreal*(yres + 2.0*yborder)/yres);
    g_object_unref(df);
}
예제 #12
0
static void
read_data_field(GwyDataField *dfield,
                EZDSection *section)
{
    gdouble *data;
    gdouble q, z0;
    guint i, j;
    gint xres, yres;

    g_assert(section->data);
    xres = section->xres;
    yres = section->yres;
    gwy_data_field_resample(dfield, xres, yres, GWY_INTERPOLATION_NONE);
    data = gwy_data_field_get_data(dfield);

    q = 1 << section->bitdepth;
    z0 = q/2.0;
    if (section->bitdepth == 8) {
        const gchar *p = section->data;

        for (i = 0; i < yres; i++) {
            for (j = 0; j < xres; j++)
                data[i*xres + j] = (p[(yres-1 - i)*xres + j] + z0)/q;
        }
    }
    else if (section->bitdepth == 16) {
        const gint16 *p = (const gint16*)section->data;

        for (i = 0; i < yres; i++) {
            for (j = 0; j < xres; j++) {
                data[i*xres + j] = GINT16_FROM_LE(p[(yres-1 - i)*xres + j]);
                data[i*xres + j] = (data[i*xres + j] + z0)/q;
            }
        }
    }
    else
        g_warning("Damn! Bit depth %d is not implemented", section->bitdepth);
}
예제 #13
0
/* create a smaller copy of data */
static GwyContainer*
create_preview_data(GwyContainer *data)
{
    GwyContainer *preview;
    GwyDataField *dfield, *dfield_show;
    gint oldid;
    gint xres, yres;
    gdouble zoomval;

    preview = gwy_container_new();

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &oldid,
                                     0);

    dfield = gwy_data_field_duplicate(dfield);
    dfield_show = gwy_data_field_duplicate(dfield);

    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    zoomval = (gdouble)PREVIEW_SIZE/MAX(xres, yres);
    gwy_data_field_resample(dfield, xres*zoomval, yres*zoomval,
                            GWY_INTERPOLATION_LINEAR);
    dfield_show = gwy_data_field_duplicate(dfield);

    gwy_container_set_object_by_name(preview, "/0/data", dfield);
    g_object_unref(dfield);
    gwy_container_set_object_by_name(preview, "/0/show", dfield_show);
    g_object_unref(dfield_show);

    gwy_app_sync_data_items(data, preview, oldid, 0, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            GWY_DATA_ITEM_RANGE,
                            GWY_DATA_ITEM_MASK_COLOR,
                            0);
    return preview;
}
예제 #14
0
static void
fill_data_fields(SurfFile *surffile,
                 const guchar *buffer)
{
    gdouble *data;
    guint i, j;

    surffile->dfield = GWY_DATA_FIELD(gwy_data_field_new(surffile->xres,
                                                   surffile->yres,
                                                   surffile->xres*surffile->dx,
                                                   surffile->yres*surffile->dy,
                                                   TRUE));


    data = gwy_data_field_get_data(surffile->dfield);
    switch (surffile->pointsize) {
        case 16:
        {
            const gint16 *row, *d16 = (const gint16*)buffer;

            for (i = 0; i < surffile->xres; i++) {
                row = d16 + i*surffile->yres;
                for (j = 0; j < surffile->yres; j++)
                    *(data++) = GINT16_FROM_LE(row[j]) * surffile->dz;
            }
        }
        break;

        case 32:
        {
            const gint32 *row, *d32 = (const gint32*)buffer;

            for (i = 0; i < surffile->xres; i++) {
                row = d32 + i*surffile->yres;
                for (j = 0; j < surffile->yres; j++)
                    *(data++) = GINT32_FROM_LE(row[j]) * surffile->dz;
            }
        }
        break;

        default:
        g_warning("Wrong data size: %d", surffile->pointsize);
        break;
    }


    /*
    data = gwy_data_field_get_data(surffile->dfield);
    for (i = 0; i < surffile->xres; i++) {
        for (j = 0; j < surffile->yres; j++) {
            if (surffile->pointsize == 16) {
                *(data++) = (gdouble)*(gint16*)buffer*surffile->dz;
                buffer += 2;
            }
            else {
                *(data++) = ((gdouble)*(gint32*)buffer)*surffile->dz;
                buffer += 4;
            }
        }
    }
    */

    if (surffile->dx > surffile->dy)
        gwy_data_field_resample(surffile->dfield, (gint)((gdouble)(surffile->xres)*surffile->dx/surffile->dy),
                                surffile->yres, GWY_INTERPOLATION_BILINEAR);

    else if (surffile->dy > surffile->dx)
        gwy_data_field_resample(surffile->dfield, surffile->xres,
                                (gint)((gdouble)(surffile->yres)*surffile->dy/surffile->dx),
                                GWY_INTERPOLATION_BILINEAR);
}
예제 #15
0
static void
tip_model_dialog(TipModelArgs *args)
{
    enum {
        RESPONSE_RESET   = 1,
        RESPONSE_PREVIEW = 2
    };
    GtkWidget *dialog, *table, *hbox, *spin;
    TipModelControls controls;
    GwyPixmapLayer *layer;
    GwyDataField *dfield;
    GwySIUnit *unit;
    GQuark quark;
    gint response, row;

    dialog = gtk_dialog_new_with_buttons(_("Model Tip"), NULL, 0, NULL);
    gtk_dialog_add_action_widget(GTK_DIALOG(dialog),
                                 gwy_stock_like_button_new(_("_Update"),
                                                           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);

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

    controls.args = args;
    controls.vxres = 200;
    controls.vyres = 200;

    /* set up initial tip field */
    quark = gwy_app_get_data_key_for_id(args->object.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(args->object.data, quark));

    controls.tip = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_resample(controls.tip, controls.vxres, controls.vyres,
                            GWY_INTERPOLATION_NONE);
    gwy_data_field_clear(controls.tip);

    /*set up data of rescaled image of the tip*/
    controls.vtip = gwy_container_new();
    gwy_app_sync_data_items(args->object.data, controls.vtip,
                            args->object.id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE, 0);

    dfield = gwy_data_field_new_alike(controls.tip, TRUE);
    gwy_container_set_object_by_name(controls.vtip, "/0/data", dfield);
    g_object_unref(dfield);

    /* set up resampled view */
    controls.view = gwy_data_view_new(controls.vtip);
    layer = gwy_layer_basic_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/data");
    gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);

    /* set up tip model controls */
    gtk_box_pack_start(GTK_BOX(hbox), controls.view, FALSE, FALSE, 4);

    table = gtk_table_new(6, 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, FALSE, FALSE, 4);
    row = 0;

    controls.type = create_preset_menu(G_CALLBACK(tip_type_cb),
                                       &controls, args->type);
    gwy_table_attach_hscale(table, row, _("Tip _type:"), NULL,
                            GTK_OBJECT(controls.type), GWY_HSCALE_WIDGET);
    row++;

    controls.nsides = gtk_adjustment_new(args->nsides, 3, 24, 1, 5, 0);
    gwy_table_attach_hscale(table, row, _("_Number of sides:"), NULL,
                            controls.nsides, 0);
    row++;

    controls.angle = gtk_adjustment_new(args->angle, 0.1, 89.9, 0.1, 1, 0);
    spin = gwy_table_attach_hscale(table, row, _("Tip _slope:"), _("deg"),
                                   controls.angle, 0);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 2);
    row++;

    controls.theta = gtk_adjustment_new(args->theta, 0, 360, 0.1, 1, 0);
    spin = gwy_table_attach_hscale(table, row, _("Tip _rotation:"), _("deg"),
                                   controls.theta, 0);
    gtk_spin_button_set_digits(GTK_SPIN_BUTTON(spin), 2);
    row++;

    controls.radius = gtk_adjustment_new(1.0, 0.01, 1000.0, 0.01, 1.0, 0.0);
    controls.radius_spin = gtk_spin_button_new(GTK_ADJUSTMENT(controls.radius),
                                               0.1, 2);
    gtk_table_attach(GTK_TABLE(table), controls.radius_spin,
                     2, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    controls.radius_label = gtk_label_new_with_mnemonic(_("Tip _apex radius:"));
    gtk_misc_set_alignment(GTK_MISC(controls.radius_label), 0.0, 0.5);
    gtk_label_set_mnemonic_widget(GTK_LABEL(controls.radius_label),
                                  controls.radius_spin);
    gtk_table_attach(GTK_TABLE(table), controls.radius_label,
                     0, 1, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    unit = gwy_data_field_get_si_unit_xy(dfield);
    controls.radius_unit
        = gwy_combo_box_metric_unit_new(G_CALLBACK(radius_changed_cb),
                                        &controls,
                                        -12, -3, unit, -9);
    gtk_table_attach(GTK_TABLE(table), controls.radius_unit,
                     3, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.radius, "value-changed",
                     G_CALLBACK(radius_changed_cb), &controls);
    row++;

    controls.labsize = gtk_label_new(NULL);
    gtk_misc_set_alignment(GTK_MISC(controls.labsize), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), controls.labsize,
                     0, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.tipdone = FALSE;
    tip_model_dialog_update_controls(&controls, args);
    preview(&controls, args);

    gtk_widget_show_all(dialog);
    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            tip_model_dialog_update_values(&controls, args);
            gtk_widget_destroy(dialog);
            tip_model_dialog_abandon(&controls);
            case GTK_RESPONSE_NONE:
            return;
            break;

            case GTK_RESPONSE_OK:
            tip_model_do(args, &controls);
            break;

            case RESPONSE_RESET:
            args->nsides = tip_model_defaults.nsides;
            args->angle = tip_model_defaults.angle;
            args->radius = tip_model_defaults.radius;
            args->theta = tip_model_defaults.theta;
            args->type = tip_model_defaults.type;
            tip_model_dialog_update_controls(&controls, args);
            break;

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

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

    tip_model_dialog_update_values(&controls, args);
    gtk_widget_destroy(dialog);
    tip_model_dialog_abandon(&controls);
}
예제 #16
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);
}
예제 #17
0
static void
tip_blind_dialog(TipBlindArgs *args)
{
    GtkWidget *dialog, *table, *hbox, *vbox, *label;
    GwyContainer *data;
    GwyGraphModel *gmodel;
    GwyGraphArea *area;
    TipBlindControls controls;
    GwyPixmapLayer *layer;
    GwyDataField *dfield;
    GQuark quark;
    GwySIUnit *unit;
    gint response, row;

    dialog = gtk_dialog_new_with_buttons(_("Blind Tip Estimation"), NULL, 0,
                                         _("Run _Partial"), RESPONSE_ESTIMATE,
                                         _("Run _Full"), RESPONSE_REFINE,
                                         _("_Reset Tip"), RESPONSE_RESET,
                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                                         GTK_STOCK_OK, GTK_RESPONSE_OK,
                                         NULL);
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK);
    gwy_help_add_to_proc_dialog(GTK_DIALOG(dialog), GWY_HELP_DEFAULT);

    controls.args = args;
    controls.in_update = TRUE;
    controls.good_tip = FALSE;
    controls.dialog = dialog;
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog), GTK_RESPONSE_OK,
                                      controls.good_tip);

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

    controls.vxres = 240;
    controls.vyres = 240;
    controls.oldnstripes = args->nstripes;

    /* set initial tip properties */
    data = gwy_app_data_browser_get(args->source.datano);
    quark = gwy_app_get_data_key_for_id(args->source.id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));

    controls.tip = gwy_data_field_new_alike(dfield, TRUE);
    gwy_data_field_resample(controls.tip, args->xres, args->yres,
                            GWY_INTERPOLATION_NONE);
    gwy_data_field_clear(controls.tip);

    /* set up data of rescaled image of the tip */
    controls.vtip = gwy_container_new();
    gwy_app_sync_data_items(data, controls.vtip,
                            args->source.id, 0, FALSE,
                            GWY_DATA_ITEM_PALETTE,
                            0);

    dfield = gwy_data_field_new_alike(controls.tip, TRUE);
    gwy_data_field_resample(dfield, controls.vxres, controls.vyres,
                            GWY_INTERPOLATION_ROUND);
    gwy_container_set_object_by_name(controls.vtip, "/0/data", dfield);
    g_object_unref(dfield);

    /* set up rescaled image of the tip */
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);

    controls.view = gwy_data_view_new(controls.vtip);
    layer = gwy_layer_basic_new();
    gwy_pixmap_layer_set_data_key(layer, "/0/data");
    gwy_layer_basic_set_gradient_key(GWY_LAYER_BASIC(layer), "/0/base/palette");
    gwy_data_view_set_base_layer(GWY_DATA_VIEW(controls.view), layer);

    /* set up tip estimation controls */
    gtk_box_pack_start(GTK_BOX(vbox), controls.view, FALSE, FALSE, 0);

    gmodel = gwy_graph_model_new();
    controls.graph = gwy_graph_new(gmodel);
    g_object_unref(gmodel);
    gwy_axis_set_visible(gwy_graph_get_axis(GWY_GRAPH(controls.graph),
                                            GTK_POS_LEFT),
                         FALSE);
    gwy_axis_set_visible(gwy_graph_get_axis(GWY_GRAPH(controls.graph),
                                            GTK_POS_BOTTOM),
                         FALSE);
    area = GWY_GRAPH_AREA(gwy_graph_get_area(GWY_GRAPH(controls.graph)));
    gtk_widget_set_no_show_all(gwy_graph_area_get_label(area), TRUE);
    g_signal_connect_after(gwy_graph_area_get_label(area), "map",
                           G_CALLBACK(gtk_widget_hide), NULL);
    gtk_box_pack_start(GTK_BOX(vbox), controls.graph, TRUE, TRUE, 0);

    table = gtk_table_new(13, 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, FALSE, FALSE, 4);
    row = 0;

    controls.data = gwy_data_chooser_new_channels();
    gwy_data_chooser_set_filter(GWY_DATA_CHOOSER(controls.data),
                                tip_blind_source_filter, &args->orig, NULL);
    gwy_data_chooser_set_active_id(GWY_DATA_CHOOSER(controls.data),
                                   &args->source);
    g_signal_connect(controls.data, "changed",
                     G_CALLBACK(data_changed), &args->source);
    gwy_table_attach_hscale(table, row, _("Related _data:"), NULL,
                            GTK_OBJECT(controls.data), GWY_HSCALE_WIDGET);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    label = gtk_label_new(_("Estimated Tip Size"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 4, row, row+1, GTK_FILL, 0, 0, 0);
    row++;

    controls.xres = gtk_adjustment_new(args->xres, MIN_RES, MAX_RES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Width:"), "px", controls.xres, 0);
    g_object_set_data(G_OBJECT(controls.xres), "controls", &controls);
    g_signal_connect(controls.xres, "value-changed",
                     G_CALLBACK(width_changed), &controls);
    row++;

    controls.yres = gtk_adjustment_new(args->yres, MIN_RES, MAX_RES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Height:"), "px", controls.yres, 0);
    g_object_set_data(G_OBJECT(controls.yres), "controls", &controls);
    g_signal_connect(controls.yres, "value-changed",
                     G_CALLBACK(height_changed), &controls);
    row++;

    controls.same_resolution
        = gtk_check_button_new_with_mnemonic(_("_Same resolution"));
    gtk_table_attach(GTK_TABLE(table), controls.same_resolution,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.same_resolution),
                                 args->same_resolution);
    g_signal_connect(controls.same_resolution, "toggled",
                     G_CALLBACK(same_resolution_changed), &controls);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Options")),
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.threshold = gtk_adjustment_new(1.0, 0.01, 1000.0, 0.01, 1.0, 0.0);
    controls.threshold_spin
        = gtk_spin_button_new(GTK_ADJUSTMENT(controls.threshold), 0.1, 2);
    gtk_table_attach(GTK_TABLE(table), controls.threshold_spin,
                     2, 3, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    label = gtk_label_new_with_mnemonic(_("Noise suppression t_hreshold:"));
    gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
    gtk_label_set_mnemonic_widget(GTK_LABEL(label), controls.threshold_spin);
    gtk_table_attach(GTK_TABLE(table), label,
                     0, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    unit = gwy_data_field_get_si_unit_z(dfield);
    controls.threshold_unit
        = gwy_combo_box_metric_unit_new(G_CALLBACK(thresh_changed),
                                        &controls,
                                        -12, -3, unit, -9);
    gtk_table_attach(GTK_TABLE(table), controls.threshold_unit,
                     3, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.threshold, "value-changed",
                     G_CALLBACK(thresh_changed), &controls);
    sci_entry_set_value(GTK_ADJUSTMENT(controls.threshold),
                        GTK_COMBO_BOX(controls.threshold_unit),
                        args->thresh);
    row++;

    controls.boundaries
                    = gtk_check_button_new_with_mnemonic(_("Use _boundaries"));
    gtk_table_attach(GTK_TABLE(table), controls.boundaries,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.boundaries),
                                                 args->use_boundaries);
    g_signal_connect(controls.boundaries, "toggled",
                     G_CALLBACK(bound_changed), args);
    gtk_table_set_row_spacing(GTK_TABLE(table), row, 8);
    row++;

    gtk_table_attach(GTK_TABLE(table), gwy_label_new_header(_("Stripes")),
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    row++;

    controls.nstripes = gtk_adjustment_new(args->nstripes,
                                           MIN_STRIPES, MAX_STRIPES, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Split to stripes:"), NULL,
                            controls.nstripes, GWY_HSCALE_CHECK);
    controls.split_to_stripes = gwy_table_hscale_get_check(controls.nstripes);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                                 !args->split_to_stripes);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                                 args->split_to_stripes);
    g_signal_connect(controls.split_to_stripes, "toggled",
                     G_CALLBACK(split_to_stripes_changed), &controls);
    g_signal_connect(controls.nstripes, "value-changed",
                     G_CALLBACK(nstripes_changed), &controls);
    row++;

    controls.stripeno = gtk_adjustment_new(1, 1, args->nstripes, 1, 10, 0);
    gwy_table_attach_hscale(table, row, _("_Preview stripe:"), NULL,
                            controls.stripeno, GWY_HSCALE_DEFAULT);
    g_signal_connect(controls.stripeno, "value-changed",
                     G_CALLBACK(stripeno_changed), &controls);
    row++;

    controls.plot_size_graph
        = gtk_check_button_new_with_mnemonic(_("Plot size _graph"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.plot_size_graph),
                                 args->plot_size_graph);
    gtk_table_attach(GTK_TABLE(table), controls.plot_size_graph,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.plot_size_graph, "toggled",
                     G_CALLBACK(plot_size_graph_changed), &controls);
    row++;

    controls.create_images
        = gtk_check_button_new_with_mnemonic(_("Create tip i_mages"));
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(controls.create_images),
                                 args->create_images);
    gtk_table_attach(GTK_TABLE(table), controls.create_images,
                     0, 4, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0);
    g_signal_connect(controls.create_images, "toggled",
                     G_CALLBACK(create_images_changed), &controls);
    row++;

    controls.tipdone = FALSE;
    controls.in_update = FALSE;
    split_to_stripes_changed(GTK_TOGGLE_BUTTON(controls.split_to_stripes),
                             &controls);
    gtk_widget_show_all(dialog);

    do {
        response = gtk_dialog_run(GTK_DIALOG(dialog));
        switch (response) {
            case GTK_RESPONSE_CANCEL:
            case GTK_RESPONSE_DELETE_EVENT:
            gtk_widget_destroy(dialog);
            case GTK_RESPONSE_NONE:
            tip_blind_dialog_abandon(&controls);
            tip_blind_save_args(gwy_app_settings_get(), args);
            return;
            break;

            case GTK_RESPONSE_OK:
            tip_blind_save_args(gwy_app_settings_get(), args);
            tip_blind_do(&controls, args);
            break;

            case RESPONSE_RESET:
            reset(&controls, args);
            break;

            case RESPONSE_ESTIMATE:
            tip_blind_run(&controls, args, FALSE);
            break;

            case RESPONSE_REFINE:
            tip_blind_run(&controls, args, TRUE);
            break;

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

    gtk_widget_destroy(dialog);
    tip_blind_dialog_abandon(&controls);

    return;
}
예제 #18
0
/**
 * gwy_data_field_correlate:
 * @data_field: A data field.
 * @kernel_field: Correlation kernel.
 * @score: Data field to store correlation scores to.
 * @method: Correlation score calculation method.
 *
 * Computes correlation score for all positions in a data field.
 *
 * Correlation score is compute for all points in data field @data_field
 * and full size of correlation kernel @kernel_field.
 *
 * The points in @score correspond to centers of kernel.  More precisely, the
 * point ((@kxres-1)/2, (@kyres-1)/2) in @score corresponds to kernel field
 * top left corner coincident with data field top left corner.  Points outside
 * the area where the kernel field fits into the data field completely are
 * set to -1 for %GWY_CORRELATION_NORMAL.
 **/
void
gwy_data_field_correlate(GwyDataField *data_field, GwyDataField *kernel_field,
                         GwyDataField *score, GwyCorrelationType method)
{

    gint xres, yres, kxres, kyres, i, j, k, fftxres, fftyres;
    GwyDataField *data_in_re, *data_out_re, *data_out_im;
    GwyDataField *kernel_in_re, *kernel_out_re, *kernel_out_im;
    gdouble norm;

    g_return_if_fail(data_field != NULL && kernel_field != NULL);

    xres = data_field->xres;
    yres = data_field->yres;
    kxres = kernel_field->xres;
    kyres = kernel_field->yres;

    if (kxres <= 0 || kyres <= 0) {
        g_warning("Correlation kernel has nonpositive size.");
        return;
    }

    switch (method) {
        case GWY_CORRELATION_NORMAL:
        gwy_data_field_fill(score, -1);
        /*correlation request outside kernel */
        if (kxres > xres || kyres > yres) {
            return;
        }

        {
            GwyDataField *avg, *rms;
            gdouble s, davg, drms, kavg, krms;
            gint xoff, yoff;

            /* The number of pixels the correlation kernel extends to the
             * negative direction */
            xoff = (kxres - 1)/2;
            yoff = (kyres - 1)/2;
            kavg = gwy_data_field_get_avg(kernel_field);
            krms = gwy_data_field_get_rms(kernel_field);
            avg = gwy_data_field_duplicate(data_field);
            rms = gwy_data_field_duplicate(data_field);
            calculate_normalization(avg, rms, kxres, kyres);
            for (i = yoff; i + kyres - yoff <= yres; i++) {
                for (j = xoff; j + kxres - xoff <= xres; j++) {
                    k = i*xres + j;
                    davg = avg->data[k];
                    drms = rms->data[k];
                    if (!krms || !drms) {
                        score->data[k] = 0.0;
                        continue;
                    }
                    s = gwy_data_field_get_raw_correlation_score(data_field,
                                                                 kernel_field,
                                                                 j - xoff,
                                                                 i - yoff,
                                                                 0, 0,
                                                                 kxres, kyres,
                                                                 davg, kavg);
                    score->data[k] = s/(drms*krms);
                }
            }
            g_object_unref(avg);
            g_object_unref(rms);
        }
        break;

        case GWY_CORRELATION_FFT:
        case GWY_CORRELATION_POC:
        fftxres = gwy_fft_find_nice_size(xres);
        fftyres = gwy_fft_find_nice_size(yres);
        data_in_re = gwy_data_field_new_resampled(data_field,
                                                  fftxres, fftyres,
                                                  GWY_INTERPOLATION_BILINEAR);
        kernel_in_re = gwy_data_field_new_alike(data_field, TRUE);
        gwy_data_field_area_copy(kernel_field, kernel_in_re,
                                 0, 0, kernel_field->xres, kernel_field->yres,
                                 kernel_in_re->xres/2 - kernel_field->xres/2,
                                 kernel_in_re->yres/2 - kernel_field->yres/2);
        gwy_data_field_resample(kernel_in_re, fftxres, fftyres,
                                GWY_INTERPOLATION_BILINEAR);
        gwy_data_field_resample(score, fftxres, fftyres,
                                GWY_INTERPOLATION_NONE);

        data_out_re = gwy_data_field_new_alike(data_in_re, TRUE);
        data_out_im = gwy_data_field_new_alike(data_in_re, TRUE);
        kernel_out_re = gwy_data_field_new_alike(data_in_re, TRUE);
        kernel_out_im = gwy_data_field_new_alike(data_in_re, TRUE);

        gwy_data_field_2dfft(data_in_re, NULL, data_out_re, data_out_im,
                             GWY_WINDOWING_NONE,
                             GWY_TRANSFORM_DIRECTION_FORWARD,
                             GWY_INTERPOLATION_BILINEAR, FALSE, FALSE);
        gwy_data_field_2dfft(kernel_in_re, NULL, kernel_out_re, kernel_out_im,
                             GWY_WINDOWING_NONE,
                             GWY_TRANSFORM_DIRECTION_FORWARD,
                             GWY_INTERPOLATION_BILINEAR, FALSE, FALSE);

        for (i = 0; i < fftxres*fftyres; i++) {
            /*NOTE: now we construct new "complex field" from data
             * and kernel fields, just to save memory*/
            data_in_re->data[i] = data_out_re->data[i]*kernel_out_re->data[i]
                + data_out_im->data[i]*kernel_out_im->data[i];
            kernel_in_re->data[i] = -data_out_re->data[i]*kernel_out_im->data[i]
                + data_out_im->data[i]*kernel_out_re->data[i];
            if (method == GWY_CORRELATION_POC) {
                norm = hypot(data_in_re->data[i], kernel_in_re->data[i]);
                data_in_re->data[i] /= norm;
                kernel_in_re->data[i] /= norm;
            }
        }
        gwy_data_field_2dfft(data_in_re, kernel_in_re, score, data_out_im,
                             GWY_WINDOWING_NONE,
                             GWY_TRANSFORM_DIRECTION_BACKWARD,
                             GWY_INTERPOLATION_BILINEAR, FALSE, FALSE);
        gwy_data_field_2dfft_humanize(score);

        /*TODO compute it and put to score field*/
        g_object_unref(data_in_re);
        g_object_unref(data_out_re);
        g_object_unref(data_out_im);
        g_object_unref(kernel_in_re);
        g_object_unref(kernel_out_re);
        g_object_unref(kernel_out_im);
        break;
    }

    gwy_data_field_invalidate(score);
}
예제 #19
0
파일: cwt.c 프로젝트: svn2github/gwyddion
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"));
}
예제 #20
0
static void
dwt_anisotropy(GwyContainer *data, GwyRunType run)
{
    GtkWidget *dialog;
    GwyDataField *dfield, *mask;
    GQuark dquark, mquark;
    GwyDataLine *wtcoefs;
    DWTAnisotropyArgs args;
    gboolean ok;
    gint xsize, ysize, newsize, limit, id, i;

    g_return_if_fail(run & DWT_ANISOTROPY_RUN_MODES);

    gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD_KEY, &dquark,
                                     GWY_APP_DATA_FIELD, &dfield,
                                     GWY_APP_DATA_FIELD_ID, &id,
                                     GWY_APP_MASK_FIELD_KEY, &mquark,
                                     GWY_APP_MASK_FIELD, &mask,
                                     0);
    g_return_if_fail(dfield && dquark);

    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, id),
             GTK_DIALOG_DESTROY_WITH_PARENT,
             GTK_MESSAGE_ERROR,
             GTK_BUTTONS_OK,
             _("%s: Data must be square."), _("DWT Anisotropy"));
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    dwt_anisotropy_load_args(gwy_app_settings_get(), &args);
    if (run == GWY_RUN_INTERACTIVE) {
        ok = dwt_anisotropy_dialog(&args);
        dwt_anisotropy_save_args(gwy_app_settings_get(), &args);
        if (!ok)
            return;
    }

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

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

    gwy_app_undo_qcheckpoint(data, dquark, mquark, 0);
    if (!mask) {
        mask = gwy_data_field_new_alike(dfield, FALSE);
        gwy_container_set_object(data, mquark, mask);
        g_object_unref(mask);
    }
    gwy_data_field_resample(mask, newsize, newsize, GWY_INTERPOLATION_NONE);

    wtcoefs = gwy_data_line_new(10, 10, TRUE);
    wtcoefs = gwy_dwt_set_coefficients(wtcoefs, args.wavelet);

    /*justo for sure clamp the lowlimit again*/
    limit = pow(2, CLAMP(args.lowlimit, 1, 20));
    gwy_data_field_dwt_mark_anisotropy(dfield, mask, wtcoefs, args.ratio,
                                       limit);

    gwy_data_field_resample(mask, xsize, ysize, GWY_INTERPOLATION_ROUND);
    g_object_unref(wtcoefs);
    g_object_unref(dfield);
    gwy_data_field_data_changed(mask);
    gwy_app_channel_log_add_proc(data, id, id);
}
예제 #21
0
파일: tip.c 프로젝트: svn2github/gwyddion
/**
 * gwy_tip_cmap:
 * @tip: Tip data.
 * @surface: Surface data.
 * @result: Data field to store ceratainty map data to.
 * @set_fraction: Function that sets fraction to output (or %NULL).
 * @set_message: Function that sets message to output (of %NULL).
 *
 * Performs certainty map algorithm published by Villarrubia. This function
 * converts all fields into form requested by "morph_lib.c" library, that is
 * almost identical with original Villarubia's library. Result certainty map
 * can be used as a mask of points where tip did not directly touch the
 * surface.
 *
 * Returns: Certainty map, i.e. @result, on success.  May return %NULL if
 *          aborted.
 **/
GwyDataField*
gwy_tip_cmap(GwyDataField *tip,
             GwyDataField *surface,
             GwyDataField *result,
             GwySetFractionFunc set_fraction,
             GwySetMessageFunc set_message)
{
    gint **ftip;
    gint **fsurface;
    gint **rsurface;
    gint **fresult;
    gint newx, newy;
    gdouble tipmin, surfacemin, step;
    GwyDataField *buffertip;
    gboolean freetip;

    newx = surface->xres + tip->xres;
    newy = surface->yres + tip->yres;

    /*if tip and surface have different spacings, make new, resampled tip*/
    buffertip = get_right_tip_field(tip, surface, &freetip);
    /*invert tip (as necessary by dilation algorithm)*/
    gwy_data_field_invert(buffertip, TRUE, TRUE, FALSE);

    /*convert fields to integer arrays*/
    tipmin = gwy_data_field_get_min(buffertip);
    surfacemin = gwy_data_field_get_min(surface);
    step = (gwy_data_field_get_max(surface) - surfacemin)/10000;

    ftip = i_datafield_to_field(buffertip, TRUE, tipmin, step);
    fsurface = i_datafield_to_largefield(surface, buffertip, surfacemin, step);

    /*perform erosion as it is necessary parameter of certainty map algorithm*/
    rsurface = _gwy_morph_lib_ierosion(fsurface, newy, newx,
                                       ftip, buffertip->yres, buffertip->xres,
                                       buffertip->yres/2, buffertip->xres/2,
                                       set_fraction, set_message);
    if (!rsurface) {
        _gwy_morph_lib_ifreematrix(ftip, buffertip->xres);
        _gwy_morph_lib_ifreematrix(fsurface, newx);
       if (freetip)
           g_object_unref(buffertip);
       return NULL;
    }

    /*find certanty map*/
    if (rsurface) {
        fresult = _gwy_morph_lib_icmap(fsurface, newy, newx,
                                       ftip, buffertip->yres, buffertip->xres,
                                       rsurface,
                                       buffertip->yres/2, buffertip->xres/2,
                                       set_fraction, set_message);
    }
    else
        fresult = NULL;

    /*convert result back*/
    if (fresult) {
        gwy_data_field_resample(result, surface->xres, surface->yres,
                                GWY_INTERPOLATION_NONE);
        result = i_largefield_to_datafield(fresult, result, buffertip,
                                           0.0, 1.0);
    }
    else
        result = NULL;

    _gwy_morph_lib_ifreematrix(ftip, buffertip->xres);
    _gwy_morph_lib_ifreematrix(fsurface, newx);
    _gwy_morph_lib_ifreematrix(rsurface, newx);
    if (fresult)
        _gwy_morph_lib_ifreematrix(fresult, result->xres);
    if (freetip)
        g_object_unref(buffertip);
    else
        gwy_data_field_invert(buffertip, TRUE, TRUE, FALSE);

    return result;
}
예제 #22
0
static void
psdflp_do(const PSDFLPArgs *args, GwyDataField *dfield, GwyDataField *lpsdf)
{
    enum { N = 4 };

    GwyDataField *reout, *imout;
    gint pxres, pyres, fxres, fyres;
    gint i, j, fi, pi;
    gdouble *ldata, *redata, *imdata;
    gdouble *cosphi, *sinphi;
    gdouble xreal, yreal, f0, f_max, b, p;

    reout = gwy_data_field_new_alike(dfield, FALSE);
    imout = gwy_data_field_new_alike(dfield, FALSE);
    gwy_data_field_2dfft(dfield, NULL, reout, imout,
                         args->window, GWY_TRANSFORM_DIRECTION_FORWARD,
                         GWY_INTERPOLATION_ROUND, /* Ignored */
                         TRUE, 1);

    pxres = reout->xres;
    pyres = reout->yres;
    redata = gwy_data_field_get_data(reout);
    imdata = gwy_data_field_get_data(imout);
    for (i = 0; i < pxres*pyres; i++)
        redata[i] = redata[i]*redata[i] + imdata[i]*imdata[i];
    gwy_data_field_2dfft_humanize(reout);
    gwy_data_field_filter_gaussian(reout, args->sigma);
    for (i = 0; i < pxres*pyres; i++)
        redata[i] = sqrt(redata[i]);

    fxres = pxres/2;
    fyres = pyres/2;
    gwy_data_field_resample(lpsdf, fxres, fyres, GWY_INTERPOLATION_NONE);
    ldata = gwy_data_field_get_data(lpsdf);

    xreal = dfield->xreal;
    yreal = dfield->yreal;
    f0 = 2.0/MIN(xreal, yreal);
    f_max = 0.5*MIN(pxres/xreal, pyres/yreal);
    if (f_max <= f0) {
        g_warning("Minimum frequency is not smaller than maximum frequency.");
    }
    b = log(f_max/f0)/fyres;

    /* Incorporate some prefactors to sinphi[] and cosphi[], knowing that
     * cosine is only ever used for x and sine for y frequencies. */
    cosphi = g_new(gdouble, (N+1)*fxres);
    sinphi = g_new(gdouble, (N+1)*fxres);
    for (j = 0; j < fxres; j++) {
        gdouble phi_from = 2.0*G_PI*j/fxres;
        gdouble phi_to = 2.0*G_PI*(j + 1.0)/fxres;

        for (pi = 0; pi <= N; pi++) {
            gdouble phi = ((pi + 0.5)*phi_from + (N - 0.5 - pi)*phi_to)/N;
            cosphi[j*(N+1) + pi] = cos(phi)*xreal;
            sinphi[j*(N+1) + pi] = sin(phi)*yreal;
        }
    }

    for (i = 0; i < fyres; i++) {
        gdouble f_from = f0*exp(b*i);
        gdouble f_to = f0*exp(b*(i + 1.0));

        for (j = 0; j < fxres; j++) {
            const gdouble *cosphi_j = cosphi + j*(N+1);
            const gdouble *sinphi_j = sinphi + j*(N+1);
            guint n = 0;
            gdouble s = 0.0;

            for (fi = 0; fi <= N; fi++) {
                gdouble f = ((fi + 0.5)*f_from + (N - 0.5 - fi)*f_to)/N;
                for (pi = 0; pi <= N; pi++) {
                    gdouble x = f*cosphi_j[pi] + pxres/2.0,
                            y = f*sinphi_j[pi] + pyres/2.0;

                    if (G_UNLIKELY(x < 0.5
                                   || y < 0.5
                                   || x > pxres - 1.5
                                   || y > pyres - 1.5))
                        continue;

                    p = gwy_data_field_get_dval(reout, x, y,
                                                GWY_INTERPOLATION_SCHAUM);
                    s += p;
                    n++;
                }
            }

            if (!n)
                n = 1;

            ldata[i*fxres + j] = 2.0*G_PI/fxres * s/n*(f_to - f_from);
        }
    }

    g_object_unref(imout);
    g_object_unref(reout);

    gwy_data_field_set_xreal(lpsdf, 2.0*G_PI);
    gwy_data_field_set_xoffset(lpsdf, 0.0);
    gwy_data_field_set_yreal(lpsdf, log(f_max/f0));
    gwy_data_field_set_yoffset(lpsdf, log(f0));
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_xy(lpsdf), "");
    gwy_si_unit_set_from_string(gwy_data_field_get_si_unit_z(lpsdf), "");
    gwy_data_field_normalize(lpsdf);
}
예제 #23
0
파일: immerse.c 프로젝트: cbuehler/gwyddion
static void
immerse_search(ImmerseControls *controls,
               gint search_type)
{
    GwyDataField *dfield, *dfieldsub, *ifield, *iarea;
    gdouble wr, hr, xpos, ypos, deltax, deltay;
    gint w, h, xfrom, xto, yfrom, yto, ixres, iyres, col, row;
    GwyContainer *data;
    GQuark quark;

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

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

    ixres = gwy_data_field_get_xres(ifield);
    iyres = gwy_data_field_get_yres(ifield);

    wr = gwy_data_field_get_xreal(dfield)/gwy_data_field_get_xmeasure(ifield);
    hr = gwy_data_field_get_yreal(dfield)/gwy_data_field_get_ymeasure(ifield);
    if (wr*hr < 6.0) {
        g_warning("Detail image is too small for correlation");
        return;
    }

    w = GWY_ROUND(MAX(wr, 1.0));
    h = GWY_ROUND(MAX(hr, 1.0));
    gwy_debug("w: %d, h: %d", w, h);
    g_assert(w <= ixres && h <= iyres);
    if (search_type == RESPONSE_REFINE) {
        xfrom = gwy_data_field_rtoj(ifield, controls->args->xpos);
        yfrom = gwy_data_field_rtoi(ifield, controls->args->ypos);
        /* Calculate the area we will search the detail in */
        deltax = improve_search_window(w, ixres);
        deltay = improve_search_window(h, iyres);
        gwy_debug("deltax: %g, deltay: %g", deltax, deltay);
        xto = MIN(xfrom + w + deltax, ixres);
        yto = MIN(yfrom + h + deltay, iyres);
        xfrom = MAX(xfrom - deltax, 0);
        yfrom = MAX(yfrom - deltay, 0);
    }
    else {
        xfrom = yfrom = 0;
        xto = ixres;
        yto = iyres;
    }
    gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto);

    /* Cut out only the interesting part from the image data field */
    if (xfrom == 0 && yfrom == 0 && xto == ixres && yto == iyres)
        iarea = g_object_ref(ifield);
    else
        iarea = gwy_data_field_area_extract(ifield,
                                            xfrom, yfrom,
                                            xto - xfrom, yto - yfrom);

    dfieldsub = gwy_data_field_new_resampled(dfield, w, h,
                                             GWY_INTERPOLATION_LINEAR);

    immerse_correlate(iarea, dfieldsub, &col, &row);
    gwy_debug("[c] col: %d, row: %d", col, row);
    col += xfrom;
    row += yfrom;
    xpos = gwy_data_field_jtor(dfieldsub, col + 0.5);
    ypos = gwy_data_field_itor(dfieldsub, row + 0.5);
    g_object_unref(iarea);
    g_object_unref(dfieldsub);
    gwy_debug("[C] col: %d, row: %d", col, row);

    /* Upsample and refine */
    xfrom = MAX(col - 1, 0);
    yfrom = MAX(row - 1, 0);
    xto = MIN(col + w + 1, ixres);
    yto = MIN(row + h + 1, iyres);
    gwy_debug("x: %d..%d, y: %d..%d", xfrom, xto, yfrom, yto);
    iarea = gwy_data_field_area_extract(ifield,
                                        xfrom, yfrom,
                                        xto - xfrom, yto - yfrom);
    wr = gwy_data_field_get_xreal(iarea)/gwy_data_field_get_xmeasure(dfield);
    hr = gwy_data_field_get_yreal(iarea)/gwy_data_field_get_ymeasure(dfield);
    gwy_data_field_resample(iarea, GWY_ROUND(wr), GWY_ROUND(hr),
                            GWY_INTERPOLATION_LINEAR);
    immerse_correlate(iarea, dfield, &col, &row);
    gwy_debug("[U] col: %d, row: %d", col, row);

    xpos = gwy_data_field_jtor(dfield, col + 0.5)
           + gwy_data_field_jtor(ifield, xfrom);
    ypos = gwy_data_field_itor(dfield, row + 0.5)
           + gwy_data_field_itor(ifield, yfrom);

    g_object_unref(iarea);
    immerse_clamp_detail_offset(controls, xpos, ypos);
}