/* * filters.c * * Image filtering * * Copyright © 2012-2021 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: * 2010-2020 Thomas White * 2013 Anton Barty * * This file is part of CrystFEL. * * CrystFEL is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CrystFEL is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CrystFEL. If not, see . * */ #include #include #include #include #include #include #include #include #include "image.h" /** \file filters.h */ static void filter_noise_in_panel(float *data, int width, int height) { int x, y; for ( y=0; ydetgeom->n_panels; i++ ) { struct detgeom_panel *p = &image->detgeom->panels[i]; filter_noise_in_panel(image->dp[i], p->w, p->h); } } /* Force the linker to bring in CBLAS to make GSL happy */ void filters_fudge_gslcblas() { STATUS("%p\n", cblas_sgemm); } #define SWAP(a,b) { float t=(a);(a)=(b);(b)=t; } static float kth_smallest(float *a, int n, int k) { long i, j, l, m; float x; l = 0; m = n-1; while ( l < m ) { x=a[k]; i=l; j=m; do { while (a[i]detgeom->n_panels; pn++ ) { int fs, ss; int i; struct detgeom_panel *p; float *localBg; p = &image->detgeom->panels[pn]; localBg = calloc(p->w*p->h, sizeof(float)); if ( localBg == NULL ) { ERROR("Failed to allocate LB buffer.\n"); return; } for ( ss=0; ssh; ss++ ) { for ( fs=0; fsw; fs++ ) { int ifs, iss; counter = 0; // Loop over median window for ( iss=-size; iss<=size; iss++ ) { for ( ifs=-size; ifs<=size; ifs++ ) { int idx; if ( (fs+ifs) < 0 ) continue; if ( (fs+ifs) >= p->w ) continue; if ( (ss+iss) < 0 ) continue; if ( (ss+iss) >= p->h ) continue; idx = fs+ifs + (ss+iss)*p->w; buffer[counter++] = image->dp[pn][idx]; } } // Find median value localBg[fs+p->w*ss] = kth_smallest(buffer, counter, counter/2); } } /* Do the background subtraction */ for ( i=0; iw*p->h; i++ ) { image->dp[pn][i] -= localBg[i]; } free(localBg); } free(buffer); }