2 #include "BlobDetectorCCA.hh"
3 #include "Base/Image/ImageConvert.hh"
27 if (left.size()>right.size())
return true;
30 bool operator()(
const std::vector<unsigned int> &left,
31 const std::vector<unsigned int> &right)
const {
32 if (left.size()>right.size())
return true;
41 template <
class StorageType>
49 template <
class StorageType>
55 template <
class StorageType>
int
58 std::vector<BIAS::BIASBlob>& blobs){
61 ret = Process_(image,fPercent_, bNeighborHood4_);
62 std::vector<BIAS::Vector2<double> > centroids;
63 GetCentroids(centroids);
66 for(
unsigned int i=0;i<centroids.size();i++){
67 blob.
UL[0] = (double)TopLefts_[i][0];
68 blob.
UL[1] = (double)TopLefts_[i][1];
69 blob.
LR[0] = (double)BotRights_[i][0];
70 blob.
LR[1] = (double)BotRights_[i][1];
73 blobs.push_back(blob);
79 template <
class StorageType>
void
87 template <
class StorageType>
int
93 unsigned int pixelAllowed= (
unsigned int)((
float)img.
GetPixelCount()
94 * (percent / 100.0) + 0.5);
97 BIASERR(
"Filter::CCA() only implemented for grey images");
103 int count=Label4Neighbour_();
106 BIASERR(
"WARNING: CCA: 255 blobs found, there are probably more."<<
107 "If so, CCA did not work correctly, "<<
108 "make sure there are less regions!");
110 BIASCDOUT(D_LABEL,
"found "<<count<<
" blobs");
115 LABEL_CALC_TYPE **ida=LabelResultImage_.GetImageDataArray();
117 width=LabelResultImage_.GetWidth();
118 height=LabelResultImage_.GetHeight();
120 BlobCount_.push_back(0);
124 BlobCount_.resize(count);
125 TopLefts_.resize(count);
126 BotRights_.resize(count);
127 SortVec_.resize(count);
128 allBlobs_.resize(count);
131 for (
int ii=0; ii<count; ii++){
133 SortVec_[ii].tl.Set(width, height);
134 SortVec_[ii].br.Set(0, 0);
139 LABEL_CALC_TYPE c=0, i=0;
141 for (
int y=0; y<height; y++) {
142 for (
int x=0; x<width; x++) {
145 while ((
unsigned int)i<Num_.size() && Num_[i]!=c) i++;
146 if ((
unsigned int)i==Num_.size()) Num_.push_back(c);
148 if (SortVec_[i].tl[0]>x) SortVec_[i].tl[0]=x;
149 if (SortVec_[i].tl[1]>y) SortVec_[i].tl[1]=y;
150 if (SortVec_[i].br[0]<x) SortVec_[i].br[0]=x;
151 if (SortVec_[i].br[1]<y) SortVec_[i].br[1]=y;
155 sort(SortVec_.begin(), SortVec_.end());
156 for (
int ii=0; ii<count; ii++) {
157 BlobCount_[ii]=SortVec_[ii].bc;
158 TopLefts_[ii]=SortVec_[ii].tl;
159 BotRights_[ii]=SortVec_[ii].br;
164 sort(allBlobs_.begin(), allBlobs_.end(), Compare());
167 for (
unsigned int r=2;r<allBlobs_.size();r++)
168 for (
unsigned int p=0;p<allBlobs_[r].size();p++)
169 data[allBlobs_[r][p][1]][allBlobs_[r][p][0]]=0;
171 for (
unsigned int r=0;r<allBlobs_.size();r++)
172 if ((
unsigned int)(BlobCount_[r])<pixelAllowed)
173 for (
unsigned int p=0;p<allBlobs_[r].size();p++)
174 data[allBlobs_[r][p][1]][allBlobs_[r][p][0]]=0;
180 template <
class StorageType>
int
185 BIASERR(
"8 neighborhood not yet implemented");
191 template <
class StorageType>
int
195 if (allBlobs_.size()<1) {
199 for (
unsigned int r=0;r<allBlobs_.size();r++) {
200 center[0]=0; center[1]=0;
201 for (
unsigned int i=0;i<allBlobs_[r].size();i++) {
202 center[0]+= allBlobs_[r][i][0];
203 center[1]+= allBlobs_[r][i][1];
205 center[0]/=(double)(allBlobs_[r].size());
206 center[1]/=(double)(allBlobs_[r].size());
207 centroids.push_back(center);
212 template <
class StorageType>
int
217 if (allBlobs_.size()<1) {
220 std::vector<unsigned int> xValues, yValues;
221 xValues.reserve(allBlobs_[0].size());
222 yValues.reserve(allBlobs_[0].size());
225 for (
unsigned int r=0;r<allBlobs_.size();r++) {
226 xValues.clear(); yValues.clear();
227 for (
unsigned int i=0;i<allBlobs_[r].size();i++) {
228 xValues.push_back( allBlobs_[r][i][0]);
229 yValues.push_back( allBlobs_[r][i][1]);
231 sort(xValues.begin(), xValues.end());
232 center[0]=xValues[xValues.size() / 2];
233 center[1]=yValues[yValues.size() / 2];
234 medians.push_back(center);
248 #ifdef BUILD_IMAGE_INT
251 #ifdef BUILD_IMAGE_CHAR
254 #ifdef BUILD_IMAGE_SHORT
256 #ifdef BUILD_IMAGE_USHORT
259 #ifdef BUILD_IMAGE_UINT
261 #ifdef BUILD_IMAGE_DOUBLE
void LabelInit_(const ImageBase &Image)
int GetCentroids(std::vector< BIAS::Vector2< double > > ¢roids)
call this afer Process() to get the centroids of all regions.
int Detect(Image< StorageType > &image, std::vector< BIAS::BIASBlob > &blobs)
Does a Connected Component Analyis (4-neighborhood) and deletes all regions, whose sizes are smaller ...
BIAS::Vector2< double > LR
int GetMedians(std::vector< BIAS::Vector2< unsigned int > > &medians)
call this afer Process() to get the medians of all regions.
Helper class to store blob corners.
int Process_(BIAS::Image< StorageType > &img, float percent, bool neighborHood4=true)
void Init_(const BIAS::Image< StorageType > &img)
init is called before processing the first image
static int ConvertST(const BIAS::ImageBase &source, BIAS::ImageBase &dest, ImageBase::EStorageType targetST)
Function to convert the storage type of images e.g.
BIAS::Vector2< double > centerofmass
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
The image template class for specific storage types.
BIAS::Vector2< double > UL
unsigned long int GetPixelCount() const
returns number of pixels in image
virtual ~BlobDetectorCCA()
int Process8_(BIAS::Image< StorageType > &img, float percent)
Does a Connected Component Analyis and gives information about regions in an image, like centroid and bounding boxes.
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase