nim_duilib/examples/contour/blob/BlobOperators.h
2025-03-16 16:42:44 +08:00

732 lines
15 KiB
C++

/**************************************************************************
Definition of classes to perform operations on blobs
Helper classes to perform operations on blobs
**************************************************************************/
#ifndef BLOB_OPERATORS_H_INCLUDED
#define BLOB_OPERATORS_H_INCLUDED
#include "blob.h"
//! Degree to radian conversion factor
#define DEGREE2RAD (CV_PI / 180.0)
//! Interface to derive all blob operations
class OperatorBlob
{
public:
virtual ~OperatorBlob() {};
//! Apply operator to blob
virtual double operator()(Blob& blob) = 0;
//! Get operator name
virtual const char *name() = 0;
operator OperatorBlob*()
{
return (OperatorBlob*)this;
}
};
typedef OperatorBlob BlobOperator;
#ifdef BLOB_OBJECT_FACTORY
/**
Function to compare two identifiers within the COperadorBlobs factory
*/
struct functorComparacioIdOperador
{
bool operator()(const char* s1, const char* s2) const
{
return strcmp(s1, s2) < 0;
}
};
//! Definition of Object factory type for OperatorBlob objects
typedef ObjectFactory<OperatorBlob, const char *, functorComparacioIdOperador > t_OperadorBlobFactory;
//! Global function to register all operators defined in blob.h
void RegistraTotsOperadors(t_OperadorBlobFactory &fabricaOperadorsBlob);
#endif
//! Class to get ID of a blob
class BlobGetID : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.getID();
}
const char *name()
{
return "BlobGetID";
}
};
//! Class to get bool m_toBeDeleted
class BlobGetTBDeleted : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.m_toBeDeleted;
}
const char *name()
{
return "BlobGetTBDeleted";
}
};
//! Class to get the area of a blob
class BlobGetArea : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.area();
}
const char *name()
{
return "BlobGetArea";
}
};
//! Class to get the perimeter of a blob
class BlobGetPerimeter : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.perimeter();
}
const char *name()
{
return "BlobGetPerimeter";
}
};
//! Class to get the external flag of a blob
class BlobGetExterior : public OperatorBlob
{
public:
BlobGetExterior()
{
m_mask = NULL;
m_xBorder = true;
m_yBorder = true;
}
BlobGetExterior(IplImage* mask, bool xBorder = true, bool yBorder = true)
{
m_mask = mask;
m_xBorder = xBorder;
m_yBorder = yBorder;
}
double operator()(Blob& blob)
{
return blob.exterior(m_mask, m_xBorder, m_yBorder);
}
const char *name()
{
return "BlobGetExterior";
}
private:
IplImage* m_mask;
bool m_xBorder, m_yBorder;
};
//! Class to get the mean grey level of a blob
class BlobGetMean : public OperatorBlob
{
public:
BlobGetMean()
{
m_image = NULL;
}
BlobGetMean(IplImage* image)
{
m_image = image;
};
double operator()(Blob& blob)
{
return blob.mean(m_image);
}
const char *name()
{
return "BlobGetMean";
}
private:
IplImage* m_image;
};
//! Class to get the standard deviation of the grey level values of a blob
class BlobGetStdDev : public OperatorBlob
{
public:
BlobGetStdDev()
{
m_image = NULL;
}
BlobGetStdDev(IplImage* image)
{
m_image = image;
};
double operator()(Blob& blob)
{
return blob.stdDev(m_image);
}
const char *name()
{
return "BlobGetStdDev";
}
private:
IplImage* m_image;
};
//! Class to calculate the compactness of a blob
class BlobGetCompactness : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetCompactness";
}
};
//! Class to calculate the length of a blob
class BlobGetLength : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetLength";
}
};
//! Class to calculate the breadth of a blob
class BlobGetBreadth : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetBreadth";
}
};
//! Class to calculate the difference in X of the blob
class CBlobGetDiffX : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.getBoundingBox().width;
}
const char *name()
{
return "CBlobGetDiffX";
}
};
//! Class to calculate the difference in X of the blob
class BlobGetDiffY : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.getBoundingBox().height;
}
const char *name()
{
return "BlobGetDiffY";
}
};
//! Class to calculate the P, Q moment of a blob
class BlobGetMoment : public OperatorBlob
{
public:
//! Standard constructor (gets the 00 moment)
BlobGetMoment()
{
m_p = m_q = 0;
}
//! Constructor: gets the P, Q moment
BlobGetMoment(int p, int q)
{
m_p = p;
m_q = q;
};
double operator()(Blob& blob);
const char *name()
{
return "BlobGetMoment";
}
private:
//! moment que volem calcular
int m_p, m_q;
};
//! Class to calculate the convex hull perimeter of a blob
class BlobGetHullPerimeter : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetHullPerimeter";
}
};
//! Class to calculate the convex hull area of a blob
class BlobGetHullArea : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetHullArea";
}
};
//! Class to calculate the minimum x on the minimum y
class BlobGetMinXatMinY : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetMinXatMinY";
}
};
//! Class to calculate the minimum y on the maximum x
class BlobGetMinYatMaxX : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetMinYatMaxX";
}
};
//! Class to calculate the maximum x on the maximum y
class BlobGetMaxXatMaxY : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetMaxXatMaxY";
}
};
//! Class to calculate the maximum y on the minimum y
class BlobGetMaxYatMinX : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetMaxYatMinX";
}
};
//! Class to get the minimum x
class BlobGetMinX : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.minX();
}
const char *name()
{
return "BlobGetMinX";
}
};
//! Class to get the maximum x
class BlobGetMaxX : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.maxX();
}
const char *name()
{
return "BlobGetMaxX";
}
};
//! Class to get the minimum y
class BlobGetMinY : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.minY();
}
const char *name()
{
return "BlobGetMinY";
}
};
//! Class to get the maximum y
class BlobGetMaxY : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.maxY();
}
const char *name()
{
return "BlobGetMaxY";
}
};
//! Class to calculate the elongation of the blob
class BlobGetElongation : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetElongation";
}
};
//! Class to calculate the roughness of the blob
class BlobGetRoughness : public OperatorBlob
{
public:
double operator()(Blob& blob);
const char *name()
{
return "BlobGetRoughness";
}
};
//! Class to calculate the euclidean distance between the center of a blob and a given point
class BlobGetDistanceFromPoint : public OperatorBlob
{
public:
//! Standard constructor (distance to point 0,0)
BlobGetDistanceFromPoint()
{
m_x = m_y = 0.0;
}
//! Constructor (distance to point x,y)
BlobGetDistanceFromPoint(const double x, const double y)
{
m_x = x;
m_y = y;
}
double operator()(Blob& blob);
const char *name()
{
return "BlobGetDistanceFromPoint";
}
private:
// coordinates of the point where we want to calculate the distance
double m_x, m_y;
};
//! Class to get the number of external pixels of a blob
class BlobGetExternalPerimeter : public OperatorBlob
{
public:
BlobGetExternalPerimeter()
{
m_mask = NULL;
m_xBorder = true;
m_yBorder = true;
}
BlobGetExternalPerimeter(IplImage* mask, bool xBorder = true, bool yBorder = true)
{
m_mask = mask;
m_xBorder = xBorder;
m_yBorder = yBorder;
}
double operator()(Blob& blob)
{
return blob.externalPerimeter(m_mask, m_xBorder, m_yBorder);
}
const char *name()
{
return "BlobGetExternalPerimeter";
}
private:
IplImage* m_mask;
bool m_xBorder, m_yBorder;
};
//! Class to calculate the ratio between the perimeter and number of external pixels
//! values close to 0 indicate that most of the blob is internal
//! values close to 1 indicate that most of the blob is external
//! Class to calculate the ratio between the perimeter and the number of external pixels
class BlobGetExternalPerimeterRatio : public OperatorBlob
{
public:
BlobGetExternalPerimeterRatio()
{
m_mask = NULL;
m_xBorder = false;
m_yBorder = false;
}
BlobGetExternalPerimeterRatio(IplImage* mask, bool xBorder = true, bool yBorder = true)
{
m_mask = mask;
m_xBorder = xBorder;
m_yBorder = yBorder;
}
double operator()(Blob& blob)
{
if (blob.perimeter() != 0) {
return blob.externalPerimeter(m_mask, m_xBorder, m_yBorder) / blob.perimeter();
}
else {
return blob.externalPerimeter(m_mask, m_xBorder, m_yBorder);
}
}
const char *name()
{
return "BlobGetExternalPerimeterRatio";
}
private:
IplImage* m_mask;
bool m_xBorder, m_yBorder;
};
//! Class to calculate the ratio between the convex perimeter and the number of external pixels
//! values close to 0 indicate that most of the blob is internal blob
//! values close to 1 indicate that most of the blob is external
//! Class to calculate the ratio between the perimeter and the number of external pixels
class BlobGetExternalHullPerimeterRatio : public OperatorBlob
{
public:
BlobGetExternalHullPerimeterRatio()
{
m_mask = NULL;
m_xBorder = false;
m_yBorder = false;
}
BlobGetExternalHullPerimeterRatio(IplImage* mask, bool xBorder = true, bool yBorder = true)
{
m_mask = mask;
m_xBorder = xBorder;
m_yBorder = yBorder;
}
double operator()(Blob& blob)
{
BlobGetHullPerimeter getHullPerimeter;
double hullPerimeter;
if ((hullPerimeter = getHullPerimeter(blob)) != 0) {
return blob.externalPerimeter(m_mask, m_xBorder, m_yBorder) / hullPerimeter;
}
else {
return blob.externalPerimeter(m_mask, m_xBorder, m_yBorder);
}
}
const char *name()
{
return "BlobGetExternalHullPerimeterRatio";
}
private:
IplImage* m_mask;
bool m_xBorder, m_yBorder;
};
//! Class to calculate the center in the X direction
class BlobGetXCenter : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.minX() + ((blob.maxX() - blob.minX()) / 2.0);
}
const char *name()
{
return "BlobGetXCenter";
}
};
//! Class to calculate the center in the Y direction
class BlobGetYCenter : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
return blob.minY() + ((blob.maxY() - blob.minY()) / 2.0);
}
const char *name()
{
return "BlobGetYCenter";
}
};
//! Class to calculate the length of the major axis of the ellipse that fits the blob edges
class BlobGetMajorAxisLength : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
cv::RotatedRect elipse = blob.getEllipse();
return elipse.size.width;
}
const char *name()
{
return "BlobGetMajorAxisLength";
}
};
//! Class to calculate the ratio between the area of the ellipse and that of the spot
class BlobGetAreaElipseRatio : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
if (blob.area() == 0.0) { return 0.0; }
cv::RotatedRect elipse = blob.getEllipse();
double ratioAreaElipseAreaTaca = ((elipse.size.width/2.0) * (elipse.size.height/2.0) * CV_PI) / blob.area();
return ratioAreaElipseAreaTaca;
}
const char *name()
{
return "BlobGetAreaElipseRatio";
}
};
//! Class to calculate the length of the minor axis of the ellipse that fits the blob edges
class BlobGetMinorAxisLength : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
cv::RotatedRect elipse = blob.getEllipse();
return elipse.size.height;
}
const char *name()
{
return "BlobGetMinorAxisLength";
}
};
//! Class to calculate the orientation of the ellipse that fits the blob edges in radians
class BlobGetOrientation : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
cv::RotatedRect elipse = blob.getEllipse();
/*
if (elipse.angle > 180.0)
return ((elipse.angle - 180.0)* DEGREE2RAD);
else
return (elipse.angle * DEGREE2RAD);
*/
return elipse.angle;
}
const char *name()
{
return "BlobGetOrientation";
}
};
//! Class to calculate the cosinus of the orientation of the ellipse that fits the blob edges
class BlobGetOrientationCos : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
BlobGetOrientation getOrientation;
return fabs(cos(getOrientation(blob)*DEGREE2RAD));
}
const char *name()
{
return "BlobGetOrientationCos";
}
};
//! Class to calculate the ratio between both axes of the ellipse
class BlobGetAxisRatio : public OperatorBlob
{
public:
double operator()(Blob& blob)
{
double major,minor;
BlobGetMajorAxisLength getMajor;
BlobGetMinorAxisLength getMinor;
major = getMajor(blob);
minor = getMinor(blob);
if (major != 0) {
return minor / major;
}
else {
return 0;
}
}
const char *name()
{
return "BlobGetAxisRatio";
}
};
//! Class to calculate whether a point is inside a blob
class BlobGetXYInside : public OperatorBlob
{
public:
//! Standard constructor
BlobGetXYInside()
{
m_p.x = 0;
m_p.y = 0;
}
//! Constructor: sets the point
BlobGetXYInside(cv::Point2f p)
{
m_p = p;
};
double operator()(Blob& blob);
const char *name()
{
return "BlobGetXYInside";
}
private:
//! point to be considered
cv::Point2f m_p;
};
#endif //!BLOB_OPERATORS_H_INCLUDED