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"
319 template <
class SrcIterator,
class SrcAccessor,
320 class DestIterator,
class DestAccessor,
323 SrcIterator slowerright, SrcAccessor sa,
324 DestIterator dupperleft, DestAccessor da,
325 Kernel1D<T>
const & kx, Kernel1D<T>
const & ky)
328 NumericTraits<typename SrcAccessor::value_type>::RealPromote
330 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
333 destImage(tmp), kernel1d(kx));
335 destIter(dupperleft, da), kernel1d(ky));
338 template <
class SrcIterator,
class SrcAccessor,
339 class DestIterator,
class DestAccessor,
342 convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
343 pair<DestIterator, DestAccessor> dest,
344 Kernel1D<T>
const & kx, Kernel1D<T>
const & ky)
347 dest.first, dest.second, kx, ky);
350 template <
class T1,
class S1,
355 MultiArrayView<2, T2, S2> dest,
356 Kernel1D<T>
const & k)
358 vigra_precondition(src.shape() == dest.shape(),
359 "convolveImage(): shape mismatch between input and output.");
361 destImage(dest), k, k);
364 template <
class T1,
class S1,
369 MultiArrayView<2, T2, S2> dest,
370 Kernel1D<T>
const & kx, Kernel1D<T>
const & ky)
372 vigra_precondition(src.shape() == dest.shape(),
373 "convolveImage(): shape mismatch between input and output.");
375 destImage(dest), kx, ky);
463 template <
class SrcIterator,
class SrcAccessor,
464 class DestIterator,
class DestAccessor>
465 void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
466 DestIterator dest_ul, DestAccessor dest_acc,
double sharpening_factor)
469 vigra_precondition(sharpening_factor >= 0.0,
470 "simpleSharpening(): amount of sharpening must be >= 0.");
472 Kernel2D<double> kernel;
474 kernel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0,
475 -sharpening_factor/8.0, 1.0+sharpening_factor*0.75, -sharpening_factor/8.0,
476 -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_factor/16.0;
479 kernel.center(), kernel.accessor(),
480 kernel.upperLeft(), kernel.lowerRight() , BORDER_TREATMENT_REFLECT );
483 template <
class SrcIterator,
class SrcAccessor,
484 class DestIterator,
class DestAccessor>
487 pair<DestIterator, DestAccessor> dest,
double sharpening_factor)
490 dest.first, dest.second, sharpening_factor);
493 template <
class T1,
class S1,
497 MultiArrayView<2, T2, S2> dest,
498 double sharpening_factor)
500 vigra_precondition(src.shape() == dest.shape(),
501 "simpleSharpening(): shape mismatch between input and output.");
503 destImage(dest), sharpening_factor);
595 template <
class SrcIterator,
class SrcAccessor,
596 class DestIterator,
class DestAccessor>
598 DestIterator dest_ul, DestAccessor dest_acc,
double sharpening_factor,
601 vigra_precondition(sharpening_factor >= 0.0,
602 "gaussianSharpening(): amount of sharpening must be >= 0");
603 vigra_precondition(scale >= 0.0,
604 "gaussianSharpening(): scale parameter should be >= 0.");
606 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote ValueType;
608 BasicImage<ValueType> tmp(src_lr - src_ul, SkipInitialization);
610 gaussianSmoothing(src_ul, src_lr, src_acc, tmp.upperLeft(), tmp.accessor(), scale);
612 SrcIterator i_src = src_ul;
613 DestIterator i_dest = dest_ul;
618 for(; i_src.y != src_lr.y ; i_src.y++, i_dest.y++, i_tmp.y++ )
620 for (;i_src.x != src_lr.x ; i_src.x++, i_dest.x++, i_tmp.x++ )
622 dest_acc.set((1.0 + sharpening_factor)*src_acc(i_src) - sharpening_factor*tmp_acc(i_tmp), i_dest);
625 i_dest.x = dest_ul.x;
630 template <
class SrcIterator,
class SrcAccessor,
631 class DestIterator,
class DestAccessor>
634 pair<DestIterator, DestAccessor> dest,
double sharpening_factor,
638 dest.first, dest.second,
639 sharpening_factor, scale);
642 template <
class T1,
class S1,
646 MultiArrayView<2, T2, S2> dest,
647 double sharpening_factor,
650 vigra_precondition(src.shape() == dest.shape(),
651 "gaussianSharpening(): shape mismatch between input and output.");
654 sharpening_factor, scale);
740 template <
class SrcIterator,
class SrcAccessor,
741 class DestIterator,
class DestAccessor>
743 gaussianSmoothing(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
744 DestIterator dupperleft, DestAccessor da,
745 double scale_x,
double scale_y)
748 NumericTraits<typename SrcAccessor::value_type>::RealPromote
750 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
752 Kernel1D<double> smooth_x, smooth_y;
753 smooth_x.initGaussian(scale_x);
754 smooth_x.setBorderTreatment(BORDER_TREATMENT_REFLECT);
755 smooth_y.initGaussian(scale_y);
756 smooth_y.setBorderTreatment(BORDER_TREATMENT_REFLECT);
759 destImage(tmp), kernel1d(smooth_x));
761 destIter(dupperleft, da), kernel1d(smooth_y));
764 template <
class SrcIterator,
class SrcAccessor,
765 class DestIterator,
class DestAccessor>
767 gaussianSmoothing(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor sa,
768 DestIterator dupperleft, DestAccessor da,
776 template <
class SrcIterator,
class SrcAccessor,
777 class DestIterator,
class DestAccessor>
780 pair<DestIterator, DestAccessor> dest,
781 double scale_x,
double scale_y)
784 dest.first, dest.second, scale_x, scale_y);
787 template <
class SrcIterator,
class SrcAccessor,
788 class DestIterator,
class DestAccessor>
791 pair<DestIterator, DestAccessor> dest,
795 dest.first, dest.second, scale, scale);
798 template <
class T1,
class S1,
802 MultiArrayView<2, T2, S2> dest,
803 double scale_x,
double scale_y)
805 vigra_precondition(src.shape() == dest.shape(),
806 "gaussianSmoothing(): shape mismatch between input and output.");
808 destImage(dest), scale_x, scale_y);
811 template <
class T1,
class S1,
815 MultiArrayView<2, T2, S2> dest,
818 vigra_precondition(src.shape() == dest.shape(),
819 "gaussianSmoothing(): shape mismatch between input and output.");
821 destImage(dest), scale, scale);
944 template <
class SrcIterator,
class SrcAccessor,
945 class DestIteratorX,
class DestAccessorX,
946 class DestIteratorY,
class DestAccessorY>
948 SrcIterator slowerright, SrcAccessor sa,
949 DestIteratorX dupperleftx, DestAccessorX dax,
950 DestIteratorY dupperlefty, DestAccessorY day,
954 NumericTraits<typename SrcAccessor::value_type>::RealPromote
956 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
958 Kernel1D<double> smooth, grad;
959 smooth.initGaussian(scale);
960 grad.initGaussianDerivative(scale, 1);
963 destImage(tmp), kernel1d(grad));
965 destIter(dupperleftx, dax), kernel1d(smooth));
967 destImage(tmp), kernel1d(smooth));
969 destIter(dupperlefty, day), kernel1d(grad));
972 template <
class SrcIterator,
class SrcAccessor,
973 class DestIterator,
class DestAccessor>
975 SrcIterator slowerright, SrcAccessor src,
976 DestIterator dupperleft, DestAccessor dest,
979 VectorElementAccessor<DestAccessor> gradx(0, dest), grady(1, dest);
981 dupperleft, gradx, dupperleft, grady, scale);
984 template <
class SrcIterator,
class SrcAccessor,
985 class DestIteratorX,
class DestAccessorX,
986 class DestIteratorY,
class DestAccessorY>
989 pair<DestIteratorX, DestAccessorX> destx,
990 pair<DestIteratorY, DestAccessorY> desty,
994 destx.first, destx.second, desty.first, desty.second, scale);
997 template <
class SrcIterator,
class SrcAccessor,
998 class DestIterator,
class DestAccessor>
1001 pair<DestIterator, DestAccessor> dest,
1005 dest.first, dest.second, scale);
1008 template <
class T1,
class S1,
1009 class T2X,
class S2X,
1010 class T2Y,
class S2Y>
1013 MultiArrayView<2, T2X, S2X> destx,
1014 MultiArrayView<2, T2Y, S2Y> desty,
1017 vigra_precondition(src.shape() == destx.shape(),
1018 "gaussianGradient(): shape mismatch between input and output.");
1020 destImage(destx), destImage(desty), scale);
1023 template <
class T1,
class S1,
1027 MultiArrayView<2, TinyVector<T2, 2>, S2> dest,
1030 vigra_precondition(src.shape() == dest.shape(),
1031 "gaussianGradient(): shape mismatch between input and output.");
1033 destImage(dest), scale);
1200 template <
class SrcIterator,
class SrcAccessor,
1201 class DestIterator,
class DestAccessor>
1203 SrcIterator slr, SrcAccessor src,
1204 DestIterator dupperleft, DestAccessor dest,
1207 typedef typename NumericTraits<typename SrcAccessor::value_type>::RealPromote TmpType;
1208 BasicImage<TmpType> gradx(slr-sul, SkipInitialization), grady(slr-sul, SkipInitialization);
1211 destImage(gradx), destImage(grady), scale);
1212 combineTwoImages(srcImageRange(gradx), srcImage(grady), destIter(dupperleft, dest),
1213 MagnitudeFunctor<TmpType>());
1216 template <
class SrcIterator,
class SrcAccessor,
1217 class DestIterator,
class DestAccessor>
1220 pair<DestIterator, DestAccessor> dest,
1224 dest.first, dest.second, scale);
1307 template <
class SrcIterator,
class SrcAccessor,
1308 class DestIterator,
class DestAccessor>
1310 SrcIterator slowerright, SrcAccessor sa,
1311 DestIterator dupperleft, DestAccessor da,
1315 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1317 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
1318 tmpx(slowerright - supperleft, SkipInitialization),
1319 tmpy(slowerright - supperleft, SkipInitialization);
1321 Kernel1D<double> smooth, deriv;
1322 smooth.initGaussian(scale);
1323 deriv.initGaussianDerivative(scale, 2);
1326 destImage(tmp), kernel1d(deriv));
1328 destImage(tmpx), kernel1d(smooth));
1330 destImage(tmp), kernel1d(smooth));
1332 destImage(tmpy), kernel1d(deriv));
1334 destIter(dupperleft, da), std::plus<TmpType>());
1337 template <
class SrcIterator,
class SrcAccessor,
1338 class DestIterator,
class DestAccessor>
1341 pair<DestIterator, DestAccessor> dest,
1345 dest.first, dest.second, scale);
1348 template <
class T1,
class S1,
1352 MultiArrayView<2, T2, S2> dest,
1355 vigra_precondition(src.shape() == dest.shape(),
1356 "laplacianOfGaussian(): shape mismatch between input and output.");
1358 destImage(dest), scale);
1468 template <
class SrcIterator,
class SrcAccessor,
1469 class DestIteratorX,
class DestAccessorX,
1470 class DestIteratorXY,
class DestAccessorXY,
1471 class DestIteratorY,
class DestAccessorY>
1473 SrcIterator slowerright, SrcAccessor sa,
1474 DestIteratorX dupperleftx, DestAccessorX dax,
1475 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
1476 DestIteratorY dupperlefty, DestAccessorY day,
1480 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1482 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization);
1484 Kernel1D<double> smooth, deriv1, deriv2;
1485 smooth.initGaussian(scale);
1486 deriv1.initGaussianDerivative(scale, 1);
1487 deriv2.initGaussianDerivative(scale, 2);
1490 destImage(tmp), kernel1d(deriv2));
1492 destIter(dupperleftx, dax), kernel1d(smooth));
1494 destImage(tmp), kernel1d(smooth));
1496 destIter(dupperlefty, day), kernel1d(deriv2));
1498 destImage(tmp), kernel1d(deriv1));
1500 destIter(dupperleftxy, daxy), kernel1d(deriv1));
1503 template <
class SrcIterator,
class SrcAccessor,
1504 class DestIteratorX,
class DestAccessorX,
1505 class DestIteratorXY,
class DestAccessorXY,
1506 class DestIteratorY,
class DestAccessorY>
1509 pair<DestIteratorX, DestAccessorX> destx,
1510 pair<DestIteratorXY, DestAccessorXY> destxy,
1511 pair<DestIteratorY, DestAccessorY> desty,
1515 destx.first, destx.second,
1516 destxy.first, destxy.second,
1517 desty.first, desty.second,
1521 template <
class T1,
class S1,
1522 class T2X,
class S2X,
1523 class T2XY,
class S2XY,
1524 class T2Y,
class S2Y>
1527 MultiArrayView<2, T2X, S2X> destx,
1528 MultiArrayView<2, T2XY, S2XY> destxy,
1529 MultiArrayView<2, T2Y, S2Y> desty,
1532 vigra_precondition(src.shape() == destx.shape() && src.shape() == destxy.shape() && src.shape() == desty.shape(),
1533 "hessianMatrixOfGaussian(): shape mismatch between input and output.");
1541 template <
class T1,
class S1,
1545 MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
1548 vigra_precondition(src.shape() == dest.shape(),
1549 "hessianMatrixOfGaussian(): shape mismatch between input and output.");
1551 MultiArrayView<3, T2> expanded(dest.expandElements(0));
1552 MultiArrayView<2, T2> dxx(expanded.template bind<0>(0));
1553 MultiArrayView<2, T2> dxy(expanded.template bind<0>(1));
1554 MultiArrayView<2, T2> dyy(expanded.template bind<0>(2));
1715 template <
class SrcIterator,
class SrcAccessor,
1716 class DestIteratorX,
class DestAccessorX,
1717 class DestIteratorXY,
class DestAccessorXY,
1718 class DestIteratorY,
class DestAccessorY>
1720 SrcIterator slowerright, SrcAccessor sa,
1721 DestIteratorX dupperleftx, DestAccessorX dax,
1722 DestIteratorXY dupperleftxy, DestAccessorXY daxy,
1723 DestIteratorY dupperlefty, DestAccessorY day,
1724 double inner_scale,
double outer_scale)
1727 NumericTraits<typename SrcAccessor::value_type>::RealPromote
1729 BasicImage<TmpType> tmp(slowerright - supperleft, SkipInitialization),
1730 tmpx(slowerright - supperleft, SkipInitialization),
1731 tmpy(slowerright - supperleft, SkipInitialization);
1734 destImage(tmpx), destImage(tmpy), inner_scale);
1736 destImage(tmp), std::multiplies<TmpType>());
1738 destIter(dupperleftx, dax), outer_scale);
1740 destImage(tmp), std::multiplies<TmpType>());
1742 destIter(dupperlefty, day), outer_scale);
1744 destImage(tmp), std::multiplies<TmpType>());
1746 destIter(dupperleftxy, daxy), outer_scale);
1749 template <
class SrcIterator,
class SrcAccessor,
1750 class DestIteratorX,
class DestAccessorX,
1751 class DestIteratorXY,
class DestAccessorXY,
1752 class DestIteratorY,
class DestAccessorY>
1755 pair<DestIteratorX, DestAccessorX> destx,
1756 pair<DestIteratorXY, DestAccessorXY> destxy,
1757 pair<DestIteratorY, DestAccessorY> desty,
1758 double inner_scale,
double outer_scale)
1761 destx.first, destx.second,
1762 destxy.first, destxy.second,
1763 desty.first, desty.second,
1764 inner_scale, outer_scale);
1767 template <
class T,
class S,
1769 class TXY,
class SXY,
1773 MultiArrayView<2, TX, SX> destx,
1774 MultiArrayView<2, TXY, SXY> destxy,
1775 MultiArrayView<2, TY, SY> desty,
1776 double inner_scale,
double outer_scale)
1778 vigra_precondition(src.shape() == destx.shape(),
1779 "structureTensor(): shape mismatch between input and output.");
1781 destImage(destx), destImage(destxy), destImage(desty),
1782 inner_scale, outer_scale);
1787 template <
class SrcIterator,
class SrcAccessor,
1788 class DestIterator,
class DestAccessor>
1790 SrcIterator slowerright, SrcAccessor src,
1791 DestIterator dupperleft, DestAccessor dest,
1792 double inner_scale,
double outer_scale,
1795 typedef VectorElementAccessor<DestAccessor> DA;
1797 dupperleft, DA(0, dest),
1798 dupperleft, DA(1, dest),
1799 dupperleft, DA(2, dest),
1800 inner_scale, outer_scale);
1803 template <
class SrcIterator,
class SrcAccessor,
1804 class DestIterator,
class DestAccessor>
1806 SrcIterator slowerright, SrcAccessor src,
1807 DestIterator dupperleft, DestAccessor dest,
1808 double inner_scale,
double outer_scale,
1811 int bands = src.size(supperleft);
1812 typedef VectorElementAccessor<SrcAccessor> SA;
1816 inner_scale, outer_scale,
1819 BasicImage<typename DestAccessor::value_type> st(slowerright - supperleft, SkipInitialization);
1820 for(
int k=1; k < bands; ++k)
1823 st.upperLeft(), st.accessor(),
1824 inner_scale, outer_scale,
1826 combineTwoImages(srcImageRange(st), srcIter(dupperleft, dest), destIter(dupperleft, dest),
1827 std::plus<typename DestAccessor::value_type>());
1833 template <
class SrcIterator,
class SrcAccessor,
1834 class DestIterator,
class DestAccessor>
1836 SrcIterator slowerright, SrcAccessor src,
1837 DestIterator dupperleft, DestAccessor dest,
1838 double inner_scale,
double outer_scale)
1841 NumericTraits<typename SrcAccessor::value_type>::isScalar isScalar;
1842 detail::structureTensor(supperleft, slowerright, src,
1843 dupperleft, dest, inner_scale, outer_scale, isScalar());
1846 template <
class SrcIterator,
class SrcAccessor,
1847 class DestIterator,
class DestAccessor>
1850 pair<DestIterator, DestAccessor> dest,
1851 double inner_scale,
double outer_scale)
1854 dest.first, dest.second,
1855 inner_scale, outer_scale);
1858 template <
class T1,
class S1,
1862 MultiArrayView<2, TinyVector<T2, 3>, S2> dest,
1863 double inner_scale,
double outer_scale)
1865 vigra_precondition(src.shape() == dest.shape(),
1866 "structureTensor(): shape mismatch between input and output.");
1869 inner_scale, outer_scale);
1876 #endif // VIGRA_CONVOLUTION_HXX