1 #ifndef __FAST_AREA_OPENIN_PIXEL_QUEUE_T_HPP__
2 #define __FAST_AREA_OPENIN_PIXEL_QUEUE_T_HPP__
4 #include "Core/include/DCore.h"
21 #define MAXGREYVAL 256
30 typedef greyval **GImage;
41 void InitPixelHeap(
PixelHeap *p_heap,
int lambda)
43 p_heap->heap = (
long *) malloc((lambda + 1) *
sizeof(long));
45 p_heap->HeapMax = lambda;
48 void ExitPixelHeap(PixelHeap *p_heap)
54 void InsertInPixelHeap(PixelHeap *p_heap, greyval *im,
long pixel)
56 long child, parent, gval = im[pixel];
59 p_heap->heap[child] = pixel;
60 while ((parent = (child >> 1)) && (im[p_heap->heap[parent]] > gval)) {
61 p_heap->heap[child] = p_heap->heap[parent];
64 p_heap->heap[child] = pixel;
67 int RemoveFromPixelHeap(PixelHeap *p_heap, greyval *im)
69 long pixel = p_heap->heap[p_heap->N--], temp = p_heap->heap[1],
70 gval = im[pixel], child, parent, maxparent = p_heap->N >> 1;
72 p_heap->heap[parent = 1] = pixel;
73 while (parent <= maxparent) {
75 if (child < p_heap->N)
76 if (im[p_heap->heap[child]] > im[p_heap->heap[child + 1]])
78 if (gval <= im[p_heap->heap[child]])
80 p_heap->heap[parent] = p_heap->heap[child];
83 p_heap->heap[parent] = pixel;
87 int HeapEmpty(PixelHeap *p_heap)
89 return (p_heap->N == 0);
94 long FillExtremum(
int *Qpos, SMIL_UNUSED
int lambda, greyval *im,
95 greyval *
label,
int width,
int height, PixelHeap *p_heap,
96 int *Queue,
int Qmax,
long *fill_list)
99 int i = *Qpos, pixel = Queue[i], curneigh, px, MARK =
label[pixel],
100 uplimit = (height - 1) * width;
103 label[pixel] = -MARK;
105 fill_list[
area++] = pixel;
107 if (pixel >= width) {
108 curneigh = pixel - width;
109 if ((
label[curneigh] != MARK) && (
label[curneigh] != -MARK)) {
110 InsertInPixelHeap(p_heap, im, curneigh);
111 label[curneigh] = -MARK;
114 if (pixel < uplimit) {
115 curneigh = pixel + width;
116 if ((
label[curneigh] != MARK) && (
label[curneigh] != -MARK)) {
117 InsertInPixelHeap(p_heap, im, curneigh);
118 label[curneigh] = -MARK;
122 curneigh = pixel - 1;
123 if ((
label[curneigh] != MARK) && (
label[curneigh] != -MARK)) {
124 InsertInPixelHeap(p_heap, im, curneigh);
125 label[curneigh] = -MARK;
128 if (px < width - 1) {
129 curneigh = pixel + 1;
130 if ((
label[curneigh] != MARK) && (
label[curneigh] != -MARK)) {
131 InsertInPixelHeap(p_heap, im, curneigh);
132 label[curneigh] = -MARK;
139 }
while (
label[pixel] == MARK);
144 void SmallRegionalMinima(greyval *im, greyval *
label,
int *Queue,
int *Qmax,
145 int width,
int height,
int lambda)
149 register int i, j, curneigh, pixel, px, gval, curlab = 1;
152 for (i = 0; i < width * height; i++)
155 for (i = 0; i < width * height; i++) {
156 if (
label[i] == REGMAX)
163 while (head != tail) {
164 pixel = Queue[head++];
166 if (pixel >= width) {
167 curneigh = pixel - width;
168 if (im[curneigh] < gval) {
171 }
else if ((im[curneigh] == gval) && (
label[curneigh] == REGMAX)) {
172 label[curneigh] = curlab;
173 Queue[tail++] = curneigh;
176 if (pixel < (height - 1) * width - 1) {
177 curneigh = pixel + width;
178 if (im[curneigh] < gval) {
181 }
else if ((im[curneigh] == gval) && (
label[curneigh] == REGMAX)) {
182 label[curneigh] = curlab;
183 Queue[tail++] = curneigh;
187 curneigh = pixel - 1;
188 if (im[curneigh] < gval) {
191 }
else if ((im[curneigh] == gval) && (
label[curneigh] == REGMAX)) {
192 label[curneigh] = curlab;
193 Queue[tail++] = curneigh;
196 if (px < width - 1) {
197 curneigh = pixel + 1;
198 if (im[curneigh] < gval) {
201 }
else if ((im[curneigh] == gval) && (
label[curneigh] == REGMAX)) {
202 label[curneigh] = curlab;
203 Queue[tail++] = curneigh;
207 if (
label[pixel] != NARM) {
208 if ((head - *Qmax) < lambda) {
212 for (j = *Qmax; j < head; j++)
213 label[Queue[j]] = NARM;
216 for (j = *Qmax; j < head; j++)
217 label[Queue[j]] = NARM;
218 while (head != tail) {
219 pixel = Queue[head++];
222 curneigh = pixel - width;
223 if ((pixel >= width) && (im[curneigh] == gval) &&
224 (
label[curneigh] != NARM)) {
225 label[curneigh] = NARM;
226 Queue[tail++] = curneigh;
228 curneigh = pixel + width;
229 if ((pixel < (height - 1) * width - 1) && (im[curneigh] == gval) &&
230 (
label[curneigh] != NARM)) {
231 label[curneigh] = NARM;
232 Queue[tail++] = curneigh;
234 curneigh = pixel - 1;
235 if ((px > 0) && (im[curneigh] == gval) &&
236 (
label[curneigh] != NARM)) {
237 label[curneigh] = NARM;
238 Queue[tail++] = curneigh;
240 curneigh = pixel + 1;
241 if ((px < width - 1) && (im[curneigh] == gval) &&
242 (
label[curneigh] != NARM)) {
243 label[curneigh] = NARM;
244 Queue[tail++] = curneigh;
253 void VincentAreaClosing(
int lambda, greyval *im, greyval *
label,
int width,
254 int height, PixelHeap *p_heap,
long *fill_list)
256 int Qpos, j, pixel, px,
258 uplimit = (height - 1) * width, maxarea, MARK, curneigh, Qmax;
260 SmallRegionalMinima(im,
label, Queue, &Qmax, width, height, lambda);
262 MARK =
label[Queue[Qpos]];
263 while (Qpos < Qmax) {
264 maxarea = FillExtremum(&Qpos, lambda, im,
label, width, height, p_heap,
265 Queue, Qmax, fill_list);
267 while (maxarea < lambda) {
268 gval = im[pixel = RemoveFromPixelHeap(p_heap, im)];
270 fill_list[maxarea++] = pixel;
271 curneigh = pixel - width;
272 if ((pixel >= width) && (
label[curneigh] != MARK)) {
273 if (gval <= im[curneigh]) {
274 label[curneigh] = MARK;
275 InsertInPixelHeap(p_heap, im, curneigh);
279 curneigh = pixel + width;
280 if ((pixel < uplimit) && (
label[curneigh] != MARK)) {
281 if (gval <= im[curneigh]) {
282 label[curneigh] = MARK;
283 InsertInPixelHeap(p_heap, im, curneigh);
287 curneigh = pixel - 1;
288 if ((px > 0) && (
label[curneigh] != MARK)) {
289 if (gval <= im[curneigh]) {
290 label[curneigh] = MARK;
291 InsertInPixelHeap(p_heap, im, curneigh);
295 curneigh = pixel + 1;
296 if ((px < width - 1) && (
label[curneigh] != MARK)) {
297 if (gval <= im[curneigh]) {
298 label[curneigh] = MARK;
299 InsertInPixelHeap(p_heap, im, curneigh);
304 for (j = 0; j < maxarea; j++)
305 im[fill_list[j]] = gval;
307 MARK =
label[Queue[Qpos]];
311 GImage CreateImage(
int width,
int height)
316 img = (GImage) malloc(height *
sizeof(greyval *));
317 buf = (greyval *) malloc(width * height *
sizeof(greyval));
319 for (i = 1; i < height; i++)
320 img[i] = img[i - 1] + width;
324 void ReleaseImage(GImage img)
338 template <
class T1,
class T2>
343 ASSERT_ALLOCATED(&imIn)
344 ASSERT_SAME_SIZE(&imIn, &imOut)
350 RES_T res =
copy(imIn, im_32);
358 typename Image<INT32>::lineType bufferIn = im_32.
getPixels();
362 outputImage = (GImage) malloc(H *
sizeof(greyval *));
363 outputImage[0] = bufferIn;
364 for (
int i = 1; i < H; i++)
365 outputImage[i] = outputImage[i - 1] + W;
368 GImage labelImage = CreateImage(W, H);
371 Queue = (
int *) malloc(W * H *
sizeof(
int));
374 InitPixelHeap(&p_heap, 2 * (size + 1));
375 long *fill_list = (
long *) malloc(size *
sizeof(
long));
377 VincentAreaClosing(size, outputImage[0], labelImage[0], W, H, &p_heap,
380 res =
copy(im_32, imOut);
385 ExitPixelHeap(&p_heap);
387 ReleaseImage(labelImage);
size_t getWidth() const
Get image width.
Definition: DBaseImage.h:80
size_t getHeight() const
Get image height.
Definition: DBaseImage.h:85
Definition: DBaseImage.h:386
lineType getPixels() const
Get the pixels as a 1D array.
Definition: DImage.hpp:105
RES_T ImAreaClosing_PixelQueue(const Image< T1 > &imIn, int size, Image< T2 > &imOut)
Area closing with pixel queue algorithm (V4)
Definition: AreaOpeningPixelQueue.hpp:339
RES_T fill(Image< T > &imOut, const T &value)
fill() - Fill an image with a given value.
Definition: DImageArith.hpp:1456
size_t label(const Image< T1 > &imIn, Image< T2 > &imOut, const StrElt &se=DEFAULT_SE)
label() - Image labelization
Definition: DMorphoLabel.hpp:564
size_t area(const Image< T > &imIn)
area() - Area of an image
Definition: DMeasures.hpp:91
Definition: AreaOpeningPixelQueue.hpp:36