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; }
static void maskcor_do(MaskcorArgs *args) { enum { WORK_PER_UPDATE = 50000000 }; GwyDataField *dfield, *kernel, *retfield, *score; GwyContainer *data, *kerneldata; GwyComputationState *state; GQuark quark; gint newid, work, wpi; kerneldata = gwy_app_data_browser_get(args->kernel.datano); quark = gwy_app_get_data_key_for_id(args->kernel.id); kernel = GWY_DATA_FIELD(gwy_container_get_object(kerneldata, quark)); data = gwy_app_data_browser_get(args->data.datano); quark = gwy_app_get_data_key_for_id(args->data.id); dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark)); retfield = gwy_data_field_new_alike(dfield, FALSE); /* FIXME */ if (args->method == GWY_CORRELATION_NORMAL) { gwy_app_wait_start(gwy_app_find_window_for_channel(data, args->data.id), _("Initializing...")); state = gwy_data_field_correlate_init(dfield, kernel, retfield); gwy_app_wait_set_message(_("Correlating...")); work = 0; wpi = gwy_data_field_get_xres(kernel)*gwy_data_field_get_yres(kernel); wpi = MIN(wpi, WORK_PER_UPDATE); do { gwy_data_field_correlate_iteration(state); work += wpi; if (work > WORK_PER_UPDATE) { work -= WORK_PER_UPDATE; if (!gwy_app_wait_set_fraction(state->fraction)) { gwy_data_field_correlate_finalize(state); gwy_app_wait_finish(); g_object_unref(retfield); return; } } } while (state->state != GWY_COMPUTATION_STATE_FINISHED); gwy_data_field_correlate_finalize(state); gwy_app_wait_finish(); } else gwy_data_field_correlate(dfield, kernel, retfield, args->method); /* score - do new data with score */ if (args->result == GWY_MASKCOR_SCORE) { score = gwy_data_field_duplicate(retfield); newid = gwy_app_data_browser_add_data_field(score, data, TRUE); gwy_app_sync_data_items(data, data, args->data.id, newid, FALSE, GWY_DATA_ITEM_GRADIENT, 0); gwy_app_set_data_field_title(data, newid, _("Correlation score")); g_object_unref(score); gwy_app_channel_log_add_proc(data, args->data.id, newid); } else { /* add mask */ quark = gwy_app_get_mask_key_for_id(args->data.id); gwy_app_undo_qcheckpointv(data, 1, &quark); if (args->result == GWY_MASKCOR_OBJECTS) plot_correlated(retfield, gwy_data_field_get_xres(kernel), gwy_data_field_get_yres(kernel), args->threshold); else if (args->result == GWY_MASKCOR_MAXIMA) gwy_data_field_threshold(retfield, args->threshold, 0.0, 1.0); gwy_container_set_object(data, quark, retfield); gwy_app_channel_log_add_proc(data, args->data.id, args->data.id); } g_object_unref(retfield); }