mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
Rework blob counting
This commit is contained in:
parent
29202f1f99
commit
06c9253644
@ -2,9 +2,43 @@
|
||||
#include "imlib.h"
|
||||
#include <arm_math.h>
|
||||
|
||||
blob_t *blob_alloc(int x, int y, int w, int h, int id, int c)
|
||||
{
|
||||
blob_t *blob = xalloc(sizeof(*blob));
|
||||
blob->x = x;
|
||||
blob->y = y;
|
||||
blob->w = w;
|
||||
blob->h = h;
|
||||
blob->id = id;
|
||||
blob->c = c;
|
||||
return blob;
|
||||
}
|
||||
|
||||
void blob_add_point(blob_t *blob, int px, int py)
|
||||
{
|
||||
/* expand blob */
|
||||
if (px < blob->x) {
|
||||
blob->x = px;
|
||||
}
|
||||
|
||||
if (py < blob->y) {
|
||||
blob->y = py;
|
||||
}
|
||||
|
||||
if (px > blob->w) {
|
||||
blob->w = px;
|
||||
}
|
||||
|
||||
if (py > blob->h) {
|
||||
blob->h = py;
|
||||
}
|
||||
}
|
||||
|
||||
array_t *imlib_count_blobs(struct image *image)
|
||||
{
|
||||
array_t *blobs;
|
||||
blob_t *blob;
|
||||
|
||||
array_alloc(&blobs, xfree);
|
||||
uint8_t *pixels = (uint8_t*) image->pixels;
|
||||
|
||||
@ -14,91 +48,83 @@ array_t *imlib_count_blobs(struct image *image)
|
||||
|
||||
for (int y=0; y<image->h; y++) {
|
||||
for (int x=0; x<image->w; x++) {
|
||||
int i=y*image->w+x;
|
||||
if (pixels[i]) {
|
||||
blob = NULL;
|
||||
uint8_t label = pixels[y*image->w+x];
|
||||
|
||||
if (label) {
|
||||
int w,e;
|
||||
int p_idx =0;
|
||||
int p_max = 1;
|
||||
|
||||
// set initial point
|
||||
points[0].x=x;
|
||||
points[0].y=y;
|
||||
|
||||
// add new blob
|
||||
rectangle_t *blob = rectangle_alloc(image->w, image->h, 0, 0);
|
||||
array_push_back(blobs, blob);
|
||||
|
||||
int p_idx =0;
|
||||
int p_max = 1;
|
||||
|
||||
/* flood fill */
|
||||
// alloc new blob
|
||||
blob = blob_alloc(image->w, image->h, 0, 0, label, 0);
|
||||
while(p_idx<p_max) {
|
||||
point_t *p=&points[p_idx++];
|
||||
|
||||
/* expand blob */
|
||||
if (p->x < blob->x) {
|
||||
blob->x = p->x;
|
||||
blob_add_point(blob, p->x, p->y);
|
||||
// scan west
|
||||
for (w=p->x-1; w>=0 && pixels[p->y*image->w+w]==label; w--) {
|
||||
blob_add_point(blob, w, p->y);
|
||||
}
|
||||
|
||||
if (p->y < blob->y) {
|
||||
blob->y = p->y;
|
||||
// scan east
|
||||
for (e=p->x+1; e<image->w && pixels[p->y*image->w+e]==label; e++) {
|
||||
blob_add_point(blob, e, p->y);
|
||||
}
|
||||
|
||||
if (p->x > blob->w) {
|
||||
blob->w = p->x;
|
||||
}
|
||||
// scan north and south rows, add a point only if it's the last
|
||||
// point or the last connected point in a row, this saves some memory
|
||||
// and other points on this segment will still be reachable from this one.
|
||||
|
||||
if (p->y > blob->h) {
|
||||
blob->h = p->y;
|
||||
}
|
||||
|
||||
int w,e;
|
||||
/* move west */
|
||||
for (w=p->x-1; w>=0 && pixels[p->y*image->w+w]; w--) {
|
||||
|
||||
}
|
||||
/* move east */
|
||||
for (e=p->x; e<image->w && pixels[p->y*image->w+e]; e++) {
|
||||
|
||||
}
|
||||
/* add points on north or south */
|
||||
for (int i=w; i<e; i++) {
|
||||
// add points on north row
|
||||
for (int i=w+1; i<e; i++) {
|
||||
pixels[p->y*image->w+i]=0;
|
||||
if ((p->y-1) > 0 && pixels[(p->y-1)*image->w+i]) {
|
||||
points[p_max].x = i;
|
||||
points[p_max].y = p->y-1;
|
||||
if ((p->y-1) > 0 && pixels[(p->y-1)*image->w+i]==label) {
|
||||
if (i==(e-1) || (pixels[(p->y-1)*image->w+i+1]!=label)) {
|
||||
points[p_max].x = i;
|
||||
points[p_max].y = p->y-1;
|
||||
|
||||
if (++p_max == p_size) {
|
||||
p_size +=100;
|
||||
points = xrealloc(points, p_size*sizeof*points);
|
||||
if (++p_max == p_size) {
|
||||
p_size +=100;
|
||||
points = xrealloc(points, p_size*sizeof*points);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if ((p->y+1) < image->h && pixels[(p->y+1)*image->w+i]) {
|
||||
points[p_max].x = i;
|
||||
points[p_max].y = p->y+1;
|
||||
// add points on south row
|
||||
for (int i=w+1; i<e; i++) {
|
||||
if ((p->y+1) < image->h && pixels[(p->y+1)*image->w+i]==label) {
|
||||
if (i==(e-1) || (pixels[(p->y+1)*image->w+i+1]!=label)) {
|
||||
points[p_max].x = i;
|
||||
points[p_max].y = p->y+1;
|
||||
|
||||
if (++p_max == p_size) {
|
||||
p_size +=100;
|
||||
points = xrealloc(points, p_size*sizeof*points);
|
||||
if (++p_max == p_size) {
|
||||
p_size +=100;
|
||||
points = xrealloc(points, p_size*sizeof*points);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (blob) {
|
||||
blob->w = blob->w - blob->x;
|
||||
blob->h = blob->h - blob->y;
|
||||
// discard small blobs
|
||||
if (blob->w > 10 && blob->h > 10) {
|
||||
array_push_back(blobs, blob);
|
||||
} else {
|
||||
xfree(blob);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0; i<array_length(blobs); i++) {
|
||||
rectangle_t *blob = array_at(blobs, i);
|
||||
// if (blob->w < 10) { /* blob too small */
|
||||
//array_erase(blobs, i); i--;
|
||||
// } else {
|
||||
blob->w = blob->w - blob->x;
|
||||
blob->h = blob->h - blob->y;
|
||||
// }
|
||||
}
|
||||
|
||||
xfree(points);
|
||||
return blobs;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user