37 #ifndef VIGRA_CONVOLUTION_HXX
38 #define VIGRA_CONVOLUTION_HXX
41 #include "stdconvolution.hxx"
42 #include "separableconvolution.hxx"
43 #include "recursiveconvolution.hxx"
44 #include "nonlineardiffusion.hxx"
45 #include "combineimages.hxx"
46 #include "multi_shape.hxx"
354 doxygen_overloaded_function(template <...>
void convolveImage)
356 template <
class SrcIterator,
class SrcAccessor,
357 class DestIterator,
class DestAccessor,
360 SrcIterator slowerright, SrcAccessor sa,
361 DestIterator dupperleft, DestAccessor da,
362 Kernel1D<T>
const & kx, Kernel1D<T>
const & ky)
365 NumericTraits<typename SrcAccessor::value_type>::RealPromote
367 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
370 destImage(tmp), kernel1d(kx));
372 destIter(dupperleft, da), kernel1d(ky));
375 template <
class SrcIterator,
class SrcAccessor,
376 class DestIterator,
class DestAccessor,
379 convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
380 pair<DestIterator, DestAccessor> dest,
381 Kernel1D<T>
const & kx, Kernel1D<T>
const & ky)
384 dest.first, dest.second, kx, ky);
387 template <
class T1,
class S1,
392 MultiArrayView<2, T2, S2> dest,
393 Kernel1D<T>
const & k)
395 vigra_precondition(src.shape() == dest.shape(),
396 "convolveImage(): shape mismatch between input and output.");
398 destImage(dest), k, k);
401 template <
class T1,
class S1,
406 MultiArrayView<2, T2, S2> dest,
407 Kernel1D<T>
const & kx, Kernel1D<T>
const & ky)
409 vigra_precondition(src.shape() == dest.shape(),
410 "convolveImage(): shape mismatch between input and output.");
412 destImage(dest), kx, ky);
498 doxygen_overloaded_function(template <...>
void simpleSharpening)
500 template <
class SrcIterator,
class SrcAccessor,
501 class DestIterator,
class DestAccessor>
502 void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
503 DestIterator dest_ul, DestAccessor dest_acc,
double sharpening_factor)
506 vigra_precondition(sharpening_factor >= 0.0,
507 "simpleSharpening(): amount of sharpening must be >= 0.");
509 Kernel2D<double> kernel;
511 kernel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0,
512 -sharpening_factor/8.0, 1.0+sharpening_factor*0.75, -sharpening_factor/8.0,
513 -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0;
516 kernel.center(), kernel.accessor(),
517 kernel.upperLeft(), kernel.lowerRight() , BORDER_TREATMENT_REFLECT );
520 template <
class SrcIterator,
class SrcAccessor,
521 class DestIterator,
class DestAccessor>
524 pair<DestIterator, DestAccessor> dest,
double sharpening_factor)
527 dest.first, dest.second, sharpening_factor);
530 template <
class T1,
class S1,
534 MultiArrayView<2, T2, S2> dest,
535 double sharpening_factor)
537 vigra_precondition(src.shape() == dest.shape(),
538 "simpleSharpening(): shape mismatch between input and output.");
540 destImage(dest), sharpening_factor);
630 doxygen_overloaded_function(template <...>
void gaussianSharpening)
632 template <
class SrcIterator,
class SrcAccessor,
633 class DestIterator,
class DestAccessor>
635 DestIterator dest_ul, DestAccessor dest_acc,
double sharpening_factor,
638 vigra_precondition(sharpening_factor >= 0.0,
639 "gaussianSharpening(): amount of sharpening must be >= 0");
640 vigra_precondition(scale >= 0.0,
641 "gaussianSharpening(): scale parameter should be >= 0.");
643 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote ValueType;
645 BasicImage<ValueType> tmp(src_lr - src_ul, SkipInitialization);
647 gaussianSmoothing(src_ul, src_lr, src_acc, tmp.upperLeft(), tmp.accessor(), scale);
649 SrcIterator i_src = src_ul;
650 DestIterator i_dest = dest_ul;
651 typename BasicImage<ValueType>::traverser tmp_ul = tmp.upperLeft();
652 typename BasicImage<ValueType>::traverser i_tmp = tmp_ul;
653 typename BasicImage<ValueType>::Accessor tmp_acc = tmp.accessor();
655 for(; i_src.y != src_lr.y ; i_src.y++, i_dest.y++, i_tmp.y++ )
657 for (;i_src.x != src_lr.x ; i_src.x++, i_dest.x++, i_tmp.x++ )
659 dest_acc.set((1.0 + sharpening_factor)*src_acc(i_src) - sharpening_factor*tmp_acc(i_tmp), i_dest);
662 i_dest.x = dest_ul.x;
667 template <
class SrcIterator,
class SrcAccessor,
668 class DestIterator,
class DestAccessor>
671 pair<DestIterator, DestAccessor> dest,
double sharpening_factor,
675 dest.first, dest.second,
676 sharpening_factor, scale);
679 template <
class T1,
class S1,
683 MultiArrayView<2, T2, S2> dest,
684 double sharpening_factor,
687 vigra_precondition(src.shape() == dest.shape(),
688 "gaussianSharpening(): shape mismatch between input and output.");
691 sharpening_factor, scale);
775 doxygen_overloaded_function(template <...>
void gaussianSmoothing)
777 template <
class SrcIterator,
class SrcAccessor,
778 class DestIterator,
class DestAccessor>
780 gaussianSmoothing(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
781 DestIterator dupperleft, DestAccessor da,
782 double scale_x,
double scale_y)
785 NumericTraits<typename SrcAccessor::value_type>::RealPromote
787 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
789 Kernel1D<double> smooth_x, smooth_y;
790 smooth_x.initGaussian(scale_x);
791 smooth_x.setBorderTreatment(BORDER_TREATMENT_REFLECT);
792 smooth_y.initGaussian(scale_y);
793 smooth_y.setBorderTreatment(BORDER_TREATMENT_REFLECT);
796 destImage(tmp), kernel1d(smooth_x));
798 destIter(dupperleft, da), kernel1d(smooth_y));
801 template <
class SrcIterator,
class SrcAccessor,
802 class DestIterator,
class DestAccessor>
804 gaussianSmoothing(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
805 DestIterator dupperleft, DestAccessor da,
813 template <
class SrcIterator,
class SrcAccessor,
814 class DestIterator,
class DestAccessor>
817 pair<DestIterator, DestAccessor> dest,
818 double scale_x,
double scale_y)
821 dest.first, dest.second, scale_x, scale_y);
824 template <
class SrcIterator,
class SrcAccessor,
825 class DestIterator,
class DestAccessor>
828 pair<DestIterator, DestAccessor> dest,
832 dest.first, dest.second, scale, scale);
835 template <
class T1,
class S1,
839 MultiArrayView<2, T2, S2> dest,
840 double scale_x,
double scale_y)
842 vigra_precondition(src.shape() == dest.shape(),
843 "gaussianSmoothing(): shape mismatch between input and output.");
845 destImage(dest), scale_x, scale_y);
848 template <
class T1,
class S1,
852 MultiArrayView<2, T2, S2> dest,
855 vigra_precondition(src.shape() == dest.shape(),
856 "gaussianSmoothing(): shape mismatch between input and output.");
858 destImage(dest), scale, scale);
979 doxygen_overloaded_function(template <...>
void gaussianGradient)
981 template <
class SrcIterator,
class SrcAccessor,
982 class DestIteratorX,
class DestAccessorX,
983 class DestIteratorY,
class DestAccessorY>
985 SrcIterator slowerright, SrcAccessor sa,
986 DestIteratorX dupperleftx, DestAccessorX dax,
987 DestIteratorY dupperlefty, DestAccessorY day,
991 NumericTraits<typename SrcAccessor::value_type>::RealPromote
993 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
995 Kernel1D<double> smooth, grad;
996 smooth.initGaussian(scale);
997 grad.initGaussianDerivative(scale, 1);
1000 destImage(tmp), kernel1d(grad));
1002 destIter(dupperleftx, dax), kernel1d(smooth));
1004 destImage(tmp), kernel1d(smooth));
1006 destIter(dupperlefty, day), kernel1d(grad));
1009 template <
class SrcIterator,
class SrcAccessor,
1010 class DestIterator,
class DestAccessor>
1012 SrcIterator slowerright, SrcAccessor src,
1013 DestIterator dupperleft, DestAccessor dest,
1016 VectorElementAccessor<DestAccessor> gradx(0, dest), grady(1, dest);
1018 dupperleft, gradx, dupperleft, grady, scale);
1021 template <
class SrcIterator,
class SrcAccessor,
1022 class DestIteratorX,
class DestAccessorX,
1023 class DestIteratorY,
class DestAccessorY>
1026 pair<DestIteratorX, DestAccessorX> destx,
1027 pair<DestIteratorY, DestAccessorY> desty,
1031 destx.first, destx.second, desty.first, desty.second, scale);
1034 template <
class SrcIterator,
class SrcAccessor,
1035 class DestIterator,
class DestAccessor>
1038 pair<DestIterator, DestAccessor> dest,
1042 dest.first, dest.second, scale);
1045 template <
class T1,
class S1,
1046 class T2X,
class S2X,
1047 class T2Y,
class S2Y>
1050 MultiArrayView<2, T2X, S2X> destx,
1051 MultiArrayView<2, T2Y, S2Y> desty,
1054 vigra_precondition(src.shape() == destx.shape(),
1055 "gaussianGradient(): shape mismatch between input and output.");
1057 destImage(destx), destImage(desty), scale);
1060 template <
class T1,
class S1,
1064 MultiArrayView<2, TinyVector<T2, 2>, S2> dest,
1067 vigra_precondition(src.shape() == dest.shape(),
1068 "gaussianGradient(): shape mismatch between input and output.");
1070 destImage(dest), scale);
1208 doxygen_overloaded_function(template <...>
void gaussianGradientMagnitude)
1210 template <
class SrcIterator,
class SrcAccessor,
1211 class DestIterator,
class DestAccessor>
1213 SrcIterator slr, SrcAccessor src,
1214 DestIterator dupperleft, DestAccessor dest,
1217 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
1218 BasicImage<TmpType> gradx(slr-sul, SkipInitialization), grady(slr-sul, SkipInitialization);
1221 destImage(gradx), destImage(grady), scale);
1222 combineTwoImages(srcImageRange(gradx), srcImage(grady), destIter(dupperleft, dest),
1223 MagnitudeFunctor<TmpType>());
1226 template <
class SrcIterator,
class SrcAccessor,
1227 class DestIterator,
class DestAccessor>
1230 pair<DestIterator, DestAccessor> dest,
1234 dest.first, dest.second, scale);
1315 doxygen_overloaded_function(template <...>
void laplacianOfGaussian)
1317 template <
class SrcIterator,
class SrcAccessor,
1318 class DestIterator,
class DestAccessor>
1320 SrcIterator slowerright, SrcAccessor sa,
1321 DestIterator dupperleft, DestAccessor da,
1325 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1327 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
1328 tmpx(slowerright - supperleft, SkipInitialization),
1329 tmpy(slowerright - supperleft, SkipInitialization);
1331 Kernel1D<double> smooth, deriv;
1332 smooth.initGaussian(scale);
1333 deriv.initGaussianDerivative(scale, 2);
1336 destImage(tmp), kernel1d(deriv));
1338 destImage(tmpx), kernel1d(smooth));
1340 destImage(tmp), kernel1d(smooth));
1342 destImage(tmpy), kernel1d(deriv));
1344 destIter(dupperleft, da), std::plus<TmpType>());
1347 template <
class SrcIterator,
class SrcAccessor,
1348 class DestIterator,
class DestAccessor>
1351 pair<DestIterator, DestAccessor> dest,
1355 dest.first, dest.second, scale);
1358 template <
class T1,
class S1,
1362 MultiArrayView<2, T2, S2> dest,
1365 vigra_precondition(src.shape() == dest.shape(),
1366 "laplacianOfGaussian(): shape mismatch between input and output.");
1368 destImage(dest), scale);
1476 doxygen_overloaded_function(template <...>
void hessianMatrixOfGaussian)
1478 template <
class SrcIterator,
class SrcAccessor,
1479 class DestIteratorX,
class DestAccessorX,
1480 class DestIteratorXY,
class DestAccessorXY,
1481 class DestIteratorY,
class DestAccessorY>
1483 SrcIterator slowerright, SrcAccessor sa,
1484 DestIteratorX dupperleftx, DestAccessorX dax,
1485 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
1486 DestIteratorY dupperlefty, DestAccessorY day,
1490 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1492 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
1494 Kernel1D<double> smooth, deriv1, deriv2;
1495 smooth.initGaussian(scale);
1496 deriv1.initGaussianDerivative(scale, 1);
1497 deriv2.initGaussianDerivative(scale, 2);
1500 destImage(tmp), kernel1d(deriv2));
1502 destIter(dupperleftx, dax), kernel1d(smooth));
1504 destImage(tmp), kernel1d(smooth));
1506 destIter(dupperlefty, day), kernel1d(deriv2));
1508 destImage(tmp), kernel1d(deriv1));
1510 destIter(dupperleftxy, daxy), kernel1d(deriv1));
1513 template <
class SrcIterator,
class SrcAccessor,
1514 class DestIteratorX,
class DestAccessorX,
1515 class DestIteratorXY,
class DestAccessorXY,
1516 class DestIteratorY,
class DestAccessorY>
1519 pair<DestIteratorX, DestAccessorX> destx,
1520 pair<DestIteratorXY, DestAccessorXY> destxy,
1521 pair<DestIteratorY, DestAccessorY> desty,
1525 destx.first, destx.second,
1526 destxy.first, destxy.second,
1527 desty.first, desty.second,
1531 template <
class T1,
class S1,
1532 class T2X,
class S2X,
1533 class T2XY,
class S2XY,
1534 class T2Y,
class S2Y>
1537 MultiArrayView<2, T2X, S2X> destx,
1538 MultiArrayView<2, T2XY, S2XY> destxy,
1539 MultiArrayView<2, T2Y, S2Y> desty,
1542 vigra_precondition(src.shape() == destx.shape() && src.shape() == destxy.shape() && src.shape() == desty.shape(),
1543 "hessianMatrixOfGaussian(): shape mismatch between input and output.");
1551 template <
class T1,
class S1,
1555 MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
1558 vigra_precondition(src.shape() == dest.shape(),
1559 "hessianMatrixOfGaussian(): shape mismatch between input and output.");
1561 MultiArrayView<3, T2> expanded(dest.expandElements(0));
1564 destImage(expanded.bind<0>(0)),
1565 destImage(expanded.bind<0>(1)),
1566 destImage(expanded.bind<0>(2)),
1720 doxygen_overloaded_function(template <...>
void structureTensor)
1722 template <
class SrcIterator,
class SrcAccessor,
1723 class DestIteratorX,
class DestAccessorX,
1724 class DestIteratorXY,
class DestAccessorXY,
1725 class DestIteratorY,
class DestAccessorY>
1727 SrcIterator slowerright, SrcAccessor sa,
1728 DestIteratorX dupperleftx, DestAccessorX dax,
1729 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
1730 DestIteratorY dupperlefty, DestAccessorY day,
1731 double inner_scale,
double outer_scale)
1734 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1736 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
1737 tmpx(slowerright - supperleft, SkipInitialization),
1738 tmpy(slowerright - supperleft, SkipInitialization);
1741 destImage(tmpx), destImage(tmpy), inner_scale);
1743 destImage(tmp), std::multiplies<TmpType>());
1745 destIter(dupperleftx, dax), outer_scale);
1747 destImage(tmp), std::multiplies<TmpType>());
1749 destIter(dupperlefty, day), outer_scale);
1751 destImage(tmp), std::multiplies<TmpType>());
1753 destIter(dupperleftxy, daxy), outer_scale);
1756 template <
class SrcIterator,
class SrcAccessor,
1757 class DestIteratorX,
class DestAccessorX,
1758 class DestIteratorXY,
class DestAccessorXY,
1759 class DestIteratorY,
class DestAccessorY>
1762 pair<DestIteratorX, DestAccessorX> destx,
1763 pair<DestIteratorXY, DestAccessorXY> destxy,
1764 pair<DestIteratorY, DestAccessorY> desty,
1765 double inner_scale,
double outer_scale)
1768 destx.first, destx.second,
1769 destxy.first, destxy.second,
1770 desty.first, desty.second,
1771 inner_scale, outer_scale);
1774 template <
class T,
class S,
1776 class TXY,
class SXY,
1780 MultiArrayView<2, TX, SX> destx,
1781 MultiArrayView<2, TXY, SXY> destxy,
1782 MultiArrayView<2, TY, SY> desty,
1783 double inner_scale,
double outer_scale)
1785 vigra_precondition(src.shape() == destx.shape(),
1786 "structureTensor(): shape mismatch between input and output.");
1788 destImage(destx), destImage(destxy), destImage(desty),
1789 inner_scale, outer_scale);
1794 template <
class SrcIterator,
class SrcAccessor,
1795 class DestIterator,
class DestAccessor>
1797 SrcIterator slowerright, SrcAccessor src,
1798 DestIterator dupperleft, DestAccessor dest,
1799 double inner_scale,
double outer_scale,
1802 typedef VectorElementAccessor<DestAccessor> DA;
1804 dupperleft, DA(0, dest),
1805 dupperleft, DA(1, dest),
1806 dupperleft, DA(2, dest),
1807 inner_scale, outer_scale);
1810 template <
class SrcIterator,
class SrcAccessor,
1811 class DestIterator,
class DestAccessor>
1813 SrcIterator slowerright, SrcAccessor src,
1814 DestIterator dupperleft, DestAccessor dest,
1815 double inner_scale,
double outer_scale,
1818 int bands = src.size(supperleft);
1819 typedef VectorElementAccessor<SrcAccessor> SA;
1823 inner_scale, outer_scale,
1826 BasicImage<typename DestAccessor::value_type> st(slowerright - supperleft, SkipInitialization);
1827 for(
int k=1; k < bands; ++k)
1830 st.upperLeft(), st.accessor(),
1831 inner_scale, outer_scale,
1833 combineTwoImages(srcImageRange(st), srcIter(dupperleft, dest), destIter(dupperleft, dest),
1834 std::plus<typename DestAccessor::value_type>());
1840 template <
class SrcIterator,
class SrcAccessor,
1841 class DestIterator,
class DestAccessor>
1843 SrcIterator slowerright, SrcAccessor src,
1844 DestIterator dupperleft, DestAccessor dest,
1845 double inner_scale,
double outer_scale)
1848 NumericTraits<typename SrcAccessor::value_type>::isScalar isScalar;
1849 detail::structureTensor(supperleft, slowerright, src,
1850 dupperleft, dest, inner_scale, outer_scale, isScalar());
1853 template <
class SrcIterator,
class SrcAccessor,
1854 class DestIterator,
class DestAccessor>
1857 pair<DestIterator, DestAccessor> dest,
1858 double inner_scale,
double outer_scale)
1861 dest.first, dest.second,
1862 inner_scale, outer_scale);
1865 template <
class T1,
class S1,
1869 MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
1870 double inner_scale,
double outer_scale)
1872 vigra_precondition(src.shape() == dest.shape(),
1873 "structureTensor(): shape mismatch between input and output.");
1876 inner_scale, outer_scale);
1883 #endif // VIGRA_CONVOLUTION_HXX
void simpleSharpening(...)
Perform simple sharpening function.
void gaussianGradient(...)
Calculate the gradient vector by means of a 1st derivatives of Gaussian filter.
void laplacianOfGaussian(...)
Filter image with the Laplacian of Gaussian operator at the given scale.
void gaussianGradientMagnitude(...)
Calculate the gradient magnitude by means of a 1st derivatives of Gaussian filter.
void gaussianSmoothing(...)
Perform isotropic Gaussian convolution.
Definition: accessor.hxx:43
void separableConvolveX(...)
Performs a 1 dimensional convolution in x direction.
void combineTwoImages(...)
Combine two source images into destination image.
void convolveImage(...)
Convolve an image with the given kernel(s).
void gaussianSharpening(...)
Perform sharpening function with gaussian filter.
void structureTensor(...)
Calculate the Structure Tensor for each pixel of and image, using Gaussian (derivative) filters...
void hessianMatrixOfGaussian(...)
Filter image with the 2nd derivatives of the Gaussian at the given scale to get the Hessian matrix...
void separableConvolveY(...)
Performs a 1 dimensional convolution in y direction.