Merge pull request #282 from kwagyeman/master

Improved the performance of the get_regression() robust linear regression code for racing.
This commit is contained in:
Ibrahim Abd Elkader 2017-11-19 13:31:29 +02:00 committed by GitHub
commit c7eb0091bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -589,13 +589,20 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang
}
}
} else { // Theil-Sen Estimator
int blob_pixels = 0;
fifo_t fifo;
fifo_alloc(&fifo, roi->w * roi->h, sizeof(point_t));
int *x_histogram = fb_alloc0(ptr->w * sizeof(int)); // Not roi so we don't have to adjust, we can burn the RAM.
int *y_histogram = fb_alloc0(ptr->h * sizeof(int)); // Not roi so we don't have to adjust, we can burn the RAM.
long long *x_delta_histogram = fb_alloc0((2 * ptr->w) * sizeof(long long)); // Not roi so we don't have to adjust, we can burn the RAM.
long long *y_delta_histogram = fb_alloc0((2 * ptr->h) * sizeof(long long)); // Not roi so we don't have to adjust, we can burn the RAM.
uint32_t size;
point_t *points = (point_t *) fb_alloc_all(&size);
size_t points_max = size / sizeof(point_t);
size_t points_count = 0;
if(points_max) {
int blob_pixels = 0;
for (list_lnk_t *it = iterator_start_from_head(thresholds); it; it = iterator_next(it)) {
color_thresholds_list_lnk_data_t lnk_data;
iterator_get(thresholds, it, &lnk_data);
@ -610,9 +617,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang
x_histogram[x]++;
y_histogram[y]++;
point_t p;
point_init(&p, x, y);
fifo_enqueue(&fifo, &p);
if(points_count < points_max) {
point_init(&points[points_count], x, y);
points_count += 1;
}
}
}
}
@ -627,9 +635,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang
x_histogram[x]++;
y_histogram[y]++;
point_t p;
point_init(&p, x, y);
fifo_enqueue(&fifo, &p);
if(points_count < points_max) {
point_init(&points[points_count], x, y);
points_count += 1;
}
}
}
}
@ -644,9 +653,10 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang
x_histogram[x]++;
y_histogram[y]++;
point_t p;
point_init(&p, x, y);
fifo_enqueue(&fifo, &p);
if(points_count < points_max) {
point_init(&points[points_count], x, y);
points_count += 1;
}
}
}
}
@ -659,26 +669,18 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang
}
if (blob_pixels) {
long long delta_sum = (fifo_size(&fifo) * (fifo_size(&fifo) - 1)) / 2;
long long delta_sum = (points_count * (points_count - 1)) / 2;
if (delta_sum) {
// The code below computes the average slope between all pairs of points.
// This is a N^2 operation that can easily blow up if the image is not threshold carefully...
long long *x_delta_histogram = fb_alloc0((2 * ptr->w) * sizeof(long long)); // Not roi so we don't have to adjust, we can burn the RAM.
long long *y_delta_histogram = fb_alloc0((2 * ptr->h) * sizeof(long long)); // Not roi so we don't have to adjust, we can burn the RAM.
while (fifo_is_not_empty(&fifo)) {
point_t p0;
fifo_dequeue(&fifo, &p0);
for (size_t i = 0, j = fifo_size(&fifo); i < j; i++) {
point_t p1;
fifo_dequeue(&fifo, &p1);
x_delta_histogram[p0.x - p1.x + ptr->w]++; // Note we allocated 1 extra above so we can do ptr->w instead of (ptr->w-1).
y_delta_histogram[p0.y - p1.y + ptr->h]++; // Note we allocated 1 extra above so we can do ptr->h instead of (ptr->h-1).
fifo_enqueue(&fifo, &p1);
for(int i = 0; i < points_count; i++) {
point_t *p0 = &points[i];
for(int j = i + 1; j < points_count; j++) {
point_t *p1 = &points[j];
x_delta_histogram[p0->x - p1->x + ptr->w]++; // Note we allocated 1 extra above so we can do ptr->w instead of (ptr->w-1).
y_delta_histogram[p0->y - p1->y + ptr->h]++; // Note we allocated 1 extra above so we can do ptr->h instead of (ptr->h-1).
}
}
@ -720,15 +722,15 @@ bool imlib_get_regression(find_lines_list_lnk_data_t *out, image_t *ptr, rectang
} else {
memset(out, 0, sizeof(find_lines_list_lnk_data_t));
}
}
}
}
fb_free(); // points
fb_free(); // y_delta_histogram
fb_free(); // x_delta_histogram
}
}
fb_free(); // y_histogram
fb_free(); // x_histogram
fifo_free(&fifo);
}
return result;