269 lines
8.1 KiB
C++
269 lines
8.1 KiB
C++
/************************************************************************
|
|
Blob.h
|
|
|
|
FUNCTIONALITY: Definition of the Blob class and some helper classes to perform
|
|
some calculations on it
|
|
AUTHOR: Inspecta S.L.
|
|
MODIFICATIONS (Modification, Author, Date):
|
|
|
|
**************************************************************************/
|
|
|
|
//! Disable warnings referred to 255 character truncation for the std:map
|
|
//#pragma warning(disable : 4786)
|
|
|
|
#ifndef CBLOB_INSPECTA_INCLUDED
|
|
#define CBLOB_INSPECTA_INCLUDED
|
|
|
|
class Blob;
|
|
#include "opencv2/core/core_c.h"
|
|
#include "opencv2/opencv.hpp"
|
|
#include "BlobLibraryConfiguration.h"
|
|
#include "BlobContour.h"
|
|
#include <deque>
|
|
#include <list>
|
|
|
|
|
|
#ifdef BLOB_OBJECT_FACTORY
|
|
//! Object factory pattern implementation
|
|
#include "..\inspecta\DesignPatterns\ObjectFactory.h"
|
|
#endif
|
|
|
|
//! Type of labelled images
|
|
typedef unsigned int LabelID;
|
|
typedef std::list<Blob*> BlobList;
|
|
typedef std::list<BlobContour*> BlobContourList;
|
|
|
|
enum AreaMode {GREEN, PIXELWISE};
|
|
|
|
//! Blob class
|
|
class Blob
|
|
{
|
|
friend class CompLabeler;
|
|
public:
|
|
Blob();
|
|
Blob(LabelID id, const cv::Point& startPoint, const cv::Size& originalImageSize);
|
|
~Blob();
|
|
|
|
//! Copy constructor
|
|
Blob(const Blob& src);
|
|
Blob(const Blob* src);
|
|
|
|
//! Assigment operator
|
|
Blob& operator=(const Blob& src);
|
|
|
|
//! Adds a new internal contour to the blob
|
|
void addInternalContour(const BlobContour& newContour);
|
|
|
|
//! Retrieves contour in Freeman's chain code
|
|
BlobContour* getExternalContour() {
|
|
return &m_externalContour;
|
|
}
|
|
|
|
BlobContourList& getInternalContours() {
|
|
return m_internalContours;
|
|
}
|
|
|
|
//! Bool to permit deletion with filter function
|
|
double m_toBeDeleted;
|
|
|
|
//! Get label ID
|
|
LabelID getID() {
|
|
return m_id;
|
|
}
|
|
|
|
void setID(LabelID newID) {
|
|
m_id = newID;
|
|
}
|
|
|
|
//! > 0 for external blobs, 0 if not
|
|
int exterior(IplImage* mask, bool xBorder = true, bool yBorder = true);
|
|
|
|
//! opencv2 Interface
|
|
int exterior(const cv::Mat& mask, bool xBorder = true, bool yBorder = true);
|
|
|
|
//! Computes the area of the blob.
|
|
//! areaCompMode defines which way to compute the areas:
|
|
//! - Using green's formula (not exact result, probably faster)
|
|
//! - Counting the pixels (probably slower)
|
|
double area(AreaMode areaCompMode = GREEN);
|
|
|
|
//! Compute blob's perimeter
|
|
double perimeter();
|
|
|
|
//! Compute blob's moment (p,q up to MAX_CALCULATED_MOMENTS)
|
|
//! if intContours = false, internal contours do not count for moment computation (i.e. the blob is considered without holes).
|
|
double moment(int p, int q, bool intContours = true);
|
|
|
|
//! Compute external perimeter
|
|
double externalPerimeter(IplImage* mask, bool xBorder = true, bool yBorder = true);
|
|
|
|
//! opencv2 interface
|
|
double externalPerimeter(const cv::Mat& mask, bool xBorder = true, bool yBorder = true);
|
|
|
|
//! Get mean grey color
|
|
//(Warning: use meanStdDev for simultaneous computation of mean and std. dev, and for RGB images).
|
|
double mean(IplImage *image);
|
|
|
|
//! opencv2 interface
|
|
//(Warning: use meanStdDev for simultaneous computation of mean and std. dev, and for RGB images).
|
|
double mean(const cv::Mat& image);
|
|
|
|
//! Get standard deviation grey color
|
|
//(Warning: use meanStdDev for simultaneous computation of mean and std. dev, and for RGB images).
|
|
double stdDev(IplImage *image);
|
|
|
|
//! opencv2 interface
|
|
//(Warning: use meanStdDev for simultaneous computation of mean and std. dev, and for RGB images).
|
|
double stdDev(const cv::Mat& image);
|
|
|
|
//! Computes mean and standard deviation of image, which can be in any opencv format
|
|
//! Since mean and standard deviation are computed with the same function call, this results quicker than
|
|
//! calling separately mean and standard deviation.
|
|
void meanStdDev(const cv::Mat& image, cv::Scalar& mean, cv::Scalar& stddev);
|
|
|
|
//void meanStdDev(Mat image, double *mean, double *stddev);
|
|
|
|
//! Shows if the blob has associated information
|
|
bool isEmpty();
|
|
|
|
//! Calculates the convex hull of the blob
|
|
void getConvexHull(Contours& hull);
|
|
|
|
//! Paints the blob in an image
|
|
//! intContours - determines wheter to draw the holes of the blob (true) or not (false)
|
|
//! srcImage - image from where to copy the holes contents. If unassigned and intContours is true, the internal pixels will be set to black.
|
|
void fillBlob(IplImage *image, cv::Scalar color, int offsetX = 0, int offsetY = 0, bool intContours = false, const IplImage* srcImage = NULL);
|
|
|
|
void fillBlob(const cv::Mat& image, cv::Scalar color, int offsetX = 0, int offsetY = 0, bool intContours = false, const cv::Mat& srcImage = cv::Mat());
|
|
|
|
//! Joins a blob to current one
|
|
//! NOTE: All the data is copied, a new blob is created and joined to the caller one.
|
|
void joinBlob(Blob* blob);
|
|
|
|
//! Get bounding box
|
|
cv::Rect getBoundingBox();
|
|
|
|
//! Get bounding ellipse
|
|
cv::RotatedRect getEllipse();
|
|
|
|
//! Minimun X
|
|
double minX() {
|
|
return getBoundingBox().x;
|
|
}
|
|
|
|
//! Minimun Y
|
|
double minY() {
|
|
return getBoundingBox().y;
|
|
}
|
|
|
|
//! Maximun X
|
|
double maxX() {
|
|
return getBoundingBox().x + getBoundingBox().width;
|
|
}
|
|
|
|
//! Maximun Y
|
|
double maxY() {
|
|
return getBoundingBox().y + getBoundingBox().height;
|
|
}
|
|
|
|
/**
|
|
Computes extremes for the contour (i.e. 4 points, respectively with max X, max Y, min X, minY)
|
|
In case of perfect rectangular shapes, the code will return the vertexes in counterclockwise order.
|
|
TODO: Extend function to joined blobs
|
|
*/
|
|
void getExtremes(cv::Point& xmax, cv::Point& xmin, cv::Point& ymax, cv::Point& ymin);
|
|
|
|
|
|
//! Shifts the blob by (x,y)
|
|
void shiftBlob(int x, int y);
|
|
|
|
//! Returns the number of overlapping pixels between the caller blob and blob.
|
|
//! A preliminary check is performed with respect to the bounding boxes in order to avoid unnecessary computations
|
|
int overlappingPixels(Blob* blob);
|
|
|
|
//! Computes the density of the blob, i.e. the ratio (blob Area) / (ConvexHullArea)
|
|
//! areaCalculationMode defines which way to compute the areas:
|
|
//! - Using green's formula (not exact result, probably faster)
|
|
//! - Counting the pixels
|
|
double density(AreaMode areaCalculationMode);
|
|
|
|
//! Returns blob center in pixels (integers).
|
|
cv::Point getCenter();
|
|
|
|
//! Return blob centroid
|
|
cv::Point2f getCentroid(bool useInternalContours);
|
|
|
|
/*
|
|
* Border: 0 = top, 1 = right, 2 = bottom, 3 = left
|
|
*/
|
|
/*Contours getPointsTouchingBorder(int border);*/
|
|
|
|
//! For joined blobs, return the number of sub-blobs.
|
|
int getNumJoinedBlobs();
|
|
|
|
cv::Size originalImageSize() const { return m_originalImageSize; }
|
|
|
|
void originalImageSize(int width, int height) { m_originalImageSize.width = width; m_originalImageSize.height = height; }
|
|
|
|
private:
|
|
void requestDeletion(Blob* blob);
|
|
|
|
//! Deallocates all contours
|
|
void clearContours();
|
|
|
|
private:
|
|
//! Just for multithread joining routine;
|
|
bool m_startPassed;
|
|
|
|
bool m_isJoined;
|
|
|
|
BlobList m_joinedBlobs;
|
|
|
|
Blob* m_deleteRequestOwnerBlob;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Blob contours
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//! External contour of the blob (crack codes)
|
|
BlobContour m_externalContour;
|
|
|
|
//! Internal contours (crack codes)
|
|
BlobContourList m_internalContours;
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// Blob features
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
//! Label number
|
|
LabelID m_id;
|
|
|
|
//! Area
|
|
double m_area;
|
|
|
|
//! Perimeter
|
|
double m_perimeter;
|
|
|
|
//! external perimeter from blob
|
|
double m_externalPerimeter;
|
|
|
|
//! mean gray color
|
|
double m_meanGray;
|
|
|
|
//! Standard deviation from gray color blob distribution
|
|
double m_stdDevGray;
|
|
|
|
//! Bounding box
|
|
cv::Rect m_boundingBox;
|
|
|
|
//! Bounding ellipse
|
|
cv::RotatedRect m_ellipse;
|
|
|
|
//! Sizes from image where blob is extracted
|
|
cv::Size m_originalImageSize;
|
|
|
|
friend class BlobGroup;
|
|
};
|
|
|
|
#endif //CBLOB_INSPECTA_INCLUDED
|