mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
parent
d93f8ec56a
commit
3d17929801
@ -683,6 +683,7 @@ void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned in
|
|||||||
|
|
||||||
for (int r = r_min, rr = r_max; r < rr; r += r_step) { // ignore r = 0/1
|
for (int r = r_min, rr = r_max; r < rr; r += r_step) { // ignore r = 0/1
|
||||||
int a_size, b_size, hough_divide = 1; // divides a and b accumulators
|
int a_size, b_size, hough_divide = 1; // divides a and b accumulators
|
||||||
|
int hough_shift = 0;
|
||||||
int w_size = roi->w - (2 * r);
|
int w_size = roi->w - (2 * r);
|
||||||
int h_size = roi->h - (2 * r);
|
int h_size = roi->h - (2 * r);
|
||||||
|
|
||||||
@ -691,10 +692,18 @@ void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned in
|
|||||||
b_size = 1 + ((h_size + hough_divide - 1) / hough_divide) + 1; // top & bottom padding
|
b_size = 1 + ((h_size + hough_divide - 1) / hough_divide) + 1; // top & bottom padding
|
||||||
if ((sizeof(uint32_t) * a_size * b_size) <= fb_avail()) break;
|
if ((sizeof(uint32_t) * a_size * b_size) <= fb_avail()) break;
|
||||||
hough_divide = hough_divide << 1; // powers of 2...
|
hough_divide = hough_divide << 1; // powers of 2...
|
||||||
|
hough_shift++;
|
||||||
if (hough_divide > 4) fb_alloc_fail(); // support 1, 2, 4
|
if (hough_divide > 4) fb_alloc_fail(); // support 1, 2, 4
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *acc = fb_alloc0(sizeof(uint32_t) * a_size * b_size, FB_ALLOC_NO_HINT);
|
uint32_t *acc = fb_alloc0(sizeof(uint32_t) * a_size * b_size, FB_ALLOC_NO_HINT);
|
||||||
|
int16_t *rcos = fb_alloc(sizeof(int16_t)*360, FB_ALLOC_NO_HINT);
|
||||||
|
int16_t *rsin = fb_alloc(sizeof(int16_t)*360, FB_ALLOC_NO_HINT);
|
||||||
|
for (int i=0; i<360; i++)
|
||||||
|
{
|
||||||
|
rcos[i] = (int16_t)roundf(r * cos_table[i]);
|
||||||
|
rsin[i] = (int16_t)roundf(r * sin_table[i]);
|
||||||
|
}
|
||||||
|
|
||||||
for (int y = 0, yy = roi->h; y < yy; y++) {
|
for (int y = 0, yy = roi->h; y < yy; y++) {
|
||||||
for (int x = 0, xx = roi->w; x < xx; x++) {
|
for (int x = 0, xx = roi->w; x < xx; x++) {
|
||||||
@ -705,13 +714,12 @@ void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned in
|
|||||||
|
|
||||||
// We have to do the below step twice because the gradient may be pointing inside or outside the circle.
|
// We have to do the below step twice because the gradient may be pointing inside or outside the circle.
|
||||||
// Only graidents pointing inside of the circle sum up to produce a large magnitude.
|
// Only graidents pointing inside of the circle sum up to produce a large magnitude.
|
||||||
|
|
||||||
for (;;) { // Hi to lo edge direction
|
for (;;) { // Hi to lo edge direction
|
||||||
int a = fast_roundf(x + (r * cos_table[theta])) - r;
|
int a = x + rcos[theta] - r;
|
||||||
if ((a < 0) || (w_size <= a)) break; // circle doesn't fit in the window
|
if ((a < 0) || (w_size <= a)) break; // circle doesn't fit in the window
|
||||||
int b = fast_roundf(y + (r * sin_table[theta])) - r;
|
int b = y + rsin[theta] - r;
|
||||||
if ((b < 0) || (h_size <= b)) break; // circle doesn't fit in the window
|
if ((b < 0) || (h_size <= b)) break; // circle doesn't fit in the window
|
||||||
int acc_index = (((b / hough_divide) + 1) * a_size) + ((a / hough_divide) + 1); // add offset
|
int acc_index = (((b >> hough_shift) + 1) * a_size) + ((a >> hough_shift) + 1); // add offset
|
||||||
|
|
||||||
int acc_value = acc[acc_index] += magnitude;
|
int acc_value = acc[acc_index] += magnitude;
|
||||||
acc[acc_index] = acc_value;
|
acc[acc_index] = acc_value;
|
||||||
@ -719,11 +727,11 @@ void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned in
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (;;) { // Lo to hi edge direction
|
for (;;) { // Lo to hi edge direction
|
||||||
int a = fast_roundf(x + (r * cos_table[(theta + 180) % 360])) - r;
|
int a = x - rcos[theta] - r;
|
||||||
if ((a < 0) || (w_size <= a)) break; // circle doesn't fit in the window
|
if ((a < 0) || (w_size <= a)) break; // circle doesn't fit in the window
|
||||||
int b = fast_roundf(y + (r * sin_table[(theta + 180) % 360])) - r;
|
int b = y - rsin[theta] - r;
|
||||||
if ((b < 0) || (h_size <= b)) break; // circle doesn't fit in the window
|
if ((b < 0) || (h_size <= b)) break; // circle doesn't fit in the window
|
||||||
int acc_index = (((b / hough_divide) + 1) * a_size) + ((a / hough_divide) + 1); // add offset
|
int acc_index = (((b >> hough_shift) + 1) * a_size) + ((a >> hough_shift) + 1); // add offset
|
||||||
|
|
||||||
int acc_value = acc[acc_index] += magnitude;
|
int acc_value = acc[acc_index] += magnitude;
|
||||||
acc[acc_index] = acc_value;
|
acc[acc_index] = acc_value;
|
||||||
@ -734,29 +742,34 @@ void imlib_find_circles(list_t *out, image_t *ptr, rectangle_t *roi, unsigned in
|
|||||||
|
|
||||||
for (int y = 1, yy = b_size - 1; y < yy; y++) {
|
for (int y = 1, yy = b_size - 1; y < yy; y++) {
|
||||||
uint32_t *row_ptr = acc + (a_size * y);
|
uint32_t *row_ptr = acc + (a_size * y);
|
||||||
|
uint32_t val;
|
||||||
for (int x = 1, xx = a_size - 1; x < xx; x++) {
|
for (int x = 1, xx = a_size - 1; x < xx; x++) {
|
||||||
if ((row_ptr[x] >= threshold)
|
val = row_ptr[x];
|
||||||
&& (row_ptr[x] >= row_ptr[x-a_size-1])
|
if ((val >= threshold)
|
||||||
&& (row_ptr[x] >= row_ptr[x-a_size])
|
&& (val >= row_ptr[x-a_size-1])
|
||||||
&& (row_ptr[x] >= row_ptr[x-a_size+1])
|
&& (val >= row_ptr[x-a_size])
|
||||||
&& (row_ptr[x] >= row_ptr[x-1])
|
&& (val >= row_ptr[x-a_size+1])
|
||||||
&& (row_ptr[x] >= row_ptr[x+1])
|
&& (val >= row_ptr[x-1])
|
||||||
&& (row_ptr[x] >= row_ptr[x+a_size-1])
|
&& (val >= row_ptr[x+1])
|
||||||
&& (row_ptr[x] >= row_ptr[x+a_size])
|
&& (val >= row_ptr[x+a_size-1])
|
||||||
&& (row_ptr[x] >= row_ptr[x+a_size+1])) {
|
&& (val >= row_ptr[x+a_size])
|
||||||
|
&& (val >= row_ptr[x+a_size+1])) {
|
||||||
|
|
||||||
find_circles_list_lnk_data_t lnk_data;
|
find_circles_list_lnk_data_t lnk_data;
|
||||||
lnk_data.magnitude = row_ptr[x];
|
lnk_data.magnitude = val;
|
||||||
lnk_data.p.x = ((x - 1) * hough_divide) + r + roi->x; // remove offset
|
lnk_data.p.x = ((x - 1) << hough_shift) + r + roi->x; // remove offset
|
||||||
lnk_data.p.y = ((y - 1) * hough_divide) + r + roi->y; // remove offset
|
lnk_data.p.y = ((y - 1) << hough_shift) + r + roi->y; // remove offset
|
||||||
lnk_data.r = r;
|
lnk_data.r = r;
|
||||||
|
|
||||||
list_push_back(out, &lnk_data);
|
list_push_back(out, &lnk_data);
|
||||||
|
if (val > row_ptr[x+1])
|
||||||
|
x++; // can skip the next pixel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fb_free(); // rsin
|
||||||
|
fb_free(); // rcos
|
||||||
fb_free(); // acc
|
fb_free(); // acc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1065,7 +1065,7 @@ typedef struct find_lines_list_lnk_data {
|
|||||||
|
|
||||||
typedef struct find_circles_list_lnk_data {
|
typedef struct find_circles_list_lnk_data {
|
||||||
point_t p;
|
point_t p;
|
||||||
uint32_t r, magnitude;
|
uint16_t r, magnitude;
|
||||||
} find_circles_list_lnk_data_t;
|
} find_circles_list_lnk_data_t;
|
||||||
|
|
||||||
typedef struct find_rects_list_lnk_data {
|
typedef struct find_rects_list_lnk_data {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user