34 #include <visp3/core/vpImageFilter.h>
35 #include <visp3/ustk_needle_detection/usNeedleTrackerSIR2D.h>
42 m_noise.setSigmaMean(1.0, 0.0);
44 m_sample = vpUniRand(42);
55 for (
unsigned int i = 0; i < m_nParticles; ++i) {
57 delete m_particles[i];
58 m_particles[i] = NULL;
76 m_nPointsCurrent = needle.
getOrder() + 1;
77 m_nParticles = nParticles;
80 for (
unsigned int i = 0; i < m_nParticles; ++i)
82 m_weights =
new double[m_nParticles];
83 for (
unsigned int i = 0; i < m_nParticles; ++i)
84 m_weights[i] = 1.0 / m_nParticles;
85 m_lengthThreshold = 50.0;
92 dims[0] = I.getHeight();
93 dims[1] = I.getWidth();
99 for (
double t = 0; t <= 1.0; t += 1.0 / length) {
101 unsigned int x = vpMath::round(point[0]);
102 unsigned int y = vpMath::round(point[1]);
103 if ((3 <= x) && (x < dims[0] - 3) && (3 <= y) && (y < dims[1] - 3)) {
104 m_fgMean += vpImageFilter::gaussianFilter(I, x, y);
109 m_bgMean = I.getSum() / I.getSize();
111 init(dims, nPoints, nParticles, needle);
118 if (i >= m_nParticles) {
119 std::cerr <<
"Error: in usNeedleTrackerSIR2D::getParticle(): "
120 <<
"Particle index is out of range." << std::endl;
123 return m_particles[i];
128 if (i >= m_nParticles) {
129 std::cerr <<
"Error: in usNeedleTrackerSIR2D::getWeight(): "
130 <<
"Particle index is out of range." << std::endl;
144 vpMatrix controlPoints;
145 vpMatrix meanControlPoints;
146 vpColVector direction;
147 vpMatrix S_noise_tip;
148 vpMatrix S_noise_inter;
149 vpColVector noise(2);
153 for (
unsigned int i = 0; i < m_nParticles; ++i) {
158 direction /= direction.frobeniusNorm();
161 for (
unsigned int j = 0; j < 2; ++j)
162 U[j][0] = direction[j];
163 U[0][1] = -direction[1];
164 U[1][1] = direction[0];
167 S_noise_tip = U * m_sigma * U.t();
168 S_noise_inter.eye(2);
169 S_noise_inter *= m_sigma[1][1];
179 for (
unsigned int j = 1; j < m_nPointsCurrent - 1; ++j) {
182 for (
unsigned int k = 0; k < 2; ++k)
183 noise[k] = m_noise();
184 noise = S_noise_inter * noise;
187 for (
unsigned int k = 0; k < 2; ++k)
188 controlPoints[k][j] += direction[k] / (m_nPointsCurrent - 1) + noise[k] / 4.0;
194 for (
unsigned int k = 0; k < 2; ++k)
195 noise[k] = m_noise();
196 noise = S_noise_tip * noise;
199 for (
unsigned int k = 0; k < 2; ++k)
200 controlPoints[k][m_nPointsCurrent - 1] += direction[k] + noise[k];
206 double sumWeights = 0.0;
207 for (
unsigned int i = 0; i < m_nParticles; ++i) {
209 sumWeights += m_weights[i];
213 double sumSquare = 0.0;
214 for (
unsigned int i = 0; i < m_nParticles; ++i) {
215 m_weights[i] /= sumWeights;
216 sumSquare += vpMath::sqr(m_weights[i]);
219 double n_eff = 1.0 / sumSquare;
223 if (n_eff < m_nParticles / 2.0) {
228 meanControlPoints.resize(2, m_nPointsCurrent);
229 meanControlPoints = 0.0;
230 for (
unsigned int i = 0; i < m_nParticles; ++i) {
236 if ((m_needleModel->
getLength()) > m_lengthThreshold && (m_nPoints != m_nPointsCurrent)) {
237 std::cout <<
"Changing polynomial order from " << m_nPointsCurrent - 1 <<
" to " << m_nPointsCurrent << std::endl;
240 delete m_needleModel;
241 m_needleModel = newModel;
242 for (
unsigned int i = 0; i < m_nParticles; ++i) {
245 delete m_particles[i];
246 m_particles[i] = newModel;
248 m_lengthThreshold *= 2.0;
260 for (
double t = 0; t <= 1.0; t += 1.0 / length) {
262 unsigned int x = vpMath::round(point[0]);
263 unsigned int y = vpMath::round(point[1]);
264 if ((3 <= x) && (x < m_dims[0] - 3) && (3 <= y) && (y < m_dims[1] - 3)) {
266 intensity = vpImageFilter::gaussianFilter(I, x, y);
277 unsigned int x = vpMath::round(point[0]);
278 unsigned int y = vpMath::round(point[1]);
279 if ((3 <= x) && (x < m_dims[0] - 3) && (3 <= y) && (y < m_dims[1] - 3)) {
280 intensity = vpImageFilter::gaussianFilter(I, x, y);
284 point = model.
getPoint(1.0 + 1.0 / length);
285 x = vpMath::round(point[0]);
286 y = vpMath::round(point[1]);
287 if ((3 <= x) && (x < m_dims[0] - 3) && (3 <= y) && (y < m_dims[1] - 3)) {
288 intensity = vpImageFilter::gaussianFilter(I, x, y);
298 int *idx =
new int[m_nParticles];
299 for (
unsigned int i = 0; i < m_nParticles; ++i) {
300 double x = m_sample();
301 double sumWeights = 0.0;
302 for (
unsigned int j = 0; j < m_nParticles; ++j) {
303 if (x < sumWeights + m_weights[j]) {
307 sumWeights += m_weights[j];
311 for (
unsigned int i = 0; i < m_nParticles; ++i) {
314 for (
unsigned int i = 0; i < m_nParticles; ++i) {
315 delete m_particles[i];
318 for (
unsigned int i = 0; i < m_nParticles; ++i) {
319 delete oldParticles[i];
320 oldParticles[i] = NULL;
322 delete[] oldParticles;
324 for (
unsigned int i = 0; i < m_nParticles; ++i) {
325 m_weights[i] = 1.0 / m_nParticles;
double getWeight(unsigned int i)
usPolynomialCurve2D * getNeedle()
double computeLikelihood(const usPolynomialCurve2D &model, const vpImage< unsigned char > &I)
void init(unsigned int dims[2], unsigned int nPoints, unsigned int nParticles, const usPolynomialCurve2D &needle)
usPolynomialCurve2D * getParticle(unsigned int i)
void run(vpImage< unsigned char > &I, double v)
usPolynomialCurve2D getNewOrderPolynomialCurve(unsigned int order) const
void setControlPoints(const vpMatrix &controlPoints)
double getLength(int nbCountSeg=50) const
vpMatrix getControlPoints() const
vpColVector getTangent(double parameter) const
vpColVector getPoint(double parameter) const
unsigned int getOrder() const