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" 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);
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);
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;
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);
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);
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);
1233 template <
class SrcIterator,
class SrcAccessor,
1234 class DestIterator,
class DestAccessor>
1236 SrcIterator slr, SrcAccessor src,
1237 DestIterator dupperleft, DestAccessor dest,
1240 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
1241 BasicImage<TmpType> gradx(slr-sul, SkipInitialization), grady(slr-sul, SkipInitialization);
1244 destImage(gradx), destImage(grady), scale);
1245 combineTwoImages(srcImageRange(gradx), srcImage(grady), destIter(dupperleft, dest),
1246 MagnitudeFunctor<TmpType>());
1249 template <
class SrcIterator,
class SrcAccessor,
1250 class DestIterator,
class DestAccessor>
1253 pair<DestIterator, DestAccessor> dest,
1257 dest.first, dest.second, scale);
1340 template <
class SrcIterator,
class SrcAccessor,
1341 class DestIterator,
class DestAccessor>
1343 SrcIterator slowerright, SrcAccessor sa,
1344 DestIterator dupperleft, DestAccessor da,
1348 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1350 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
1351 tmpx(slowerright - supperleft, SkipInitialization),
1352 tmpy(slowerright - supperleft, SkipInitialization);
1354 Kernel1D<double> smooth, deriv;
1355 smooth.initGaussian(scale);
1356 deriv.initGaussianDerivative(scale, 2);
1359 destImage(tmp), kernel1d(deriv));
1361 destImage(tmpx), kernel1d(smooth));
1363 destImage(tmp), kernel1d(smooth));
1365 destImage(tmpy), kernel1d(deriv));
1367 destIter(dupperleft, da), std::plus<TmpType>());
1370 template <
class SrcIterator,
class SrcAccessor,
1371 class DestIterator,
class DestAccessor>
1374 pair<DestIterator, DestAccessor> dest,
1378 dest.first, dest.second, scale);
1381 template <
class T1,
class S1,
1385 MultiArrayView<2, T2, S2> dest,
1388 vigra_precondition(src.shape() == dest.shape(),
1389 "laplacianOfGaussian(): shape mismatch between input and output.");
1391 destImage(dest), scale);
1501 template <
class SrcIterator,
class SrcAccessor,
1502 class DestIteratorX,
class DestAccessorX,
1503 class DestIteratorXY,
class DestAccessorXY,
1504 class DestIteratorY,
class DestAccessorY>
1506 SrcIterator slowerright, SrcAccessor sa,
1507 DestIteratorX dupperleftx, DestAccessorX dax,
1508 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
1509 DestIteratorY dupperlefty, DestAccessorY day,
1513 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1515 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
1517 Kernel1D<double> smooth, deriv1, deriv2;
1518 smooth.initGaussian(scale);
1519 deriv1.initGaussianDerivative(scale, 1);
1520 deriv2.initGaussianDerivative(scale, 2);
1523 destImage(tmp), kernel1d(deriv2));
1525 destIter(dupperleftx, dax), kernel1d(smooth));
1527 destImage(tmp), kernel1d(smooth));
1529 destIter(dupperlefty, day), kernel1d(deriv2));
1531 destImage(tmp), kernel1d(deriv1));
1533 destIter(dupperleftxy, daxy), kernel1d(deriv1));
1536 template <
class SrcIterator,
class SrcAccessor,
1537 class DestIteratorX,
class DestAccessorX,
1538 class DestIteratorXY,
class DestAccessorXY,
1539 class DestIteratorY,
class DestAccessorY>
1542 pair<DestIteratorX, DestAccessorX> destx,
1543 pair<DestIteratorXY, DestAccessorXY> destxy,
1544 pair<DestIteratorY, DestAccessorY> desty,
1548 destx.first, destx.second,
1549 destxy.first, destxy.second,
1550 desty.first, desty.second,
1554 template <
class T1,
class S1,
1555 class T2X,
class S2X,
1556 class T2XY,
class S2XY,
1557 class T2Y,
class S2Y>
1560 MultiArrayView<2, T2X, S2X> destx,
1561 MultiArrayView<2, T2XY, S2XY> destxy,
1562 MultiArrayView<2, T2Y, S2Y> desty,
1565 vigra_precondition(src.shape() == destx.shape() && src.shape() == destxy.shape() && src.shape() == desty.shape(),
1566 "hessianMatrixOfGaussian(): shape mismatch between input and output.");
1574 template <
class T1,
class S1,
1578 MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
1581 vigra_precondition(src.shape() == dest.shape(),
1582 "hessianMatrixOfGaussian(): shape mismatch between input and output.");
1584 MultiArrayView<3, T2> expanded(dest.expandElements(0));
1585 MultiArrayView<2, T2> dxx(expanded.template bind<0>(0));
1586 MultiArrayView<2, T2> dxy(expanded.template bind<0>(1));
1587 MultiArrayView<2, T2> dyy(expanded.template bind<0>(2));
1748 template <
class SrcIterator,
class SrcAccessor,
1749 class DestIteratorX,
class DestAccessorX,
1750 class DestIteratorXY,
class DestAccessorXY,
1751 class DestIteratorY,
class DestAccessorY>
1753 SrcIterator slowerright, SrcAccessor sa,
1754 DestIteratorX dupperleftx, DestAccessorX dax,
1755 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
1756 DestIteratorY dupperlefty, DestAccessorY day,
1757 double inner_scale,
double outer_scale)
1760 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1762 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
1763 tmpx(slowerright - supperleft, SkipInitialization),
1764 tmpy(slowerright - supperleft, SkipInitialization);
1767 destImage(tmpx), destImage(tmpy), inner_scale);
1769 destImage(tmp), std::multiplies<TmpType>());
1771 destIter(dupperleftx, dax), outer_scale);
1773 destImage(tmp), std::multiplies<TmpType>());
1775 destIter(dupperlefty, day), outer_scale);
1777 destImage(tmp), std::multiplies<TmpType>());
1779 destIter(dupperleftxy, daxy), outer_scale);
1782 template <
class SrcIterator,
class SrcAccessor,
1783 class DestIteratorX,
class DestAccessorX,
1784 class DestIteratorXY,
class DestAccessorXY,
1785 class DestIteratorY,
class DestAccessorY>
1788 pair<DestIteratorX, DestAccessorX> destx,
1789 pair<DestIteratorXY, DestAccessorXY> destxy,
1790 pair<DestIteratorY, DestAccessorY> desty,
1791 double inner_scale,
double outer_scale)
1794 destx.first, destx.second,
1795 destxy.first, destxy.second,
1796 desty.first, desty.second,
1797 inner_scale, outer_scale);
1800 template <
class T,
class S,
1802 class TXY,
class SXY,
1806 MultiArrayView<2, TX, SX> destx,
1807 MultiArrayView<2, TXY, SXY> destxy,
1808 MultiArrayView<2, TY, SY> desty,
1809 double inner_scale,
double outer_scale)
1811 vigra_precondition(src.shape() == destx.shape(),
1812 "structureTensor(): shape mismatch between input and output.");
1814 destImage(destx), destImage(destxy), destImage(desty),
1815 inner_scale, outer_scale);
1820 template <
class SrcIterator,
class SrcAccessor,
1821 class DestIterator,
class DestAccessor>
1823 SrcIterator slowerright, SrcAccessor src,
1824 DestIterator dupperleft, DestAccessor dest,
1825 double inner_scale,
double outer_scale,
1828 typedef VectorElementAccessor<DestAccessor> DA;
1830 dupperleft, DA(0, dest),
1831 dupperleft, DA(1, dest),
1832 dupperleft, DA(2, dest),
1833 inner_scale, outer_scale);
1836 template <
class SrcIterator,
class SrcAccessor,
1837 class DestIterator,
class DestAccessor>
1839 SrcIterator slowerright, SrcAccessor src,
1840 DestIterator dupperleft, DestAccessor dest,
1841 double inner_scale,
double outer_scale,
1844 int bands = src.size(supperleft);
1845 typedef VectorElementAccessor<SrcAccessor> SA;
1849 inner_scale, outer_scale,
1852 BasicImage<typename DestAccessor::value_type> st(slowerright - supperleft, SkipInitialization);
1853 for(
int k=1; k < bands; ++k)
1856 st.upperLeft(), st.accessor(),
1857 inner_scale, outer_scale,
1859 combineTwoImages(srcImageRange(st), srcIter(dupperleft, dest), destIter(dupperleft, dest),
1860 std::plus<typename DestAccessor::value_type>());
1866 template <
class SrcIterator,
class SrcAccessor,
1867 class DestIterator,
class DestAccessor>
1869 SrcIterator slowerright, SrcAccessor src,
1870 DestIterator dupperleft, DestAccessor dest,
1871 double inner_scale,
double outer_scale)
1874 NumericTraits<typename SrcAccessor::value_type>::isScalar isScalar;
1875 detail::structureTensor(supperleft, slowerright, src,
1876 dupperleft, dest, inner_scale, outer_scale, isScalar());
1879 template <
class SrcIterator,
class SrcAccessor,
1880 class DestIterator,
class DestAccessor>
1883 pair<DestIterator, DestAccessor> dest,
1884 double inner_scale,
double outer_scale)
1887 dest.first, dest.second,
1888 inner_scale, outer_scale);
1891 template <
class T1,
class S1,
1895 MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
1896 double inner_scale,
double outer_scale)
1898 vigra_precondition(src.shape() == dest.shape(),
1899 "structureTensor(): shape mismatch between input and output.");
1902 inner_scale, outer_scale);
1909 #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.
IteratorTraits< traverser >::DefaultAccessor Accessor
Definition: basicimage.hxx:571
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.
BasicImageIterator< PIXELTYPE, PIXELTYPE ** > traverser
Definition: basicimage.hxx:526
doxygen_overloaded_function(template<... > void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays.
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.