Ejemplo n.º 1
0
/* create a smaller copy of data */
static GwyContainer*
create_preview_data(GwyContainer *data,
                    GwyDataField *dfield,
                    GwyDataField *mfield,
                    gint id)
{
    GwyContainer *pdata;
    GwyDataField *pfield;
    gint xres, yres;
    gdouble zoomval;

    pdata = gwy_container_new();
    xres = gwy_data_field_get_xres(dfield);
    yres = gwy_data_field_get_yres(dfield);
    zoomval = (gdouble)PREVIEW_SIZE/MAX(xres, yres);
    xres = MAX(xres*zoomval, 3);
    yres = MAX(yres*zoomval, 3);

    /* Base data */
    pfield = gwy_data_field_new_resampled(dfield, xres, yres,
                                          GWY_INTERPOLATION_ROUND);
    gwy_container_set_object_by_name(pdata, "/source", pfield);
    g_object_unref(pfield);

    /* Mask */
    if (mfield) {
        pfield = gwy_data_field_new_resampled(mfield, xres, yres,
                                              GWY_INTERPOLATION_ROUND);
        gwy_container_set_object_by_name(pdata, "/mask", pfield);
        g_object_unref(pfield);
    }

    /* Leveled */
    pfield = gwy_data_field_new_alike(pfield, FALSE);
    gwy_container_set_object_by_name(pdata, "/0/data", pfield);
    g_object_unref(pfield);

    /* Background */
    pfield = gwy_data_field_new_alike(pfield, FALSE);
    gwy_container_set_object_by_name(pdata, "/1/data", pfield);
    g_object_unref(pfield);

    gwy_app_sync_data_items(data, pdata, id, 0, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);
    gwy_app_sync_data_items(data, pdata, id, 1, FALSE,
                            GWY_DATA_ITEM_GRADIENT,
                            0);

    return pdata;
}
Ejemplo n.º 2
0
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_new_resampled(tip,
                                              tip->xres/surfxstep*tipxstep,
                                              tip->yres/surfystep*tipystep,
                                              GWY_INTERPOLATION_BILINEAR);
        *freetip = TRUE;
        return buffer;
    }
    else
        return tip;
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
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"));
}
Ejemplo n.º 5
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);
}
Ejemplo n.º 6
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);
}
Ejemplo n.º 7
0
static void
immerse_correlate(GwyDataField *image,
                  GwyDataField *kernel,
                  gint *col,
                  gint *row)
{
    GwyDataField *subimage, *subkernel, *score, *imagearea;
    gdouble factor;
    gint ixres, iyres, kxres, kyres;
    gint sixres, siyres, skxres, skyres;
    gint xfrom, yfrom, xto, yto;
    gint sx, sy, delta;

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

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

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

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

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

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

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

    *col = sx + xfrom - (kxres - 1)/2;
    *row = sy + yfrom - (kyres - 1)/2;
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
0
static void
square_samples(GwyContainer *data, GwyRunType run)
{
    GwyDataField *dfield, *dfields[3];
    gdouble xreal, yreal, qx, qy;
    gint oldid, newid, xres, yres;
    GQuark quark;

    g_return_if_fail(run & BASICOPS_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);
    dfield = dfields[0];
    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);
    qx = xres/xreal;
    qy = yres/yreal;
    if (fabs(log(qx/qy)) > 1.0/hypot(xres, yres)) {
        /* Resample */
        if (qx < qy)
            xres = MAX(GWY_ROUND(xreal*qy), 1);
        else
            yres = MAX(GWY_ROUND(yreal*qx), 1);

        dfields[0] = gwy_data_field_new_resampled(dfields[0], xres, yres,
                                                  GWY_INTERPOLATION_BSPLINE);
        if (dfields[1]) {
            dfields[1]
                = gwy_data_field_new_resampled(dfields[1], xres, yres,
                                               GWY_INTERPOLATION_ROUND);
        }
        if (dfields[2]) {
            dfields[2]
                = gwy_data_field_new_resampled(dfields[2], xres, yres,
                                               GWY_INTERPOLATION_BSPLINE);
        }
    }
    else {
        /* Ratios are equal, just duplicate */
        dfields[0] = gwy_data_field_duplicate(dfields[0]);
        if (dfields[1])
            dfields[1] = gwy_data_field_duplicate(dfields[1]);
        if (dfields[2])
            dfields[2] = gwy_data_field_duplicate(dfields[2]);
    }


    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_channel_log_add_proc(data, oldid, newid);
}