36 #ifndef FFT_COMMON_HXX_
37 #define FFT_COMMON_HXX_
40 #include <Core/ITKCommon/common.hxx>
41 #include <Core/ITKCommon/FFT/fft.hxx>
42 #include <Core/ITKCommon/the_dynamic_array.hxx>
70 #define DEBUG_PDF_PFX ""
83 const unsigned int area):
90 inline bool operator == (
const local_max_t & lm)
const
91 {
return (value_ == lm.value_) && (x_ == lm.x_) && (y_ == lm.y_); }
93 inline bool operator < (
const local_max_t & lm)
const
94 {
return value_ < lm.value_; }
96 inline bool operator > (
const local_max_t & lm)
const
97 {
return value_ > lm.value_; }
113 inline std::ostream &
114 operator << (std::ostream & sout,
const local_max_t & lm)
116 return sout << lm.value_ <<
'\t'
119 << lm.area_ << std::endl;
133 min_[0] = std::numeric_limits<int>::max();
134 min_[1] = std::numeric_limits<int>::max();
135 max_[0] = std::numeric_limits<int>::min();
136 max_[1] = std::numeric_limits<int>::min();
139 void update(
int x,
int y)
141 min_[0] = std::min(min_[0], x);
142 min_[1] = std::min(min_[1], y);
143 max_[0] = std::max(max_[0], x);
144 max_[1] = std::max(max_[1], y);
166 find_maxima_cm(std::list<local_max_t> & max_list,
167 const itk_image_t::Pointer & image,
168 const double percentage = 0.9995,
169 const bfs::path & prefix = DEBUG_PDF_PFX,
170 const bfs::path & suffix=
".png");
176 template <
class TImage>
178 find_correlation(std::list<local_max_t> & max_list,
184 itk_image_t::Pointer z0 = cast<TImage, itk_image_t>(fi);
185 itk_image_t::Pointer z1 = cast<TImage, itk_image_t>(mi);
186 return find_correlation<itk_image_t>(max_list,
199 find_correlation(std::list<local_max_t> & max_list,
200 const itk_image_t * fi,
201 const itk_image_t * mi,
214 template <
class TImage>
216 find_correlation(
const TImage * fi,
218 std::list<local_max_t> & max_list,
221 double lp_filter_r = resampled_data ? 0.9 : 0.5;
222 return find_correlation<TImage>(max_list, fi, mi, lp_filter_r, 0.1);
233 threshold_maxima(std::list<local_max_t> & max_list,
234 const double threshold);
245 reject_negligible_maxima(std::list<local_max_t> & max_list,
246 const double min_peak = 0.1,
247 const double threshold = 0.3);
260 overlap_t(
const unsigned int id,
const double overlap):
265 inline bool operator == (
const overlap_t & d)
const
266 {
return id_ == d.id_; }
268 inline bool operator < (
const overlap_t & d)
const
269 {
return overlap_ < d.overlap_; }
271 inline bool operator > (
const overlap_t & d)
const
272 {
return overlap_ > d.overlap_; }
282 reject_negligible_overlap(std::list<overlap_t> & ol,
283 const double threshold);
289 template <
class TImage>
291 estimate_displacement(
const TImage * a,
294 translate_transform_t::Pointer & transform,
295 image_t::PointType offset_min,
296 image_t::PointType offset_max,
297 const double overlap_min = 0.0,
298 const double overlap_max = 1.0,
299 const mask_t * mask_a = NULL,
300 const mask_t * mask_b = NULL)
309 itk_image_t::SizeType max_sz = calc_padding<TImage>(a, b);
310 const unsigned int & w = max_sz[0];
311 const unsigned int & h = max_sz[1];
315 typedef itk::MeanSquaresImageToImageMetric<TImage, TImage> metric_t;
316 typedef itk::LinearInterpolateImageFunction<TImage, double> interpolator_t;
318 typedef typename TImage::SpacingType spacing_t;
319 spacing_t spacing = a->GetSpacing();
320 double sx = spacing[0];
321 double sy = spacing[1];
324 const double x = lm.x_;
325 const double y = lm.y_;
327 const vec2d_t t[] = {
328 vec2d(sx * x, sy * y),
329 vec2d(sx * (x - w), sy * y),
330 vec2d(sx * x, sy * (y - h)),
331 vec2d(sx * (x - w), sy * (y - h))
334 std::ostringstream oss;
335 double best_metric = std::numeric_limits<double>::max();
336 for (
unsigned int i = 0; i < 4; i++)
338 if ( t[i][0] < offset_min[0] || t[i][0] > offset_max[0] ||
339 t[i][1] < offset_min[1] || t[i][1] > offset_max[1] )
344 translate_transform_t::Pointer ti = translate_transform_t::New();
353 const double area_ratio = overlap_ratio<TImage>(a, b, ti);
355 int old_precision = oss.precision();
357 oss << i <<
": " << std::setw(3) << std::fixed << area_ratio * 100.0 <<
"% of overlap, ";
358 oss.precision(old_precision);
360 if (area_ratio < overlap_min || area_ratio > overlap_max)
362 oss <<
"skipping..." << std::endl;
367 double metric = my_metric<TImage>(a,
374 oss << std::scientific << metric;
375 if (metric < best_metric)
378 best_metric = metric;
379 oss <<
" - better..." << std::endl;
388 oss <<
" - worse..." << std::endl;
392 CORE_LOG_MESSAGE(oss.str());
403 template <
typename TImage,
typename TMask>
405 match_one_pair(
const bool images_were_resampled,
406 const bool use_std_mask,
409 const TMask * fi_mask,
410 const TMask * mi_mask,
412 const double overlap_min,
413 const double overlap_max,
415 image_t::PointType offset_min,
416 image_t::PointType offset_max,
418 translate_transform_t::Pointer & ti,
419 std::list<local_max_t> & peaks,
420 unsigned int & num_peaks,
426 double min_peak = 0.1,
427 double peak_threshold = 0.3,
428 size_t position = 99)
436 unsigned int total_peaks = 0;
441 typename TImage::SizeType fi_sz = fi->GetLargestPossibleRegion().GetSize();
442 typename TImage::SizeType mi_sz = mi->GetLargestPossibleRegion().GetSize();
444 unsigned int fi_y = (
unsigned int)(0.95 * fi_sz[1]);
445 unsigned int mi_y = (
unsigned int)(0.95 * mi_sz[1]);
447 typename TImage::Pointer fi_filled = cast<TImage, TImage>(fi);
448 fill<TImage>(fi_filled, 0, fi_y, fi_sz[0], fi_sz[1] - fi_y, 0);
450 typename TImage::Pointer mi_filled = cast<TImage, TImage>(mi);
451 fill<TImage>(mi_filled, 0, mi_y, mi_sz[0], mi_sz[1] - mi_y, 0);
453 total_peaks = find_correlation<TImage>(fi_filled,
456 images_were_resampled);
460 total_peaks = find_correlation<TImage>(fi,
463 images_were_resampled);
466 num_peaks = reject_negligible_maxima(peaks, min_peak, peak_threshold);
467 double max_v = (*peaks.begin()).value_;
471 if (max_v < min_peak || total_peaks == 0 ||
472 (position >= 99 && num_peaks > 16)) {
473 return std::numeric_limits<double>::max();
475 std::ostringstream oss;
476 oss << num_peaks <<
'/' << total_peaks <<
" eligible peaks, ";
478 double best_metric = std::numeric_limits<double>::max();
479 typename TImage::IndexValueType numCols =
480 (
typename TImage::IndexValueType)
481 (fi->GetLargestPossibleRegion().GetSize()[1]);
482 typename TImage::IndexValueType numRows =
483 (
typename TImage::IndexValueType)
484 (fi->GetLargestPossibleRegion().GetSize()[0]);
485 double rowLen =
static_cast<double>(numRows) * shrink;
486 double colLen =
static_cast<double>(numCols) * shrink;
487 for (std::list<local_max_t>::iterator j = peaks.begin();
488 j != peaks.end(); ++j)
490 oss <<
"evaluating permutations..." << std::endl;
493 translate_transform_t::Pointer tmp = translate_transform_t::New();
494 double metric = estimate_displacement<TImage>(fi,
504 double x = tmp.GetPointer()->GetOffset()[0];
505 double y = tmp.GetPointer()->GetOffset()[1];
509 if (x < rowLen * ( - overlap_min) || x > rowLen * ( overlap_min) ||
510 y < colLen * (1. - overlap_max) || y > colLen * (1. - overlap_min) )
513 if (x < rowLen * (1. - overlap_max) || x > rowLen * (1. - overlap_min) ||
514 y < colLen * ( - overlap_min) || y > colLen * ( overlap_min) )
517 if (x < rowLen * (overlap_min - 1.) || x > rowLen * (overlap_max - 1.) ||
518 y < colLen * ( - overlap_min) || y > colLen * ( overlap_min) )
521 if (x < rowLen * ( - overlap_min) || x > rowLen * (overlap_min ) ||
522 y < colLen * (overlap_min - 1.) || y > colLen * (overlap_max - 1.) )
528 if (metric < best_metric)
530 best_metric = metric;
538 CORE_LOG_MESSAGE(oss.str());
549 template <
typename TImage,
typename TMask>
551 match_one_pair(
const bool images_were_resampled,
552 const bool use_std_mask,
555 const TMask * fi_mask,
556 const TMask * mi_mask,
558 const double overlap_min,
559 const double overlap_max,
561 image_t::PointType offset_min,
562 image_t::PointType offset_max,
564 const unsigned int node_id,
565 translate_transform_t::Pointer & ti,
566 std::pair<
unsigned int, std::list<local_max_t> > & peaks,
572 double min_peak = 0.1,
573 double peak_threshold = 0.3,
574 size_t position = 99)
576 unsigned int peak_list_size = 0;
577 std::list<local_max_t> peak_list;
578 return match_one_pair<TImage, TMask>(images_were_resampled,
600 template <
typename TImage,
typename TMask>
602 match_one_pair(
const bool images_were_resampled,
603 const bool use_std_mask,
606 const TMask * fi_mask,
607 const TMask * mi_mask,
608 const double overlap_min,
609 const double overlap_max,
610 image_t::PointType offset_min,
611 image_t::PointType offset_max,
612 translate_transform_t::Pointer & ti)
614 std::list<local_max_t> peaks;
615 unsigned int num_peaks = 0;
616 return match_one_pair<TImage, TMask>(images_were_resampled,
632 #endif // FFT_COMMON_HXX_
Definition: fft_common.hxx:252
Definition: fft_common.hxx:125
Definition: fft_common.hxx:77