static void line_correct_median_difference(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; gdouble *diffs, *row, *prev; gint xres, yres, i, j; gdouble median; GQuark dquark; g_return_if_fail(run & GWY_RUN_IMMEDIATE); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); xres = gwy_data_field_get_xres(dfield); yres = gwy_data_field_get_yres(dfield); row = gwy_data_field_get_data(dfield); diffs = g_new(gdouble, xres); for (i = 1; i < yres; i++) { prev = row; row += xres; for (j = 0; j < xres; j++) diffs[j] = prev[j] - row[j]; median = gwy_math_median(xres, diffs); for (j = 0; j < xres; j++) row[j] += median; } g_free(diffs); gwy_data_field_data_changed(dfield); }
static GwyDataField* median_background(gint size, GwyDataField *dfield) { GwyDataField *rfield; gint *circle; gdouble *data, *rdata, *buffer; gint i, j, xres, yres, buflen; data = gwy_data_field_get_data(dfield); rfield = gwy_data_field_duplicate(dfield); xres = gwy_data_field_get_xres(rfield); yres = gwy_data_field_get_yres(rfield); rdata = gwy_data_field_get_data(rfield); buflen = 0; circle = median_make_circle(size); for (i = 0; i < 2*size + 1; i++) buflen += 2*circle[i] + 1; buffer = g_new(gdouble, buflen); for (i = 0; i < yres; i++) { for (j = 0; j < xres; j++) { gint n, k, from, to; n = 0; for (k = MAX(0, i - size); k <= MIN(yres - 1, i + size); k++) { gdouble *row = data + k*xres; from = MAX(0, j - circle[k - i + size]); to = MIN(xres - 1, j + circle[k - i + size]); memcpy(buffer + n, row + from, (to - from + 1)*sizeof(gdouble)); n += to - from + 1; } rdata[i*xres + j] = gwy_math_median(n, buffer); } if (i % 10 == 0 && !gwy_app_wait_set_fraction((gdouble)i/yres)) { g_free(circle); g_object_unref(rfield); return NULL; } } g_free(circle); return rfield; }
/* Note this is not a correlation score since we care also about absolute * differences and try to suppress the influence of outliers. */ static gdouble get_row_difference(GwyDataField *dfield1, gint col1, gint row1, GwyDataField *dfield2, gint col2, gint row2, gint width, gint height) { gint xres1, yres1, xres2, yres2, i, j; const gdouble *data1, *data2; gdouble *row; gdouble s = 0.0; g_return_val_if_fail(width > 0, G_MAXDOUBLE); g_return_val_if_fail(height > 0, G_MAXDOUBLE); xres1 = gwy_data_field_get_xres(dfield1); yres1 = gwy_data_field_get_yres(dfield1); xres2 = gwy_data_field_get_xres(dfield2); yres2 = gwy_data_field_get_yres(dfield2); data1 = gwy_data_field_get_data_const(dfield1); data2 = gwy_data_field_get_data_const(dfield2); g_return_val_if_fail(col1 + width <= xres1, G_MAXDOUBLE); g_return_val_if_fail(col2 + width <= xres2, G_MAXDOUBLE); g_return_val_if_fail(row1 + height <= yres1, G_MAXDOUBLE); g_return_val_if_fail(row2 + height <= yres2, G_MAXDOUBLE); row = g_new(gdouble, width); for (i = 0; i < height; i++) { const gdouble *d1 = data1 + (row1 + i)*xres1 + col1; const gdouble *d2 = data2 + (row2 + i)*xres2 + col2; gdouble d; for (j = 0; j < width; j++) { d = d1[j] - d2[j]; row[j] = d; } d = gwy_math_median(width, row); s += d*d; } g_free(row); return sqrt(s/height); }
static gdouble get_column_difference(GwyDataField *dfield1, gint col1, gint row1, GwyDataField *dfield2, gint col2, gint row2, gint width, gint height) { gint xres1, yres1, xres2, yres2, i, j; const gdouble *data1, *data2; gdouble *column; gdouble s = 0.0; g_return_val_if_fail(width > 0, G_MAXDOUBLE); g_return_val_if_fail(height > 0, G_MAXDOUBLE); xres1 = gwy_data_field_get_xres(dfield1); yres1 = gwy_data_field_get_yres(dfield1); xres2 = gwy_data_field_get_xres(dfield2); yres2 = gwy_data_field_get_yres(dfield2); data1 = gwy_data_field_get_data_const(dfield1); data2 = gwy_data_field_get_data_const(dfield2); g_return_val_if_fail(col1 + width <= xres1, G_MAXDOUBLE); g_return_val_if_fail(col2 + width <= xres2, G_MAXDOUBLE); g_return_val_if_fail(row1 + height <= yres1, G_MAXDOUBLE); g_return_val_if_fail(row2 + height <= yres2, G_MAXDOUBLE); column = g_new(gdouble, height); for (j = 0; j < width; j++) { const gdouble *d1 = data1 + row1*xres1 + col1 + j; const gdouble *d2 = data2 + row2*xres2 + col2 + j; gdouble d; for (i = 0; i < height; i++) { d = d1[i*xres1] - d2[i*xres2]; column[i] = d; } d = gwy_math_median(height, column); s += d*d; } g_free(column); return sqrt(s/height); }
static void modify_channel_for_preview(GwyContainer *data, gint id, gboolean plane_level, gboolean row_level) { GwyDataField *field; gdouble a, bx, by; if (!plane_level && !row_level) return; if (!gwy_container_gis_object(data, gwy_app_get_data_key_for_id(id), &field) || !GWY_IS_DATA_FIELD(field)) return; if (plane_level) { gwy_data_field_fit_plane(field, &a, &bx, &by); gwy_data_field_plane_level(field, a, bx, by); } if (row_level) { guint xres = gwy_data_field_get_xres(field); guint yres = gwy_data_field_get_yres(field); gdouble *row = gwy_data_field_get_data(field); gdouble *diffs = g_new(gdouble, xres); guint i, j; for (i = 1; i < yres; i++) { gdouble *prev = row; gdouble median; row += xres; for (j = 0; j < xres; j++) diffs[j] = prev[j] - row[j]; median = gwy_math_median(xres, diffs); for (j = 0; j < xres; j++) row[j] += median; } g_free(diffs); } }
static void line_correct_median(GwyContainer *data, GwyRunType run) { GwyDataField *dfield; GwyDataLine *line, *modi; gint xres, yres, i; GQuark dquark; gdouble median; g_return_if_fail(run & LINECORR_RUN_MODES); gwy_app_data_browser_get_current(GWY_APP_DATA_FIELD, &dfield, GWY_APP_DATA_FIELD_KEY, &dquark, 0); g_return_if_fail(dfield && dquark); gwy_app_undo_qcheckpointv(data, 1, &dquark); xres = gwy_data_field_get_xres(dfield); line = gwy_data_line_new(xres, 1.0, FALSE); yres = gwy_data_field_get_yres(dfield); modi = gwy_data_line_new(yres, 1.0, FALSE); for (i = 0; i < yres; i++) { gwy_data_field_get_row(dfield, line, i); median = gwy_math_median(xres, gwy_data_line_get_data(line)); gwy_data_line_set_val(modi, i, median); } median = gwy_data_line_get_median(modi); for (i = 0; i < yres; i++) { gwy_data_field_area_add(dfield, 0, i, xres, 1, median - gwy_data_line_get_val(modi, i)); } g_object_unref(modi); g_object_unref(line); gwy_data_field_data_changed(dfield); }