30 #ifndef _D_MEASURES_HPP
31 #define _D_MEASURES_HPP
33 #include "Core/include/private/DImage.hpp"
34 #include "DBaseMeasureOperations.hpp"
35 #include "DImageArith.hpp"
36 #include "Base/include/DImageDraw.h"
58 struct measAreaFunc :
public MeasureFunctionBase<T, double> {
59 typedef typename Image<T>::lineType lineType;
61 virtual void processSequence(lineType ,
size_t size)
94 return static_cast<size_t>(func(imIn,
true));
99 struct measVolFunc :
public MeasureFunctionBase<T, double> {
100 typedef typename Image<T>::lineType lineType;
102 virtual void processSequence(lineType lineIn,
size_t size)
104 for (
size_t i = 0; i < size; i++)
105 this->retVal +=
double(lineIn[i]);
135 return func(imIn,
false);
157 return func(imIn,
false);
170 struct measMeanValFunc :
public MeasureFunctionBase<T, Vector_double> {
171 typedef typename Image<T>::lineType lineType;
175 virtual void initialize(
const Image<T> & )
177 this->retVal.clear();
178 sum1 = sum2 = pixNbr = 0.;
180 virtual void processSequence(lineType lineIn,
size_t size)
183 for (
size_t i = 0; i < size; i++) {
190 virtual void finalize(
const Image<T> & )
192 double mean_val = pixNbr == 0 ? 0 : sum1 / pixNbr;
194 pixNbr == 0 ? 0 :
std::sqrt(sum2 / pixNbr - mean_val * mean_val);
196 this->retVal.push_back(mean_val);
197 this->retVal.push_back(std_dev_val);
213 measMeanValFunc<T> func;
214 return func(imIn, onlyNonZero);
227 struct measMinValFunc :
public MeasureFunctionBase<T, T> {
228 typedef typename Image<T>::lineType lineType;
229 virtual void initialize(
const Image<T> & )
231 this->retVal = numeric_limits<T>::max();
233 virtual void processSequence(lineType lineIn,
size_t size)
235 for (
size_t i = 0; i < size; i++)
236 if (lineIn[i] < this->retVal)
237 this->retVal = lineIn[i];
242 struct measMinValPosFunc :
public MeasureFunctionWithPos<T, T> {
243 typedef typename Image<T>::lineType lineType;
245 virtual void initialize(
const Image<T> & )
247 this->retVal = numeric_limits<T>::max();
249 virtual void processSequence(lineType lineIn,
size_t size,
size_t x,
252 for (
size_t i = 0; i < size; i++, x++)
253 if (lineIn[i] < this->retVal) {
254 this->retVal = lineIn[i];
273 measMinValFunc<T> func;
274 return func(imIn, onlyNonZero);
288 measMinValPosFunc<T> func;
289 func(imIn, onlyNonZero);
304 struct measMaxValFunc :
public MeasureFunctionBase<T, T> {
305 typedef typename Image<T>::lineType lineType;
306 virtual void initialize(
const Image<T> & )
308 this->retVal = numeric_limits<T>::min();
310 virtual void processSequence(lineType lineIn,
size_t size)
312 for (
size_t i = 0; i < size; i++)
313 if (lineIn[i] > this->retVal)
314 this->retVal = lineIn[i];
319 struct measMaxValPosFunc :
public MeasureFunctionWithPos<T, T> {
320 typedef typename Image<T>::lineType lineType;
322 virtual void initialize(
const Image<T> & )
324 this->retVal = numeric_limits<T>::min();
326 virtual void processSequence(lineType lineIn,
size_t size,
size_t x,
329 for (
size_t i = 0; i < size; i++, x++)
330 if (lineIn[i] > this->retVal) {
331 this->retVal = lineIn[i];
350 measMaxValFunc<T> func;
351 return func(imIn, onlyNonZero);
365 measMaxValPosFunc<T> func;
366 func(imIn, onlyNonZero);
381 struct measMinMaxValFunc :
public MeasureFunctionBase<T, vector<T>> {
382 typedef typename Image<T>::lineType lineType;
384 virtual void initialize(
const Image<T> & )
386 this->retVal.clear();
387 maxVal = numeric_limits<T>::min();
388 minVal = numeric_limits<T>::max();
390 virtual void processSequence(lineType lineIn,
size_t size)
392 for (
size_t i = 0; i < size; i++) {
400 virtual void finalize(
const Image<T> & )
402 this->retVal.push_back(
minVal);
403 this->retVal.push_back(
maxVal);
418 measMinMaxValFunc<T> func;
419 return func(imIn, onlyNonZero);
432 struct valueListFunc :
public MeasureFunctionBase<T, vector<T>> {
433 typedef typename Image<T>::lineType lineType;
436 virtual void initialize(
const Image<T> & )
438 this->retVal.clear();
442 virtual void processSequence(lineType lineIn,
size_t size)
444 for (
size_t i = 0; i < size; i++)
445 valList.insert(lineIn[i]);
447 virtual void finalize(
const Image<T> & )
450 std::copy(valList.begin(), valList.end(),
451 std::back_inserter(this->retVal));
470 valueListFunc<T> func;
471 return func(imIn, onlyNonZero);
484 struct measModeValFunc :
public MeasureFunctionBase<T, T> {
485 typedef typename Image<T>::lineType lineType;
487 map<int, int> nbList;
490 virtual void initialize(
const Image<T> & )
498 virtual void processSequence(lineType lineIn,
size_t size)
500 for (
size_t i = 0; i < size; i++) {
503 if (nbList.find(val) == nbList.end()) {
504 nbList.insert(std::pair<int, int>(val, 1));
507 if (nbList[val] > maxNb) {
536 measModeValFunc<T> func;
537 return func(imIn, onlyNonZero);
550 struct measMedianValFunc :
public MeasureFunctionBase<T, T> {
551 typedef typename Image<T>::lineType lineType;
553 map<int, int> nbList;
554 size_t acc_elem, total_elems;
556 virtual void initialize(
const Image<T> & )
565 virtual void processSequence(lineType lineIn,
size_t size)
567 for (
size_t i = 0; i < size; i++) {
571 if (nbList.find(val) == nbList.end()) {
572 nbList.insert(std::pair<int, int>(val, 1));
581 virtual void finalize(
const Image<T> & )
583 typedef std::map<int, int>::iterator it_type;
585 for (it_type my_iterator = nbList.begin(); my_iterator != nbList.end();
587 acc_elem = acc_elem + my_iterator->second;
588 if (acc_elem > total_elems / 2.0) {
589 medianval = my_iterator->first;
596 this->retVal = medianval;
612 measMedianValFunc<T> func;
613 return func(imIn, onlyNonZero);
636 size_t y1,
size_t z = 0)
644 vector<IntPoint> bPoints;
645 if (x0 >= imW || y0 >= imH || x1 >= imW || y1 >= imH)
651 typename Image<T>::sliceType lines = im.
getSlices()[z];
653 for (vector<IntPoint>::iterator it = bPoints.begin(); it != bPoints.end();
655 vec.push_back(lines[(*it).y][(*it).x]);
670 struct measBarycenterFunc :
public MeasureFunctionWithPos<T, Vector_double> {
671 typedef typename Image<T>::lineType lineType;
672 double xSum, ySum, zSum, tSum;
673 virtual void initialize(
const Image<T> & )
675 this->retVal.clear();
676 xSum = ySum = zSum = tSum = 0.;
678 virtual void processSequence(lineType lineIn,
size_t size,
size_t x,
681 for (
size_t i = 0; i < size; i++, x++) {
682 T pixVal = lineIn[i];
683 xSum += double(pixVal) * x;
684 ySum += double(pixVal) * y;
685 zSum += double(pixVal) * z;
686 tSum += double(pixVal);
689 virtual void finalize(
const Image<T> &imIn)
691 this->retVal.push_back(xSum / tSum);
692 this->retVal.push_back(ySum / tSum);
693 if (imIn.getDimension() == 3)
694 this->retVal.push_back(zSum / tSum);
707 measBarycenterFunc<T> func;
708 return func(im,
false);
721 struct measBoundBoxFunc :
public MeasureFunctionWithPos<T, vector<size_t>> {
722 typedef typename Image<T>::lineType lineType;
723 double xMin, xMax, yMin, yMax, zMin, zMax;
725 virtual void initialize(
const Image<T> &imIn)
727 this->retVal.clear();
729 imIn.getSize(imSize);
730 im3d = (imSize[2] > 1);
739 virtual void processSequence(lineType ,
size_t size,
size_t x,
744 if (x + size - 1 > xMax)
757 virtual void finalize(
const Image<T> & )
759 this->retVal.push_back(UINT(xMin));
760 this->retVal.push_back(UINT(yMin));
762 this->retVal.push_back(UINT(zMin));
763 this->retVal.push_back(UINT(xMax));
764 this->retVal.push_back(UINT(yMax));
766 this->retVal.push_back(UINT(zMax));
781 measBoundBoxFunc<T> func;
782 return func(im,
true);
795 struct measMomentsFunc :
public MeasureFunctionWithPos<T, Vector_double> {
796 typedef typename Image<T>::lineType lineType;
797 double m000, m100, m010, m110, m200, m020, m001, m101, m011, m002;
799 virtual void initialize(
const Image<T> &imIn)
801 im3d = (imIn.getDimension() == 3);
802 this->retVal.clear();
803 m000 = m100 = m010 = m110 = m200 = m020 = m001 = m101 = m011 = m002 = 0.;
805 virtual void processSequence(lineType lineIn,
size_t size,
size_t x,
808 for (
size_t i = 0; i < size; i++, x++) {
809 double pxVal = double(lineIn[i]);
813 m110 += pxVal * x * y;
814 m200 += pxVal * x * x;
815 m020 += pxVal * y * y;
818 m101 += pxVal * x * z;
819 m011 += pxVal * y * z;
820 m002 += pxVal * z * z;
824 virtual void finalize(
const Image<T> & )
826 this->retVal.push_back(m000);
827 this->retVal.push_back(m100);
828 this->retVal.push_back(m010);
830 this->retVal.push_back(m001);
831 this->retVal.push_back(m110);
833 this->retVal.push_back(m101);
834 this->retVal.push_back(m011);
836 this->retVal.push_back(m200);
837 this->retVal.push_back(m020);
839 this->retVal.push_back(m002);
847 double EPSILON = 1e-8;
850 if (moments[0] < EPSILON)
853 bool im3d = (moments.size() == 10);
868 m[4] -= moments[2] * moments[1] / moments[0];
869 m[5] -= moments[3] * moments[1] / moments[0];
870 m[6] -= moments[3] * moments[2] / moments[0];
872 m[7] -= moments[1] * moments[1] / moments[0];
873 m[8] -= moments[2] * moments[2] / moments[0];
874 m[9] -= moments[3] * moments[3] / moments[0];
882 m[3] -= moments[2] * moments[1] / moments[0];
884 m[4] -= moments[1] * moments[1] / moments[0];
885 m[5] -= moments[2] * moments[2] / moments[0];
932 const bool centered =
false)
936 measMomentsFunc<T> func;
937 m = func(im, onlyNonZero);
940 m = centerMoments(m);
954 inline vector<double>
955 genericCovariance(
const Image<T> &imIn1,
const Image<T> &imIn2,
size_t dx,
956 size_t dy,
size_t dz,
size_t maxSteps = 0,
957 bool normalize =
false)
960 ASSERT(areAllocated(&imIn1, &imIn2, NULL), vec);
961 ASSERT(haveSameSize(&imIn1, &imIn2, NULL),
962 "Input images must have the same size", vec);
963 ASSERT((dx + dy + dz > 0),
964 "dx, dy and dz can't be all zero at the same time", vec);
969 size_t maxH = max(max(s[0], s[1]), s[2]);
971 maxH = min(maxH, s[0]);
973 maxH = min(maxH, s[1]);
975 maxH = min(maxH, s[2]);
982 maxSteps = min(maxSteps, maxH);
984 ERR_MSG(
"Too small");
990 typename ImDtTypes<T>::volType slicesIn1 = imIn1.getSlices();
991 typename ImDtTypes<T>::volType slicesIn2 = imIn2.getSlices();
992 typename ImDtTypes<T>::sliceType curSliceIn1;
993 typename ImDtTypes<T>::sliceType curSliceIn2;
994 typename ImDtTypes<T>::lineType lineIn1;
995 typename ImDtTypes<T>::lineType lineIn2;
996 typename ImDtTypes<T>::lineType bufLine = ImDtTypes<T>::createLine(s[0]);
998 for (
size_t len = 0; len <= maxSteps; len++) {
1001 size_t mdx = min(dx * len, s[0] - 1);
1002 size_t mdy = min(dy * len, s[1] - 1);
1003 size_t mdz = min(dz * len, s[2] - 1);
1005 size_t xLen = s[0] - mdx;
1006 size_t yLen = s[1] - mdy;
1007 size_t zLen = s[2] - mdz;
1009 for (
size_t z = 0; z < zLen; z++) {
1010 curSliceIn1 = slicesIn1[z];
1011 curSliceIn2 = slicesIn2[z + mdz];
1012 for (
size_t y = 0; y < yLen; y++) {
1013 lineIn1 = curSliceIn1[y];
1014 lineIn2 = curSliceIn2[y + mdy];
1015 copyLine<T>(lineIn2 + mdx, xLen, bufLine);
1017 for (
size_t x = 0; x < xLen; x++) {
1018 prod += lineIn1[x] * bufLine[x];
1022 if (xLen * yLen * zLen != 0)
1023 prod /= (xLen * yLen * zLen);
1024 vec.push_back(prod);
1028 double orig = vec[0];
1029 for (vector<double>::iterator it = vec.begin(); it != vec.end(); it++)
1033 ImDtTypes<T>::deleteLine(bufLine);
1068 vector<double>
measCovariance(
const Image<T> &imIn1,
const Image<T> &imIn2,
1069 size_t dx,
size_t dy,
size_t dz,
1070 size_t maxSteps = 0,
bool normalize =
false)
1073 ASSERT(areAllocated(&imIn1, &imIn2, NULL), vec);
1074 ASSERT(haveSameSize(&imIn1, &imIn2, NULL),
1075 "Input images must have the same size", vec);
1076 ASSERT((dx + dy + dz > 0),
1077 "dx, dy and dz can't be all zero at the same time", vec);
1082 size_t maxH = max(max(s[0], s[1]), s[2]);
1084 maxH = min(maxH, s[0]);
1086 maxH = min(maxH, s[1]);
1088 maxH = min(maxH, s[2]);
1095 maxSteps = min(maxSteps, maxH);
1096 if (maxSteps == 0) {
1097 ERR_MSG(
"Too small");
1103 typename ImDtTypes<T>::volType slicesIn1 = imIn1.getSlices();
1104 typename ImDtTypes<T>::volType slicesIn2 = imIn2.getSlices();
1105 typename ImDtTypes<T>::sliceType curSliceIn1;
1106 typename ImDtTypes<T>::sliceType curSliceIn2;
1107 typename ImDtTypes<T>::lineType lineIn1;
1108 typename ImDtTypes<T>::lineType lineIn2;
1109 typename ImDtTypes<T>::lineType bufLine = ImDtTypes<T>::createLine(s[0]);
1111 for (
size_t len = 0; len <= maxSteps; len++) {
1114 size_t mdx = min(dx * len, s[0] - 1);
1115 size_t mdy = min(dy * len, s[1] - 1);
1116 size_t mdz = min(dz * len, s[2] - 1);
1118 size_t xLen = s[0] - mdx;
1119 size_t yLen = s[1] - mdy;
1120 size_t zLen = s[2] - mdz;
1122 for (
size_t z = 0; z < zLen; z++) {
1123 curSliceIn1 = slicesIn1[z];
1124 curSliceIn2 = slicesIn2[z + mdz];
1125 for (
size_t y = 0; y < yLen; y++) {
1126 lineIn1 = curSliceIn1[y];
1127 lineIn2 = curSliceIn2[y + mdy];
1128 copyLine<T>(lineIn2 + mdx, xLen, bufLine);
1130 for (
size_t x = 0; x < xLen; x++) {
1131 prod += lineIn1[x] * bufLine[x];
1135 if (xLen * yLen * zLen != 0)
1136 prod /= (xLen * yLen * zLen);
1137 vec.push_back(prod);
1141 double orig = vec[0];
1142 for (vector<double>::iterator it = vec.begin(); it != vec.end(); it++)
1146 ImDtTypes<T>::deleteLine(bufLine);
1184 size_t dx,
size_t dy,
size_t dz,
1185 size_t maxSteps = 0,
bool centered =
false,
1186 bool normalize =
false)
1190 float meanV1 =
meanVal(imMean1)[0];
1191 sub(imMean1, meanV1, imMean1);
1194 float meanV2 =
meanVal(imMean2)[0];
1195 sub(imMean2, meanV2, imMean2);
1197 return genericCovariance(imMean1, imMean2, dx, dy, dz, maxSteps,
1200 return genericCovariance(imIn1, imIn2, dx, dy, dz, maxSteps, normalize);
1220 size_t dz,
size_t maxSteps = 0,
1221 bool centered =
false,
1222 bool normalize =
false)
1226 float meanV =
meanVal(imMean)[0];
1227 sub(imMean, meanV, imMean);
1228 return genericCovariance(imMean, imMean, dx, dy, dz, maxSteps, normalize);
1230 return genericCovariance(imIn, imIn, dx, dy, dz, maxSteps, normalize);
1244 struct measEntropyFunc :
public MeasureFunctionBase<T, double> {
1245 typedef typename Image<T>::lineType lineType;
1249 virtual void initialize(
const Image<T> & )
1254 virtual void processSequence(lineType lineIn,
size_t size)
1256 for (
size_t i = 0; i < size; i++) {
1259 UINT nb = histo[val];
1264 virtual void finalize(
const Image<T> & )
1266 double entropy = 0.;
1270 typename map<T, UINT>::iterator it;
1271 for (it = histo.begin(); it != histo.end(); it++) {
1272 if (it->second > 0) {
1274 sumP += it->second * log2(it->second);
1278 entropy = log2(sumN) - sumP / sumN;
1280 this->retVal = entropy;
1299 ASSERT_ALLOCATED(&imIn);
1302 double entropy = 0.;
1306 map<T, UINT> hist =
histogram(imIn,
false);
1307 typename map<T, UINT>::iterator it;
1308 for (it = hist.begin(); it != hist.end(); it++) {
1309 if (it->second > 0) {
1310 sumP += it->second * log2(it->second);
1316 entropy = log2(sumN) - sumP / sumN;
1320 measEntropyFunc<T> func;
1321 return func(imIn,
false);
1340 ASSERT_ALLOCATED(&imIn, &imMask);
1341 ASSERT_SAME_SIZE(&imIn, &imMask);
1343 double entropy = 0.;
1347 map<T, UINT> hist =
histogram(imIn, imMask,
false);
1348 typename map<T, UINT>::iterator it;
1349 for (it = hist.begin(); it != hist.end(); it++) {
1350 if (it->second > 0) {
1351 sumP += it->second * log2(it->second);
1357 entropy = log2(sumN) - sumP / sumN;
1383 ASSERT(CHECK_ALLOCATED(&imIn), RES_ERR_BAD_ALLOCATION, offsets);
1385 typename Image<T>::lineType pixels = imIn.
getPixels();
1389 offsets.push_back(i);
1404 CHECK_ALLOCATED(&imIn);
1407 typename Image<T>::lineType pixels = imIn.
getPixels();
1413 h[pixels[i]] =
true;
1420 #pragma omp parallel for
1422 for (
size_t i = 0; i < imIn.
getPixelCount() && h.size() <= 2; i++) {
1423 h[pixels[i]] = True;
1427 return h[0] > 0 && h.size() == 2;
bool isAllocated() const
Check if the image is allocated.
Definition: DBaseImage.h:176
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:80
size_t getPixelCount() const
Get the number of pixels.
Definition: DBaseImage.h:160
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:85
Main Image class.
Definition: DImage.hpp:57
volType getSlices() const
Get an array containing the start offset of each slice.
Definition: DImage.hpp:117
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
Struct Point.
Definition: DCommon.h:125
RES_T sqrt(const Image< T1 > &imIn, Image< T2 > &imOut)
sqrt() - square root of an image
Definition: DImageArith.hpp:926
RES_T sub(const Image< T > &imIn1, const Image< T > &imIn2, Image< T > &imOut)
sub() - Subtraction between two images
Definition: DImageArith.hpp:160
vector< IntPoint > bresenhamPoints(int p1x, int p1y, int p2x, int p2y, int xMax=0, int yMax=0)
Find intermediate points forming a line between two end points, using the Bresenham Line Draw Algorit...
Definition: DImageDraw.h:62
histogram(const Image< T > &imIn, size_t *h)
Image histogram.
Definition: DImageHistogram.hpp:64
vector< T > rangeVal(const Image< T > &imIn, bool onlyNonZero=false)
rangeVal() - Min and Max values of an image
Definition: DMeasures.hpp:416
Vector_size_t nonZeroOffsets(Image< T > &imIn)
nonZeroOffsets() - Returns the offsets of pixels having non nul values.
Definition: DMeasures.hpp:1379
T modeVal(const Image< T > &imIn, bool onlyNonZero=true)
modeVal() - Get the mode of the histogram present in the image, i.e.
Definition: DMeasures.hpp:534
double vol(const Image< T > &imIn)
vol() - Volume of an image
Definition: DMeasures.hpp:129
double volume(const Image< T > &imIn)
colume() - Volume of an image
Definition: DMeasures.hpp:154
double measEntropy(const Image< T > &imIn, const Image< T > &imMask)
measEntropy() - Image entropy
Definition: DMeasures.hpp:1338
vector< T > valueList(const Image< T > &imIn, bool onlyNonZero=true)
valueList() - Get the list of the pixel values present in the image
Definition: DMeasures.hpp:468
vector< double > measCovariance(const Image< T > &imIn1, const Image< T > &imIn2, size_t dx, size_t dy, size_t dz, size_t maxSteps=0, bool centered=false, bool normalize=false)
measCovariance() - Centered covariance of two images in the direction defined by dx,...
Definition: DMeasures.hpp:1183
T maxVal(const Image< T > &imIn, Point< UINT > &pt, bool onlyNonZero=false)
maxVal() - Max value of an image
Definition: DMeasures.hpp:363
Vector_double measBarycenter(Image< T > &im)
measBarycenter() - Gets the barycenter coordinates of an image
Definition: DMeasures.hpp:705
vector< size_t > measBoundBox(Image< T > &im)
measBoundBox() - Bounding Box measure - gets the coordinates of the bounding box
Definition: DMeasures.hpp:779
Vector_double meanVal(const Image< T > &imIn, bool onlyNonZero=false)
meanVal() - Mean value and standard deviation
Definition: DMeasures.hpp:211
bool isBinary(const Image< T > &imIn)
isBinary() - Test if an image is binary.
Definition: DMeasures.hpp:1402
Vector_double measMoments(Image< T > &im, const bool onlyNonZero=true, const bool centered=false)
measMoments() - Measure image moments
Definition: DMeasures.hpp:931
T minVal(const Image< T > &imIn, Point< UINT > &pt, bool onlyNonZero=false)
minVal() - Min value of an image
Definition: DMeasures.hpp:286
T medianVal(const Image< T > &imIn, bool onlyNonZero=true)
medianVal() - Get the median of the image histogram.
Definition: DMeasures.hpp:610
size_t area(const Image< T > &imIn)
area() - Area of an image
Definition: DMeasures.hpp:91
vector< double > measAutoCovariance(const Image< T > &imIn, size_t dx, size_t dy, size_t dz, size_t maxSteps=0, bool centered=false, bool normalize=false)
measAutoCovariance() - Auto-covariance
Definition: DMeasures.hpp:1219
vector< T > profile(const Image< T > &im, size_t x0, size_t y0, size_t x1, size_t y1, size_t z=0)
profile() - Get image values along a line defined by the points and in the slice .
Definition: DMeasures.hpp:635