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); }
/** * gwy_data_field_get_correlation_score: * @data_field: A data field. * @kernel_field: Kernel to correlate data field with. * @col: Upper-left column position in the data field. * @row: Upper-left row position in the data field. * @kernel_col: Upper-left column position in kernel field. * @kernel_row: Upper-left row position in kernel field. * @kernel_width: Width of kernel field area. * @kernel_height: Heigh of kernel field area. * * Calculates a correlation score in one point. * * Correlation window size is given * by @kernel_col, @kernel_row, @kernel_width, @kernel_height, * postion of the correlation window on data is given by * @col, @row. * * If anything fails (data too close to boundary, etc.), * function returns -1.0 (none correlation).. * * Returns: Correlation score (between -1.0 and 1.0). Value 1.0 denotes * maximum correlation, -1.0 none correlation. **/ gdouble gwy_data_field_get_correlation_score(GwyDataField *data_field, GwyDataField *kernel_field, gint col, gint row, gint kernel_col, gint kernel_row, gint kernel_width, gint kernel_height) { gint xres, yres, kxres, kyres, i, j; gdouble rms1, rms2, avg1, avg2, sumpoints, score; gdouble *data, *kdata; g_return_val_if_fail(GWY_IS_DATA_FIELD(data_field), -1.0); g_return_val_if_fail(GWY_IS_DATA_FIELD(kernel_field), -1.0); xres = data_field->xres; yres = data_field->yres; kxres = kernel_field->xres; kyres = kernel_field->yres; kernel_width = kernel_width; kernel_height = kernel_height; /* correlation request outside kernel */ if (kernel_col > kxres || kernel_row > kyres) return -1; /* correlation request outside data field */ if (col < 0 || row < 0 || col + kernel_width > xres || row + kernel_height > yres) return -1; if (kernel_col < 0 || kernel_row < 0 || kernel_col + kernel_width > kxres || kernel_row + kernel_height > kyres) return -1; avg1 = gwy_data_field_area_get_avg(data_field, NULL, col, row, kernel_width, kernel_height); avg2 = gwy_data_field_area_get_avg(kernel_field, NULL, kernel_col, kernel_row, kernel_width, kernel_height); rms1 = gwy_data_field_area_get_rms(data_field, NULL, col, row, kernel_width, kernel_height); if (rms1 == 0.0) return 0.0; rms2 = gwy_data_field_area_get_rms(kernel_field, NULL, kernel_col, kernel_row, kernel_width, kernel_height); if (rms2 == 0.0) return 0.0; score = 0; sumpoints = kernel_width * kernel_height; data = data_field->data; kdata = kernel_field->data; for (j = 0; j < kernel_height; j++) { /* row */ for (i = 0; i < kernel_width; i++) { /* col */ score += (data[(i + col) + xres*(j + row)] - avg1) * (kdata[(i + kernel_col) + kxres*(j + kernel_row)] - avg2); } } score /= rms1 * rms2 * sumpoints; return score; }