73 template <
typename KDATATYPE>
class TKernel {
295 template <
typename KDATATYPE2>
302 _invalidateSeparableInfos();
309 _calculateRealKernelExt();
333 if (normalize){ manipulateKernelElements(KERN_NORMALIZE, 0); }
516 mutable bool _areSeparabilityInfosUpToDate;
536 mutable std::vector<ImageVector> _separableCoordTab;
552 template <
typename KDATATYPE>
561 template <
typename KDATATYPE>
571 template <
typename KDATATYPE>
580 template <
typename KDATATYPE>
589 setPartialKernel(
kern._tabSize,
kern._coordTab,
kern._valueTab);
592 _isSeparable =
kern._isSeparable;
593 _areSeparabilityInfosUpToDate =
kern._areSeparabilityInfosUpToDate;
594 _separableDimEntries =
kern._separableDimEntries;
595 _separableOneDimExt =
kern._separableOneDimExt;
596 _separableExt =
kern._separableExt;
597 _separableNegExt =
kern._separableNegExt;
598 _separablePosExt =
kern._separablePosExt;
599 _separableCoordTab =
kern._separableCoordTab;
609 template <
typename KDATATYPE>
623 template <
typename KDATATYPE>
627 _validateSeparabilityInfos();
628 return getSeparableCoordTab().size();
643 template <
typename KDATATYPE>
646 return _isSeparable ? &(getSeparableCoordTab()[getSeparableDimIndex(dim)]) : _coordTab;
655 template <
typename KDATATYPE>
658 return _isSeparable ? (_valueTab + getSeparableDimIndex(dim)) : _valueTab;
664 template <
typename KDATATYPE>
669 for (
size_t i=0;
i<_tabSize;
i++){ v+=_valueTab[
i]; }
677 template <
typename KDATATYPE>
682 for (
size_t i=1;
i<_tabSize;
i++){
if (_valueTab[
i] < v){ v = _valueTab[
i]; } }
690 template <
typename KDATATYPE>
695 for (
size_t i=1;
i<_tabSize;
i++){
if (_valueTab[
i] > v){ v = _valueTab[
i]; } }
704 template <
typename KDATATYPE>
708 for (
size_t i=0;
i<_tabSize;
i++){
710 if (!(_valueTab[
i] > 0)){ v += _valueTab[
i]; }
719 template <
typename KDATATYPE>
723 for (
size_t i=0;
i<_tabSize;
i++){
if (_valueTab[
i] > 0){ v += _valueTab[
i]; } }
731 template <
typename KDATATYPE>
735 _invalidateSeparableInfos();
740 for (
size_t i=0;
i<_tabSize;
i++){ _valueTab[
i] = v; }
746 for (
size_t i=0;
i<_tabSize;
i++){ _valueTab[
i] *= v; }
752 for (
size_t i=0;
i<_tabSize;
i++){ _valueTab[
i] += v; }
758 for (
size_t i=0;
i<_tabSize;
i++){
if (!
MLValueIs0WOM(_valueTab[
i])) {_valueTab[
i] = v/_valueTab[
i]; } }
764 for (
size_t i=0;
i<_tabSize;
i++){ _valueTab[
i] = v-_valueTab[
i]; }
770 for (
size_t i=0;
i<_tabSize;
i++){ _valueTab[
i] *= _valueTab[
i]; }
777 for (
size_t i=0;
i<_tabSize;
i++){
782 _valueTab[
i] =
static_cast<KDATATYPE>(sqrt(
static_cast<double>(_valueTab[
i])));
790 for (
size_t i=0;
i<_tabSize;
i++){
815 for (
size_t i=0;
i<_tabSize;
i++){
818 if (val > 0){ _valueTab[
i] =
static_cast<KDATATYPE>(log(
static_cast<double>(val))*
invBase); }
824 case KERN_NORMALIZE:{
887 case NUM_KERN_MODIFYERS:{
888 ML_PRINT_ERROR(
"TKernel<KDATATYPE>::manipulateKernelElements(mlKernModifier mode, KDATATYPE v)",
889 ML_PROGRAMMING_ERROR,
"NUM_KERN_MODIFYERS is an invalid parameter. Ignoring kernel manipulation.");
894 ML_PRINT_ERROR(
"TKernel<KDATATYPE>::manipulateKernelElements(mlKernModifier mode, KDATATYPE v)",
895 ML_BAD_PARAMETER,
"Invalid parameter passed. Ignoring kernel manipulation.");
912 template <
typename KDATATYPE>
916 _validateSeparabilityInfos();
917 return _separableExt;
930 template <
typename KDATATYPE>
934 _validateSeparabilityInfos();
935 return _separableNegExt;
945 template <
typename KDATATYPE>
949 _validateSeparabilityInfos();
950 return _separablePosExt;
961 template <
typename KDATATYPE>
964 return SubImage::coordToIndex(x,y,z,c,t,u, size);
970 template <
typename KDATATYPE>
973 return SubImage::coordToIndex(p, size);
979 template <
typename KDATATYPE>
982 return SubImage::indexToCoord(
idx,
ext);
988 template <
typename KDATATYPE>
997 template <
typename KDATATYPE>
1008 template <
typename KDATATYPE>
1012 for (
size_t c=0; c < _tabSize; c++){
1013 if (_coordTab[c] == pos){
1029 template <
typename KDATATYPE>
1045 for (
size_t c=0; c < _tabSize; c++){ _coordTab[c] =
coords[c]; }
1055 for (
size_t d=0; d<_tabSize; d++){ _valueTab[d] = v; }
1061 _calculateRealKernelExt();
1096 template <
typename KDATATYPE>
1108 for (
MLint u=0; u < getExtent().u; u++){
1109 for (
MLint t=0; t < getExtent().t; t++){
1110 for (
MLint c=0; c < getExtent().c; c++){
1111 for (
MLint z=0; z < getExtent().z; z++){
1112 for (
MLint y=0; y < getExtent().y; y++){
1114 snprintf(
strLine, 255,
"(*,%lld,%lld,%lld,%lld,%lld):", y, z, c, t, u);
1125 for (
MLint x=0; x < getExtent().x; x++){
1134 strLine[0] = x==0 ?
' ' :
',';
1165 for (
size_t c=0; c < _tabSize; c++){
1214 template <
typename KDATATYPE>
1219 char *copy =
nullptr;
1235 if (
str[
str.length()-1] !=
'\n'){
str +=
'\n'; }
1238 MLint lineNumber = 0;
1241 MLint x=0, y=0, z=0, c=0, t=0, u=0, num=0;
1243 num =
sscanf(
str.c_str(),
"(%lld,%lld,%lld,%lld,%lld,%lld):%lf", &x, &y, &z, &c, &t, &u, &
fValue);
1247 _addCoordinate(
ImageVector(x,y,z,c,t,u), value,
false);
1251 num =
sscanf(
str.c_str(),
"(*,%lld,%lld,%lld,%lld,%lld):", &y, &z, &c, &t, &u);
1254 const size_t cPos =
str.find(
':');
1255 if (
cPos != std::string::npos){
1264 while (
go && (
str.length() != 0)){
1265 const char ch =
str[0];
1273 else if (
'\n' ==
ch) {
1279 else if (
',' ==
ch) {
1318 Memory::freeMemory(copy);
1328 const size_t pos =
str.find(
'\n');
1329 if (pos != std::string::npos){
1332 str.erase(0, pos+1);
1345 _calculateRealKernelExt();
1362 template <
typename KDATATYPE>
1374 for (
size_t c=0; c<
maxElems; c++){
if (mask[c]){ _tabSize++; } }
1385 if (!_coordTab || !_valueTab){
1388 "Cannot create kernel filter tables, so tables are reset. This will probably cause other errors.");
1391 if (_coordTab && _valueTab){
1400 for (
size_t d=0; d<_tabSize; d++){ _valueTab[d] = v; }
1407 if (!mask || (mask && mask[e])){
1408 _coordTab[
idx] = indexToCoord(e,
ext);
1413 if (
idx !=_tabSize){
1415 "Internal error. Cannot create kernel filter tables. This will probably cause other errors.");
1423 _calculateRealKernelExt();
1435 template <
typename KDATATYPE>
1445 size_t numEntries = 0;
1453 for (
size_t r=0; r <
numRows; ++r){
1478 _validateSeparabilityInfos();
1488 template <
typename KDATATYPE>
1508 if ((u < getExtent().u) &&
1509 (t < getExtent().t) &&
1510 (c < getExtent().c) &&
1511 (z < getExtent().z) &&
1512 (y < getExtent().y) &&
1513 (x < getExtent().x)){
1535 _calculateRealKernelExt();
1542 template <
typename KDATATYPE>
1546 _invalidateSeparableInfos();
1549 for (
MLint u=0; u < getExtent().u; u++){
1550 for (
MLint t=0; t < getExtent().t; t++){
1551 for (
MLint c=0; c < getExtent().c; c++){
1552 for (
MLint z=0; z < getExtent().z; z++){
1553 for (
MLint y=0; y < getExtent().y; y++){
1554 for (
MLint x=0; x < getExtent().x; x++){
1573 _calculateRealKernelExt();
1584 template <
typename KDATATYPE>
1588 _invalidateSeparableInfos();
1615 _coordTab =
nullptr;
1618 _valueTab =
nullptr;
1626 for (
size_t e=0; e <
tabSize; e++){
1638 _addCoordinate(v,
valueTab[e],
false);
1649 _calculateRealKernelExt();
1659 template <
typename KDATATYPE>
1663 _invalidateSeparableInfos();
1667 _coordTab =
nullptr;
1670 _valueTab =
nullptr;
1710 _calculateRealKernelExt();
1717 template <
typename KDATATYPE>
1725 if((
k!=0) && (
k!=
n)){
1726 for (
i=1;
i<(
n+1);
i++){ v*=
i; }
1727 for (
i=1;
i<(
k+1);
i++){ v/=
i; }
1728 for (
i=1;
i<(
n-
k+1);
i++){ v/=
i; }
1741 template <
typename KDATATYPE>
1745 std::vector<KDATATYPE> v;
1761 if (normalize && (sum > 0)){
1762 for (
size_t u=0; u<
numSamples; u++){ v[u] /= sum; }
1773 template <
typename KDATATYPE>
1777 _invalidateSeparableInfos();
1783 std::vector<KDATATYPE> vx=get1DGauss(
ext.x,
false);
1784 std::vector<KDATATYPE> vy=get1DGauss(
ext.y,
false);
1785 std::vector<KDATATYPE> vz=get1DGauss(
ext.z,
false);
1786 std::vector<KDATATYPE> vc=get1DGauss(
ext.c,
false);
1787 std::vector<KDATATYPE>
vt=get1DGauss(
ext.t,
false);
1788 std::vector<KDATATYPE>
vu=get1DGauss(
ext.u,
false);
1792 setKernel(
ext, &(vx[0]), &(vy[0]), &(vz[0]), &(vc[0]), &(
vt[0]), &(
vu[0]),
true);
1799 template <
typename KDATATYPE>
1808 _valueTab =
nullptr;
1809 _coordTab =
nullptr;
1812 _isSeparable =
false;
1813 _areSeparabilityInfosUpToDate =
false;
1814 _separableDimEntries.set(0);
1815 _separableOneDimExt.set(0);
1816 _separableExt.set(0);
1817 _separableNegExt.set(0);
1818 _separablePosExt.set(0);
1819 _separableCoordTab.clear();
1826 template <
typename KDATATYPE>
1833 _areSeparabilityInfosUpToDate =
false;
1835 delete [] _valueTab;
1837 _valueTab =
nullptr;
1838 delete [] _coordTab;
1839 _coordTab =
nullptr;
1849 template <
typename KDATATYPE>
1857 _areSeparabilityInfosUpToDate =
false;
1873 "Cannot create kernel tables. Returning with invalid "
1874 "reset tables. This will probably cause other errors.");
1897 if (update){ _calculateRealKernelExt(); }
1907 template <
typename KDATATYPE>
1915 if (getTabSize() > 0){
1916 for (
size_t c=0; c < getTabSize(); c++){
1917 maximum = ImageVector::compMax(_coordTab[c], maximum);
1927 _negExt = calculateNegativeExtentFromExtent(_ext);
1928 _posExt = calculatePositiveExtentFromExtent(_ext);
1931 if (!_ext.allBiggerZero()){
1934 "Kernel has invalid extents now. Continuing anyway.");
1952 template <
typename KDATATYPE>
1958 _invalidateSeparableInfos();
1966 template <
typename KDATATYPE>
1969 return _isSeparable;
1977 template <
typename KDATATYPE>
1980 _validateSeparabilityInfos();
1981 return _separableDimEntries;
1991 template <
typename KDATATYPE>
1994 _validateSeparabilityInfos();
1995 return _separableOneDimExt;
2006 template <
typename KDATATYPE>
2009 _validateSeparabilityInfos();
2010 if (dim>5){ dim = 5; }
2016 case 1:
return static_cast<size_t>(_separableDimEntries.x);
2018 case 2:
return static_cast<size_t>(_separableDimEntries.x +
2019 _separableDimEntries.y);
2021 case 3:
return static_cast<size_t>(_separableDimEntries.x +
2022 _separableDimEntries.y +
2023 _separableDimEntries.z);
2025 case 4:
return static_cast<size_t>(_separableDimEntries.x +
2026 _separableDimEntries.y +
2027 _separableDimEntries.z +
2028 _separableDimEntries.c);
2030 case 5:
return static_cast<size_t>(_separableDimEntries.x +
2031 _separableDimEntries.y +
2032 _separableDimEntries.z +
2033 _separableDimEntries.c +
2034 _separableDimEntries.t);
2046 template <
typename KDATATYPE>
2049 _validateSeparabilityInfos();
2050 return _separableCoordTab;
2056 template <
typename KDATATYPE>
2059 _areSeparabilityInfosUpToDate =
false;
2069 template <
typename KDATATYPE>
2073 if (_areSeparabilityInfosUpToDate){
return; }
2074 if (!_areSeparabilityInfosUpToDate){
2080 _separableDimEntries.set(0);
2081 _separableOneDimExt.set(0);
2082 _separableExt.set(0);
2083 _separableCoordTab.clear();
2086 while ((
idx<_tabSize) && (_coordTab[
idx].y < 6)){
2096 _separableDimEntries[
entryY]++;
2113 _separableCoordTab.push_back(
sepCoord);
2121 _separableExt = _separableOneDimExt;
2122 _separableExt.fillSmallerComps(1,1);
2130 for (
size_t e=0; e <
idx; ++e){
2133 for (
size_t d=0; d < 6; ++d){
2135 if (coord[d] == -1){ coord[d] =
negExt[d]; }
2145 _areSeparabilityInfosUpToDate =
true;
Class to manage a filtering kernel for images.
virtual ~TKernel()
Destructor. Cleans up and removes instance of kernel.
void mirror(int dimension=-1)
Applies a point symmetric mirroring of all kernel elements.
std::string getKernel(bool asLines=false, MLint fieldWidth=0, MLint precision=10) const
Returns the current kernel elements and values as string: The string needs has the following format: ...
const ImageVector & getPositiveExtent() const
See getNegativeExtent().
bool isSeparable() const
Indicates whether the first 6 rows of the first kernel slice are interpreted as 1-D axes of a separab...
static ImageVector indexToCoord(MLint idx, const ImageVector &ext)
Converts an index into an array with extents ext to a coordinate.
void makeCircular()
Takes the current kernel, computes radii from the extents of the kernel and removes all kernel elemen...
static ImageVector calculateNegativeExtentFromExtent(const ImageVector &ext)
Calculate the negative extent of a kernel from a kernel extent.
static ImageVector calculatePositiveExtentFromExtent(const ImageVector &ext)
Calculate the positive extent of a kernel from a kernel extent.
void _invalidateSeparableInfos()
Invalidate separability information.
static MLldouble binomialcoeff(MLint n, MLint k)
Calculate binomial coefficients for (n) (k)
void _init()
Initialization. Should be called only by constructors.
void fillUndefinedElements(KDATATYPE newVal=0)
Fill all undefined kernel elements with newVal.
static MLint coordToIndex(const ImageVector &p, const ImageVector &size)
Converts the coordinate into the kernel with extents size to an index.
void setPartialKernel(size_t numElems, ImageVector *const coords, KDATATYPE *const values=nullptr)
Defines a set of local kernel coordinates and optionally a set of values which define the kernel elem...
size_t getTabSize() const
Returns the current number of kernel elements.
ImageVector getSeparableDimEntries() const
Returns a ImageVector with the number of entries of the separable kernel for the dimensions 0,...
KDATATYPE getMinValue() const
Return the minimum value of all kernel element values If kernel value table is empty then 0 is return...
KDATATYPE getMaxValue() const
Return the maximum value of all kernel element values If kernel value table is empty then 1 is return...
void setSeparable(bool isSeparableVal)
Set/unset a flag to indicate that the first 6 rows of the first kernel slice is considered as 1-D axe...
const TKernel & operator=(const TKernel &kern)
Assignment operator. Sets current instance to contents of kern.
void manipulateKernelElements(KernModifier mode, KDATATYPE v)
Modify all kernel element values with the value v.
TKernel()
Constructor. Builds an empty kernel.
static std::vector< KDATATYPE > get1DGauss(size_t numSamples, bool normalize=true)
Returns a vector with numSample values binomial coefficients.
std::string setKernel(const std::string &kernString)
Defines elements and values of the kernel matrix by a string.
void reset()
Reset kernel to construction state.
const ImageVector & getExtent() const
Returns the kernel extents in 6D.
ImageVector getSeparableOneDimExtents() const
Returns a vector where the components 0,...,5 contain the extent of the region spanned by the 6 separ...
const std::vector< ImageVector > & getSeparableCoordTab() const
Returns the table of with all coordinates for filtering with separable kernels.
const KDATATYPE * getValueTab(size_t dim=0) const
Gets the table of kernel element values which are currently defined.
void _clearTables()
Clear all internal (dynamic) tables.
MLint findIndex(const ImageVector &pos) const
Return index to kernel element if it exists; otherwise return -1.
KernModifier
Manipulation modes for kernel values with a given value v:
KDATATYPE getValueTabSum() const
Return the sum of all kernel element values.
void setKernel(const ImageVector &ext, const KDATATYPE2 *const xaxis, const KDATATYPE2 *const yaxis, const KDATATYPE2 *const zaxis, const KDATATYPE2 *const caxis, const KDATATYPE2 *const taxis, const KDATATYPE2 *const uaxis, bool normalize)
Defines a complete kernel matrix whose extents are defined by ext.
static MLint coordToIndex(MLint x, MLint y, MLint z, MLint c, MLint t, MLint u, const ImageVector &size)
Converts the coordinate (x,y,z,c,t,u) into the kernel to an index into an array with 6D extents given...
const ImageVector * getCoordTab(size_t dim=0) const
Gets a table of coordinates pointing to all kernel elements which are currently defined.
TKernel(const TKernel &kern)
Copy constructor. Builds a kernel with contents of kern.
void _addCoordinate(const ImageVector &pos, KDATATYPE value, bool update)
Add a new coordinate with value to the coordinate and value table.
const ImageVector & getNegativeExtent() const
The extent of the kernel to both sides.
void _calculateRealKernelExt()
Calculate the correct maximum kernel extent for used kernel elements.
size_t getSeparableDimIndex(size_t dim=0) const
Returns the index to entries of valueTab or coordTab which are related to the 1-D separable kernel fo...
void setGauss(const ImageVector &ext)
Replaces the current kernel by a normalized gauss kernel.
KDATATYPE getNegativeValueSum() const
Return the sum of all negative kernel element values.
KDATATYPE getPositiveValueSum() const
Return the sum of all positive kernel element values.
void setKernel(const ImageVector &ext, const KDATATYPE *const values=nullptr, bool *const mask=nullptr)
Defines a complete kernel matrix whose extents are defined by ext.
void _validateSeparabilityInfos() const
This method updates all members which are needed in query methods for separability properties of the ...
void setSeparableKernel(const std::vector< typename std::vector< KDATATYPE > > &separableRows)
Create kernel coordinate and value tables in separable table format, that means a 2-D kernel where ea...
void resizeKernel(const ImageVector &ext, KDATATYPE newVal=0)
Resizes the kernel to a new state and tries to maintain the previous elements if possible.
std::string print(const std::string &openStr="", const std::string &sepStr=" ", const std::string &termStr="", const MLint16 numDigits=-1) const
Returns the string openStr + v.array[0] + sepStr + ... + v.array[NumberOfDimensions-2] + sepStr + v....
bool MLValueIs0WOM(MLint8 a)
Returns true if value is 0, otherwise false.
bool MLValuesDifferWOM(MLint8 a, MLint8 b)
Returns true if values differ, otherwise false.
#define ML_CALCULATION_ERROR
This is an unspecific error used in some cases where the error is not very specific; for which there ...
#define ML_PROGRAMMING_ERROR
A case occurred which should not appear and here are a variety of reasons, typically it is a programm...
#define ML_BAD_PARAMETER
A bad/invalid parameter (or even an inappropriate image) has been passed to a module or an algorithm;...
#define ML_NO_MEMORY
The system does not have enough memory to perform the desired operation; try to reduce application da...
#define ML_PRINT_FATAL_ERROR(FUNC_NAME, REASON, HANDLING)
Like ML_PRINT_FATAL_ERROR_DUMP(FUNC_NAME, REASON, HANDLING, RT_OBJ) without a runtime object to be du...
#define ML_PRINT_ERROR(FUNC_NAME, REASON, HANDLING)
Like ML_PRINT_ERROR_DUMP(FUNC_NAME, REASON, HANDLING, RT_OBJ) without a runtime object to be dumped.
Target mlrange_cast(Source arg)
Generic version of checked ML casts.
@ ML_FATAL_MEMORY_ERROR
On allocation failure a fatal error print is done and NULL is returned.
MLint64 MLint
A signed ML integer type with at least 64 bits used for index calculations on very large images even ...
T mlAbs(T a)
Defines ML specific abs template since only type depended library functions exists.
MLdouble KernelDataType
Define the standard data type for kernel elements to be used in this library.