KSquare Utilities
Blob.cpp
Go to the documentation of this file.
1 /* Blob.cpp -- Works with Raster class to track individual connected component in Raster.
2  * Copyright (C) 1994-2011 Kurt Kramer
3  * For conditions of distribution and use, see copyright notice in KKB.h
4  */
5 
6 #include "FirstIncludes.h"
7 #include <stdlib.h>
8 #include <iostream>
9 #include <map>
10 #include <vector>
11 
12 #include "MemoryDebug.h"
13 using namespace std;
14 
15 #include "BitString.h"
16 #include "Blob.h"
17 using namespace KKB;
18 
19 
20 
21 
22 Blob::Blob (kkint32 _id):
23  colLeft (0),
24  colRight (0),
25  id (_id),
26  pixelCount (0),
27  rowBot (0),
28  rowTop (0)
29 
30 {
31 }
32 
33 
34 
35 Blob::~Blob ()
36 {
37 }
38 
39 
40 
42 {
43  colLeft = 0;
44  colRight = 0;
45  id = _id;
46  pixelCount = 0;
47  rowBot = 0;
48  rowTop = 0;
49 }
50 
51 
52 
54 {
55  const_iterator idx;
56  idx = find (blobId);
57  if (idx == end ())
58  return NULL;
59  return idx->second;
60 } /* LookUpByBlobId */
61 
62 
63 
64 BlobList::BlobList (bool _owner):
65  availableBlobs (),
66  nextBlobId (0)
67 {
68 }
69 
70 
71 
73 {
74  while (availableBlobs.size () > 0)
75  {
76  BlobPtr b = availableBlobs.back ();
77  availableBlobs.pop_back ();
78 
79  delete b;
80  }
81 
82  iterator idx2;
83  iterator endIdx = end ();
84  for (idx2 = begin (); idx2 != endIdx; ++idx2)
85  {
86  BlobPtr b = idx2->second;
87  delete b;
88  }
89 }
90 
91 
92 
94  kkuint32 colLeft
95  )
96 {
97  BlobPtr blob = NULL;
98  if (availableBlobs.size () > 0)
99  {
100  blob = availableBlobs.back ();
101  blob->InitialzieAsNew (nextBlobId);
102  availableBlobs.pop_back ();
103  }
104  else
105  {
106  blob = new Blob (nextBlobId);
107  }
108 
109  blob->rowTop = rowTop;
110  blob->rowBot = rowTop;
111 
112  blob->colLeft = colLeft;
113  blob->colRight = colLeft;
114 
115  nextBlobId++;
116  PushOnBack (blob);
117  return blob;
118 }
119 
120 
121 
123  kkint32 blobId,
124  kkint32** blobIds
125  )
126 {
127  kkint32 newId = blob->Id ();
128 
129  iterator idx;
130  idx = find (blobId);
131  if (idx == end ())
132  return;
133  BlobPtr blobToMerge = idx->second;
134 
135  kkint32 col;
136  kkint32 row;
137 
138  kkint32 rowBot = blobToMerge->rowBot;
139  kkint32 colRight = blobToMerge->colRight;
140 
141  for (row = blobToMerge->rowTop; row <= rowBot; row++)
142  {
143  for (col = blobToMerge->colLeft; col <= colRight; col++)
144  {
145  if (blobIds[row][col] == blobId)
146  blobIds[row][col] = newId;
147  }
148  }
149 
150  blob->rowTop = Min (blob->rowTop, blobToMerge->rowTop);
151  blob->rowBot = Max (blob->rowBot, blobToMerge->rowBot);
152  blob->colLeft = Min (blob->colLeft, blobToMerge->colLeft);
153  blob->colRight = Max (blob->colRight, blobToMerge->colRight);
154  blob->pixelCount = blob->pixelCount + blobToMerge->pixelCount;
155 
156  erase (idx);
157  availableBlobs.push_back (blobToMerge);
158 } /* MergeBlobIds */
159 
160 
161 
162 
164  kkint32 blob2Id,
165  kkint32** blobIds
166  )
167 {
168  kkint32 blob1Id = blob1->Id ();
169  iterator idx;
170  idx = find (blob2Id);
171  if (idx == end ())
172  return blob1;
173  BlobPtr blob2 = idx->second;
174 
175  if ((blob1Id == blob2Id) || (blob1 == blob2))
176  {
177  return blob1;
178  }
179 
180  BlobPtr srcBlob = NULL;
181  BlobPtr destBlob = NULL;
182 
183  if (blob1->PixelCount () > blob2->PixelCount ())
184  {
185  srcBlob = blob2;
186  destBlob = blob1;
187  }
188  else
189  {
190  srcBlob = blob1;
191  destBlob = blob2;
192  }
193 
194  kkint32 destBlobId = destBlob->Id ();
195  kkint32 srcBlobId = srcBlob->Id ();
196 
197  kkint32 col = 0;
198  kkint32 row = 0;
199 
200  kkint32 rowBot = srcBlob->rowBot;
201  kkint32 colRight = srcBlob->colRight;
202 
203  for (row = srcBlob->rowTop; row <= rowBot; ++row)
204  {
205  for (col = srcBlob->colLeft; col <= colRight; ++col)
206  {
207  if (blobIds[row][col] == srcBlobId)
208  blobIds[row][col] = destBlobId;
209  }
210  }
211 
212  destBlob->rowTop = Min (destBlob->rowTop, srcBlob->rowTop);
213  destBlob->rowBot = Max (destBlob->rowBot, srcBlob->rowBot);
214  destBlob->colLeft = Min (destBlob->colLeft, srcBlob->colLeft);
215  destBlob->colRight = Max (destBlob->colRight, srcBlob->colRight);
216  destBlob->pixelCount = destBlob->pixelCount + srcBlob->pixelCount;
217 
218  idx = find (srcBlobId);
219  if (idx != end ())
220  erase (idx);
221 
222  availableBlobs.push_back (srcBlob);
223  return destBlob;
224 } /* MergeIntoSingleBlob */
225 
226 
227 
228 
229 
231 {
232  BlobPtr blob = NULL;
233  BlobPtr tempBlob = NULL;
234  kkint32 largestSize = 0;
235 
236  const_iterator idx;
237  const_iterator endIdx = end ();
238 
239  for (idx = begin (); idx != endIdx; ++idx)
240  {
241  tempBlob = idx->second;
242  if (tempBlob->pixelCount > largestSize)
243  {
244  largestSize = tempBlob->pixelCount;
245  blob = tempBlob;
246  }
247  }
248  return blob;
249 } /* LocateLargestBlob */
250 
251 
252 
254 {
255  BlobPtr blob = NULL;
256  BlobPtr tempBlob = NULL;
257  kkint32 largestSize = 0;
258 
259  const_iterator idx;
260  const_iterator endIdx = end ();
261 
262  for (idx = begin (); idx != endIdx; ++idx)
263  {
264  tempBlob = idx->second;
265  kkint32 size = tempBlob->Height () * tempBlob->Width ();
266  if (size > largestSize)
267  {
268  largestSize = size;
269  blob = tempBlob;
270  }
271  }
272  return blob;
273 } /* LocateMostComplete */
274 
275 
276 
277 
278 
279 
281 {
282  insert (BlobIndexPair (blob->Id (), blob));
283 } /* PushOnBack */
284 
285 
286 
288 {
289  insert (BlobIndexPair (blob->Id (), blob));
290 }
Blob(kkint32 _id)
Definition: Blob.cpp:22
BlobPtr LocateMostComplete()
Locates the blob that covers the greatest part of the raster; that is the one who has the largest (He...
Definition: Blob.cpp:253
__int32 kkint32
Definition: KKBaseTypes.h:88
Used by the Raster object to identify a distinct blob; where it is in the raster and its unique id...
Definition: Blob.h:32
kkint32 Width()
Number of columns that this blob occupies.
Definition: Blob.h:54
kkint32 colLeft
Definition: Blob.h:61
kkint32 rowBot
Definition: Blob.h:65
Blob * BlobPtr
Definition: Blob.h:70
BlobPtr NewBlob(kkuint32 rowTop, kkuint32 colLeft)
Definition: Blob.cpp:93
unsigned __int32 kkuint32
Definition: KKBaseTypes.h:89
kkint32 Height()
Number of rows that the blob occupies.
Definition: Blob.h:49
KKTHread * KKTHreadPtr
~Blob()
Definition: Blob.cpp:35
kkint32 rowTop
Definition: Blob.h:66
void PushOnBack(BlobPtr blob)
Definition: Blob.cpp:280
void MergeBlobIds(BlobPtr blob, kkint32 blobId, kkint32 **blobIds)
Used by the Connected component analysis to merge two blobs together.
Definition: Blob.cpp:122
Maintains a list of blobs.
Definition: Blob.h:77
BlobPtr LocateLargestBlob()
Will return Blob with largest pixel count.
Definition: Blob.cpp:230
kkint32 pixelCount
Definition: Blob.h:64
kkint32 PixelCount()
Number of pixels that are part of this blob.
Definition: Blob.h:56
BlobPtr LookUpByBlobId(kkint32 blobId)
Will return pointer to blob with &#39;blobId&#39;; if not found will return NULL.
Definition: Blob.cpp:53
kkint32 Id()
The unique ID assigned to this blob.
Definition: Blob.h:44
kkint32 colRight
Definition: Blob.h:62
void InitialzieAsNew(kkint32 _id)
Definition: Blob.cpp:41
BlobList(bool _owner)
Definition: Blob.cpp:64
BlobPtr MergeIntoSingleBlob(BlobPtr blob1, kkint32 blob2Id, kkint32 **blobIds)
Definition: Blob.cpp:163
void PushOnFront(BlobPtr blob)
Definition: Blob.cpp:287
kkint32 id
Definition: Blob.h:63