39 #ifndef __usVolumeProcessing_h_
40 #define __usVolumeProcessing_h_
42 #include <visp3/core/vpConfig.h>
43 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
44 #include <type_traits>
47 #include <visp3/core/vpColVector.h>
48 #include <visp3/core/vpMath.h>
49 #include <visp3/core/vpMatrix.h>
51 #include <visp3/ustk_core/usImage3D.h>
61 template <
class Type1,
class Type2>
64 template <
class Type1,
class Type2>
68 template <
class Type1,
class Type2>
71 template <
class Type>
static void computeBarycenter(
const usImage3D<Type> &V,
double &ic,
double &jc,
double &kc);
75 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
76 template <class Type1, class Type2 = typename std::conditional<std::is_arithmetic<Type1>::value, double, Type1>::type>
77 static Type2 derivativeI(
const usImage3D<Type1> &V,
unsigned int i,
unsigned int j,
unsigned int k);
80 static double derivativeI(
const usImage3D<Type> &V,
unsigned int i,
unsigned int j,
unsigned int k);
85 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
86 template <class Type1, class Type2 = typename std::conditional<std::is_arithmetic<Type1>::value, double, Type1>::type>
87 static Type2 derivativeJ(
const usImage3D<Type1> &V,
unsigned int i,
unsigned int j,
unsigned int k);
90 static double derivativeJ(
const usImage3D<Type> &V,
unsigned int i,
unsigned int j,
unsigned int k);
95 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
96 template <class Type1, class Type2 = typename std::conditional<std::is_arithmetic<Type1>::value, double, Type1>::type>
97 static Type2 derivativeK(
const usImage3D<Type1> &V,
unsigned int i,
unsigned int j,
unsigned int k);
100 static double derivativeK(
const usImage3D<Type> &V,
unsigned int i,
unsigned int j,
unsigned int k);
103 template <
class Type1,
class Type2>
106 template <
class Type>
109 template <
class Type1,
class Type2>
111 unsigned int filter_size);
113 template <
class Type1,
class Type2>
115 unsigned int filter_size);
117 template <
class Type1,
class Type2>
119 unsigned int filter_size);
121 static usImage3D<double> generateGaussianDerivativeFilterI(
double sigma,
int size);
123 static usImage3D<double> generateGaussianDerivativeFilterII(
double sigma,
int size);
125 static usImage3D<double> generateGaussianDerivativeFilterIJ(
double sigma,
int size);
127 static usImage3D<double> generateGaussianDerivativeFilterIK(
double sigma,
int size);
129 static usImage3D<double> generateGaussianDerivativeFilterJ(
double sigma,
int size);
131 static usImage3D<double> generateGaussianDerivativeFilterJJ(
double sigma,
int size);
133 static usImage3D<double> generateGaussianDerivativeFilterJK(
double sigma,
int size);
135 static usImage3D<double> generateGaussianDerivativeFilterK(
double sigma,
int size);
137 static usImage3D<double> generateGaussianDerivativeFilterKK(
double sigma,
int size);
163 for (
unsigned int i = 1; i < V.
getSize(); i++) {
181 for (
unsigned int i = 1; i < V.
getSize(); i++) {
199 template <
class Type1,
class Type2>
201 unsigned int j,
unsigned int k)
204 unsigned int s_j = filter.
getWidth();
206 unsigned int m_i = s_i / 2;
207 unsigned int m_j = s_j / 2;
208 unsigned int m_k = s_k / 2;
211 if ((m_i < i) && (i < src.
getHeight() - m_i) && (m_j < j) && (j < src.
getWidth() - m_j) && (m_k < k) &&
213 for (
unsigned int k_it = 0; k_it < s_k; k_it++)
214 for (
unsigned int j_it = 0; j_it < s_j; j_it++)
215 for (
unsigned int i_it = 0; i_it < s_i; i_it++)
216 v += filter(i_it, j_it, k_it) * src(i + i_it - m_i, j + j_it - m_j, k + k_it - m_k);
228 template <
class Type1,
class Type2>
233 unsigned int s_j = filter.
getWidth();
237 unsigned int width = src.
getWidth();
239 dst.
resize(height, width, nbFrames);
241 for (
unsigned int k = s_k; k < nbFrames - s_k; k++)
242 for (
unsigned int j = s_j; j < width - s_j; j++)
243 for (
unsigned int i = s_i; i < height - s_i; i++)
247 #ifdef VISP_HAVE_CPP11_COMPATIBILITY
256 template <
class Type1,
class Type2>
259 return ((Type2)V(i + 1, j, k) - (Type2)V(i - 1, j, k)) / 2.0;
270 template <
class Type1,
class Type2>
273 return ((Type2)V(i, j + 1, k) - (Type2)V(i, j - 1, k)) / 2.0;
284 template <
class Type1,
class Type2>
287 return ((Type2)V(i, j, k + 1) - (Type2)V(i, j, k - 1)) / 2.0;
298 template <
class Type>
301 return ((
double)V(i + 1, j, k) - (
double)V(i - 1, j, k)) / 2.0;
312 template <
class Type>
315 return ((
double)V(i, j + 1, k) - (
double)V(i, j - 1, k)) / 2.0;
326 template <
class Type>
329 return ((
double)V(i, j, k + 1) - (
double)V(i, j, k - 1)) / 2.0;
341 template <
class Type1,
class Type2>
343 unsigned int filter_size)
357 template <
class Type1,
class Type2>
359 unsigned int filter_size)
373 template <
class Type1,
class Type2>
375 unsigned int filter_size)
386 template <
class Type1,
class Type2>
390 unsigned int width = src.
getWidth();
392 dst.
resize(height, width, nbFrames);
395 for (
unsigned int k = 0; k < nbFrames; k++)
396 for (
unsigned int j = 0; j < width; j++) {
398 for (
unsigned int i = 1; i < height - 1; i++)
400 dst(height - 1, j, k, zero);
409 template <
class Type1,
class Type2>
413 unsigned int width = src.
getWidth();
415 dst.
resize(height, width, nbFrames);
418 for (
unsigned int k = 0; k < nbFrames; k++) {
419 for (
unsigned int j = 1; j < width - 1; j++)
420 for (
unsigned int i = 0; i < height; i++)
423 for (
unsigned int i = 0; i < height; i++) {
424 dst(i, width - 1, k, zero);
435 template <
class Type1,
class Type2>
439 unsigned int width = src.
getWidth();
441 dst.
resize(height, width, nbFrames);
444 for (
unsigned int k = 1; k < nbFrames - 1; k++)
445 for (
unsigned int j = 0; j < width; j++)
446 for (
unsigned int i = 0; i < height; i++)
449 for (
unsigned int j = 0; j < width; j++)
450 for (
unsigned int i = 0; i < height; i++) {
452 dst(i, j, nbFrames - 1, zero);
464 unsigned int width = src.
getWidth();
470 dst.
resize(height, width, nbFrames);
471 for (
unsigned int i = 0; i < src.
getSize(); i++) {
488 unsigned int width = src.
getWidth();
500 dst.
resize(height, width, nbFrames);
501 for (
unsigned int i = 0; i < src.
getSize(); i++) {
529 template <
class Type>
533 unsigned int width = src.
getWidth();
537 dst.
resize(height, width, nbFrames);
538 for (
unsigned int i = 0; i < src.
getSize(); i++) {
539 vpColVector evalues = H.
getConstData()[i].eigenValues();
542 if (vpMath::abs(evalues[0]) > vpMath::abs(evalues[1]))
543 std::swap(evalues[0], evalues[1]);
544 if (vpMath::abs(evalues[1]) > vpMath::abs(evalues[2]))
545 std::swap(evalues[1], evalues[2]);
546 if (vpMath::abs(evalues[0]) > vpMath::abs(evalues[1]))
547 std::swap(evalues[0], evalues[1]);
550 if ((evalues[1] >= 0.0) || (evalues[2] >= 0.0))
553 double Rb = vpMath::abs(evalues[0]) / sqrt(vpMath::abs(evalues[1] * evalues[2]));
554 double Ra = vpMath::abs(evalues[1] / evalues[2]);
555 double S = evalues.frobeniusNorm();
557 v = (1.0 - exp(-vpMath::sqr(Ra) / (2.0 * vpMath::sqr(a)))) * exp(-vpMath::sqr(Rb) / (2.0 * vpMath::sqr(b))) *
558 (1.0 - exp(-vpMath::sqr(S) / (2.0 * vpMath::sqr(c))));
570 template <
class Type1,
class Type2>
574 unsigned int width = src1.
getWidth();
577 throw vpException(vpException::dimensionError,
"usVolumeProcessing::difference: mismatched volumes dimensions");
578 unsigned int n = src1.
getSize();
579 dst.
resize(height, width, nbFrames);
580 for (
unsigned int i = 0; i < n; i++)
590 template <
class Type1,
class Type2>
595 unsigned int width = src1.
getWidth();
598 throw vpException(vpException::dimensionError,
599 "usVolumeProcessing::absoluteDifference: mismatched volumes dimensions");
600 unsigned int n = src1.
getSize();
601 dst.
resize(height, width, nbFrames);
602 for (
unsigned int i = 0; i < n; i++)
613 template <
class Type>
619 Type V_sum = 0 * V(0, 0, 0);
623 for (
unsigned int k = 0; k < nbFrames; k++)
624 for (
unsigned int j = 0; j < width; j++)
625 for (
unsigned int i = 0; i < height; i++) {
626 Type val = V(i, j, k);
Representation of a physical image volume.
unsigned int getNumberOfFrames() const
unsigned int getSize() const
void resize(unsigned int height, unsigned int width, unsigned int numberOfFrames)
Type * getConstData() const
void initData(Type value)
unsigned int getHeight() const
unsigned int getWidth() const
Processing tools (derivative, filtering...) for the usImage3D class.
static void hessian(const usImage3D< Type > &src, usImage3D< vpMatrix > &dst)
static void frangi(const usImage3D< Type > &src, usImage3D< double > &dst, double a, double b, double c)
static Type min(const usImage3D< Type > &V)
static usImage3D< double > generateGaussianDerivativeFilterJ(double sigma, int size)
static void gaussianDerivativeJ(const usImage3D< Type1 > &src, usImage3D< Type2 > &dst, double sigma, unsigned int filter_size)
static void gradient(const usImage3D< Type > &src, usImage3D< vpColVector > &dst)
static void derivativeI(const usImage3D< Type1 > &src, usImage3D< Type2 > &dst)
static usImage3D< double > generateGaussianDerivativeFilterI(double sigma, int size)
static Type max(const usImage3D< Type > &V)
static void derivativeJ(const usImage3D< Type1 > &src, usImage3D< Type2 > &dst)
static void difference(const usImage3D< Type1 > &src1, const usImage3D< Type1 > &src2, usImage3D< Type2 > &dst)
static void derivativeK(const usImage3D< Type1 > &src, usImage3D< Type2 > &dst)
static void absoluteDifference(const usImage3D< Type1 > &src1, const usImage3D< Type1 > &src2, usImage3D< Type2 > &dst)
static void gaussianDerivativeI(const usImage3D< Type1 > &src, usImage3D< Type2 > &dst, double sigma, unsigned int filter_size)
static void gaussianDerivativeK(const usImage3D< Type1 > &src, usImage3D< Type2 > &dst, double sigma, unsigned int filter_size)
static double applyFilter(const usImage3D< Type1 > &src, const usImage3D< Type2 > &filter, unsigned int i, unsigned int j, unsigned int k)
static void computeBarycenter(const usImage3D< Type > &V, double &ic, double &jc, double &kc)
static usImage3D< double > generateGaussianDerivativeFilterK(double sigma, int size)