20 double s2s = sqrt(2)*p[2]*p[2];
21 double ex = (erf((x-p[0]+.5)/s2s)-erf((x-p[0]-.5)/s2s))*.5;
22 double ey = (erf((y-p[1]+.5)/s2s)-erf((y-p[1]-.5)/s2s))*.5;
23 return ex*ey*p[3]*p[3]+p[4]*p[4];
45 for (
int y = 0; y<l; y++)
for (
int x = 0; x<l; x++) {
47 tl += i[y*w+x]*log(psf)-psf;
68 std::vector<Particle> res;
70 double const wk1[] = {1./16,1./4,3./8,1./4,1./16};
71 double const wk2[] = {1./16,0,1./4,0,3./8,0,1./4,0,1./16};
75 std::vector<double> bf(sz);
80 std::vector<double> v1(sz);
81 for (
int i = 0; i<sz; i++) {
84 int r1 = x+2<w ? 5 : w+2-x;
85 for (
int j = x<2 ? 2-x : 0; j<r1; j++) s += data[i+j-2]*wk1[j];
90 for (
int i = 0; i<sz; i++) {
93 int r1 = y+2<h ? 5 : h+2-y;
94 for (
int j = y<2 ? 2-y : 0; j<r1; j++) s += bf[i+j*w-2*w]*wk1[j];
96 double f1 = data[i]-s;
102 double threshold = 1.5*sqrt(f1a2-f1a*f1a);
103 debug <<
"threshold = " << threshold <<
'\n';
106 std::vector<double> f2(sz);
107 for (
int i = 0; i<sz; i++) {
110 int r1 = x+4<w ? 9 : w+4-x;
111 for (
int j = x<4 ? 4-x : 0; j<r1; j++) s += v1[i+j-4]*wk2[j];
114 for (
int i = 0; i<sz; i++) {
117 int r1 = y+4<h ? 9 : h+4-y;
118 for (
int j = y<4 ? 4-y : 0; j<r1; j++) s += bf[i+j*w-4*w]*wk2[j];
122 for (
int i = 0; i<sz; i++) bf[i] = data[i]*
i2p;
125 std::vector<int> nd{1,w+1,w,w-1};
126 std::vector<bool> n8(sz,
true);
129 for (
int i = 0; i<ne; i++) {
131 if (f2[i]>f2[i+d]) n8[i+d] =
false;
136 if (n8[i] && x>=
fwr && x<w-fwr && y>=
fwr && y<h-
fwr && f2[i]>threshold) {
138 double const * sq = bf.data()+i-(w+1)*
fwr;
142 for (
int y = 0; y<l; y++)
for (
int x = 0; x<l; x++) {
143 double vv = sq[y*w+x];
145 else if (vv<mn) mn = vv;
147 param_t p = {double(
fwr),double(
fwr),sqrt(1.6),sqrt(mx-mn),sqrt(mn)};
150 res.push_back({x,y,nm.
minimize(std::ref(fn),p,stps)});
157 int main(
int argc,
char ** argv)
160 msg(0) <<
"Missing expected filename!\nUsage:\n";
161 msg(0) <<
'\t' << argv[0] <<
" <filename of TIFF>\n\n";
165 Tiff tf(std::make_shared<std::ifstream>(argv[1]));
176 uint16_t * v =
reinterpret_cast<uint16_t *
>(imd.data());
178 std::vector<double> im(v,v+sz);
183 if (r.p[2]<0.5||r.p[2]>
fwr/2)
continue;
184 if (abs(r.p[3])>1000)
continue;
185 std::cout << icnt+1 <<
",\t";
186 std::cout <<
plsz*(r.x+r.p[0]) <<
",\t";
187 std::cout <<
plsz*(r.y+r.p[1]) <<
",\t";
188 std::cout <<
plsz*(r.p[2]*r.p[2]) <<
",\t";
189 std::cout << r.p[3]*r.p[3] <<
",\t";
190 std::cout << r.p[4]*r.p[4] <<
'\n';
Template implementation of Nelder–Mead method for minimization.
double fn(double const *p)
Function to be minimized.
std::vector< char > read_image()
vec_t minimize(fun_t fn, vec_t const &x0, vec_t const &step)
<perform minimization
std::vector< Particle > process_image(double const *data, int w, int h)
Process a single 2D image.
Likelihood(int l, int w)
Construct the calculator.
Optimizer with Nelder–Mead method for functions with N arguments.
uint32_t image_width
width of image
std::ostream & msg(int l)
message output stream
std::array< double, 5 > param_t
Type for fitting parameters.
uint32_t image_length
length of image
int x
x coordinate of the maximum
int fwr
fitting window range
void set_image(double const *im)
Set the image for calculation.
double psf_ig2(double x, double y, param_t const &p)
Point-spread function with integrated Gaussian.
param_t p
fitted parameters of the point-spread function
double plsz
pixel size in nm
int main(int argc, char **argv)
Main function for localization.
Functor for likelihood calculation.
double operator()(param_t const &p)
Actual calculation make the functor.
double i2p
intensity to photon scale
std::ostream & debug
stream for debug messages
int y
y coordinate of the maximum
uint32_t parse_ifd(uint32_t i=0)
Parse image file directory (IFD)
Class for processing TIFF file.