52 #define SUCCESS_DETECT 1
56 #define FILTER_IMAGE 0
86 int cmpfunc(
const void *a,
const void *
b);
87 int cmp_i(
const void *a,
const void *
b);
92 return (*(
const int *)a - * (
const int *)
b);
96 int cmp_i(
const void *a,
const void *
b)
98 int ia = *(
const int *)a;
99 int ib = *(
const int *)
b;
141 static int last_frame_detection = 0;
142 static int repeat_gate = 0;
143 static struct gate_img previous_best_gate = {0};
146 bool check_initial_square =
false;
147 float iou_threshold = 0.7;
206 y = (y_high + y_low) / 2;
220 szx1 = (x_high1 - x_low1);
221 szx2 = (x_high2 - x_low2);
226 x = (x_high1 + x_low1) / 2;
228 sz = (
sz > szx1) ?
sz : szx1;
231 x = (x_high2 + x_low2) / 2;
233 sz = (
sz > szx2) ?
sz : szx2;
243 if (check_initial_square) {
274 bool add_gate =
true;
276 for (
int g = 0; g < (*n_gates); g++) {
279 if (iou > iou_threshold) {
312 #ifdef DEBUG_SNAKE_GATE
314 printf(
"(*n_gates):%d\n", (*n_gates));
315 for (
int i = 0; i < (*n_gates); i++) {
332 for (
int gate_nr = 0; gate_nr < (*n_gates); gate_nr++) {
347 static float limit_ratio = 1.5;
348 if(sz1g > 0.1 && sz2g > 0.1) {
349 ratio = (sz1g >= sz2g) ? sz1g / sz2g : sz2g / sz1g;
352 ratio = limit_ratio + 0.1;
383 memcpy(x_values, last_gate.
x_corners,
sizeof(x_values));
384 memcpy(y_values, last_gate.
y_corners,
sizeof(y_values));
386 qsort(x_values, 4,
sizeof(
int),
cmpfunc);
387 qsort(y_values, 4,
sizeof(
int),
cmpfunc);
389 int radius_p = x_values[3] - x_values[0];
406 #ifdef DEBUG_SNAKE_GATE
430 last_frame_detection = 1;
434 for (
int gate_nr = 0; gate_nr < (*n_gates); gate_nr++) {
442 int size_crosshair = 10;
443 if (repeat_gate == 0) {
445 }
else if (repeat_gate == 1) {
447 for (
int i = 0; i < 3; i++) {
466 last_frame_detection = 0;
552 from.
y = gate.
x - gate.
sz;
554 to.
y = gate.
x - gate.
sz;
557 from.
y = gate.
x - gate.
sz;
559 to.
y = gate.
x + gate.
sz;
562 from.
y = gate.
x + gate.
sz;
564 to.
y = gate.
x + gate.
sz;
567 from.
y = gate.
x + gate.
sz;
569 to.
y = gate.
x - gate.
sz;
583 int n_points, n_colored_points;
585 n_colored_points = 0;
590 float min_ratio_side = 0.4;
603 if ((
float) nc / (
float) np >= min_ratio_side &&
segment_length(from, to) > min_segment_length) {
607 n_colored_points += nc;
614 if ((
float) nc / (
float) np >= min_ratio_side &&
segment_length(from, to) > min_segment_length) {
618 n_colored_points += nc;
625 if ((
float) nc / (
float) np >= min_ratio_side &&
segment_length(from, to) > min_segment_length) {
629 n_colored_points += nc;
636 if ((
float) nc / (
float) np >= min_ratio_side &&
segment_length(from, to) > min_segment_length) {
641 n_colored_points += nc;
647 (*quality) = ((float) n_colored_points) / ((float) n_points);
652 static int n_samples_in = 100;
653 static float center_discard_threshold = 0.25;
655 float center_factor =
check_inside(im, gate.
x, gate.
y, gate.
sz, n_samples_in);
656 if (center_factor > center_discard_threshold) {
675 int n_points, n_colored_points;
677 n_colored_points = 0;
681 float min_ratio_side = 0.30;
687 from.
x = gate.
x - gate.
sz;
689 to.
x = gate.
x - gate.
sz;
692 if ((
float) nc / (
float) np >= min_ratio_side) {
696 n_colored_points += nc;
698 from.
x = gate.
x - gate.
sz;
700 to.
x = gate.
x + gate.
sz;
703 if ((
float) nc / (
float) np >= min_ratio_side) {
707 n_colored_points += nc;
709 from.
x = gate.
x + gate.
sz;
711 to.
x = gate.
x + gate.
sz;
714 if ((
float) nc / (
float) np >= min_ratio_side) {
718 n_colored_points += nc;
720 from.
x = gate.
x + gate.
sz;
722 to.
x = gate.
x - gate.
sz;
725 if ((
float) nc / (
float) np >= min_ratio_side) {
730 n_colored_points += nc;
737 (*quality) = ((float) n_colored_points) / ((float) n_points);
741 int n_samples_in = 100;
742 float center_discard_threshold = 0.25;
743 float center_factor =
check_inside(im, gate.
x, gate.
y, gate.
sz, n_samples_in);
744 if (center_factor > center_discard_threshold) {
763 int num_color_center = 0;
770 for (
int i = 0; i < n_samples_in; i++) {
772 int x_in =
x + (rand() % sz) - (0.5 * sz);
773 int y_in =
y + (rand() % sz) - (0.5 * sz);
775 if (y_in >= 0 && y_in < im->w && x_in >= 0 && x_in < im->
h) {
789 float center_factor = 0;
791 center_factor = num_color_center / (float)
n_samples;
793 return center_factor;
805 float r = sqrtf((Q1.
x - Q2.
x) * (Q1.
x - Q2.
x) + (Q1.
y - Q2.
y) * (Q1.
y - Q2.
y));
822 (*n_colored_points) = 0;
829 for (t = 0.0
f; t < 1.0f; t += t_step) {
831 x = (int)(t * Q1.
x + (1.0f - t) * Q2.
x);
832 y = (int)(t * Q1.
y + (1.0f - t) * Q2.
y);
835 if (
x >= 0 && x < im->
h &&
y >= 0 && y < im->w) {
841 (*n_colored_points)++;
867 while ((*y_low) > 0 && !done) {
888 while ((*y_high) < im->
w - 1 && !done) {
926 while ((*x_low) > 0 && !done) {
947 while ((*x_high) < im->
h - 1 && !done) {
997 float corner_area = 0.3f;
1016 float x_corner_f = (float)(*corner_x);
1017 float y_corner_f = (float)(*corner_y);
1018 float size_f = (float)size;
1021 int x_l = (int)(x_corner_f - size_f * size_factor);
1022 Bound(x_l, 0, im->
h);
1023 int x_r = (int)(x_corner_f + size_f * size_factor);
1024 Bound(x_r, 0, im->
h);
1025 int y_h = (int)(y_corner_f + size_f * size_factor);
1026 Bound(y_h, 0, im->
w);
1027 int y_l = (int)(y_corner_f - size_f * size_factor);
1028 Bound(y_l, 0, im->
w);
1031 #ifdef DEBUG_SNAKE_GATE
1045 int x_size = x_r - x_l + 1;
1046 int y_size = y_h - y_l + 1;
1050 memset(x_hist, 0,
sizeof(
int)*x_size);
1051 memset(y_hist, 0,
sizeof(
int)*y_size);
1055 int best_x_loc = x_l;
1056 int x_best_start = x_l;
1058 int best_y_loc = y_l;
1059 int y_best_start = y_l;
1062 for (
int y_pix = y_l; y_pix < y_h; y_pix++) {
1063 for (
int x_pix = x_l; x_pix < x_r; x_pix++) {
1066 int cur_x = x_hist[x_pix - x_l];
1067 int cur_y = y_hist[y_pix - y_l];
1068 x_hist[x_pix - x_l] = cur_x + 1;
1069 y_hist[y_pix - y_l] = cur_y + 1;
1071 if (x_hist[x_pix - x_l] > best_x) {
1072 best_x = x_hist[x_pix - x_l];
1074 x_best_start = x_pix;
1075 }
else if (cur_x == best_x) {
1076 best_x_loc = (x_pix + x_best_start) / 2;
1078 if (y_hist[y_pix - y_l] > best_y) {
1079 best_y = y_hist[y_pix - y_l];
1081 y_best_start = y_pix;
1082 }
else if (cur_y == best_y) {
1083 best_y_loc = (y_pix + y_best_start) / 2;
1091 *corner_x = best_x_loc;
1092 *corner_y = best_y_loc;
1142 int w1, h1, w2, h2, un;
1143 w1 = x_box_1[1] - x_box_1[0];
1144 h1 = y_box_1[0] - y_box_1[2];
1145 w2 = x_box_2[1] - x_box_2[0];
1146 h2 = y_box_2[0] - y_box_2[2];
1147 un = w1 * h1 + w2 * h2 - intersection;
1153 iou = (float) intersection / (
float) un;
1173 return width * height;
1188 if (val_low_2 < val_low_1) {
1189 if (val_high_2 < val_low_1) {
1192 min_val = (val_high_1 > val_high_2) ? val_high_2 : val_high_1;
1193 overlap = min_val - val_low_1;
1196 if (val_high_1 < val_low_2) {
1199 min_val = (val_high_1 > val_high_2) ? val_high_2 : val_high_1;
1200 overlap = min_val - val_low_2;