Files
QDAC-firmware/app/gl_handle_img.c

240 lines
8.3 KiB
C
Raw Normal View History

#include "zf_common_headfile.h"
#include "math.h"
#include "gl_headfile.h"
const int32_t direction_front[4][2] = {{0, -1},{1, 0},{0, 1},{-1, 0}};
const int32_t direction_frontleft[4][2] = {{-1, -1},{1, -1},{1, 1},{-1, 1}};
const int32_t direction_frontright[4][2] ={{1, -1},{1, 1},{-1, 1},{-1, -1}};
void SearchLineAdaptive_Left(uint8_t img_gray[], int32_t block_size, int32_t down_value, int32_t h, int32_t w, int32_t pts[][2], int32_t* line_num)
{
const int32_t half = block_size / 2;
int step = 0;
int dir = 0;
int turn = 0;
while (step < *line_num && half < w && w < IMAGE_W - half -1 && half < h && h < IMAGE_H - half -1 && turn < 4) {
int local_thres = 0;
for (int dh = -1 * half; dh <= half; dh++) {
for (int dw = -1 * half; dw <= half; dw++) {
local_thres += GET_PIX_1C(img_gray, h + dh, w + dw);
}
}
local_thres /= block_size * block_size;
local_thres -= down_value;
int front_value = GET_PIX_1C(img_gray, h+direction_front[dir][1], w + direction_front[dir][0]);
int frontleft_value = GET_PIX_1C(img_gray, h + direction_frontleft[dir][1], w + direction_frontleft[dir][0]);
if (front_value < local_thres) {
dir = (dir + 1) % 4;
turn++;
} else if (frontleft_value < local_thres) {
w += direction_front[dir][0];
h += direction_front[dir][1];
pts[step][1] = w;
pts[step][0] = h;
step++;
turn = 0;
} else {
w += direction_frontleft[dir][0];
h += direction_frontleft[dir][1];
dir = (dir + 3) % 4;
pts[step][1] = w;
pts[step][0] = h;
step++;
turn = 0;
}
}
*line_num = step;
}
void SearchLineAdaptive_Right(uint8_t img_gray[], int32_t block_size, int32_t down_value, int32_t h, int32_t w, int32_t pts[][2], int32_t* line_num)
{
int half = block_size / 2;
int step = 0, dir = 0, turn = 0;
while (step < *line_num && 0 < w && w < IMAGE_W - 1 && 0 < h && h < IMAGE_H -1 && turn < 4) {
int local_thres = 0;
for (int dh = -half; dh <= half; dh++) {
for (int dw = -half; dw <= half; dw++) {
local_thres += GET_PIX_1C(img_gray, h + dh, w + dw);
}
}
local_thres /= block_size * block_size;
local_thres -= down_value;
int front_value = GET_PIX_1C(img_gray, h + direction_front[dir][1], w + direction_front[dir][0]);
int frontright_value = GET_PIX_1C(img_gray, h + direction_frontright[dir][1], w + direction_frontright[dir][0]);
if (front_value < local_thres) {
dir = (dir + 3) % 4;
turn++;
} else if (frontright_value < local_thres) {
w += direction_front[dir][0];
h += direction_front[dir][1];
pts[step][1] = w;
pts[step][0] = h;
step++;
turn = 0;
} else {
w += direction_frontright[dir][0];
h += direction_frontright[dir][1];
dir = (dir + 1) % 4;
pts[step][1] = w;
pts[step][0] = h;
step++;
turn = 0;
}
}
*line_num = step;
}
void GetLinesFilter(float pts_in[][2], int32_t pts_in_count, float pts_out[][2], int32_t kernelsize)
{
int half = kernelsize / 2;
for (int i = 0; i < pts_in_count; i++) {
pts_out[i][0] = 0;
pts_out[i][1] = 0;
for (int j = -half; j <= half; j++) {
pts_out[i][0] += pts_in[clip(i + j, 0, pts_in_count - 1)][0] * (half + 1 - abs(j));
pts_out[i][1] += pts_in[clip(i + j, 0, pts_in_count - 1)][1] * (half + 1 - abs(j));
}
pts_out[i][0] /= (2 * half + 2) * (half + 1) / 2;
pts_out[i][1] /= (2 * half + 2) * (half + 1) / 2;
}
}
void GetLinesResample(float pts_in[][2], int32_t num1, float pts_out[][2], int32_t* num2, float dist)
{
if (num1 < 0) {
*num2 = 0;
return;
}
pts_out[0][0] = pts_in[0][0];
pts_out[0][1] = pts_in[0][1];
int len = 1;
for (int i = 0; i < num1 - 1 && len < *num2; i++) {
float x0 = pts_in[i][1];
float y0 = pts_in[i][0];
float x1 = pts_in[i + 1][1];
float y1 = pts_in[i + 1][0];
do {
float x = pts_out[len - 1][1];
float y = pts_out[len - 1][0];
float dx0 = x0 - x;
float dy0 = y0 - y;
float dx1 = x1 - x;
float dy1 = y1 - y;
float dist0 = sqrt(dx0 * dx0 + dy0 * dy0);
float dist1 = sqrt(dx1 * dx1 + dy1 * dy1);
float r0 = (dist1 - dist) / (dist1 - dist0);
float r1 = 1 - r0;
if (r0 < 0 || r1 < 0) break;
x0 = x0 * r0 + x1 * r1;
y0 = y0 * r0 + y1 * r1;
pts_out[len][1] = x0;
pts_out[len][0] = y0;
len++;
} while (len < *num2);
}
*num2 = len;
}
2024-03-08 19:58:36 +08:00
//*************************** 函数中x,y的位置似乎反了 *************************//
void local_angle_points(float pts_in[][2], int num, float angle_out[], int dist) {
for (int i = 0; i < num; i++) {
if (i <= 0 || i >= num - 1) {
angle_out[i] = 0;
continue;
}
float dx1 = pts_in[i][0] - pts_in[clip(i - dist, 0, num - 1)][0];
float dy1 = pts_in[i][1] - pts_in[clip(i - dist, 0, num - 1)][1];
float dn1 = sqrtf(dx1 * dx1 + dy1 * dy1);
float dx2 = pts_in[clip(i + dist, 0, num - 1)][0] - pts_in[i][0];
float dy2 = pts_in[clip(i + dist, 0, num - 1)][1] - pts_in[i][1];
float dn2 = sqrtf(dx2 * dx2 + dy2 * dy2);
float c1 = dx1 / dn1;
float s1 = dy1 / dn1;
float c2 = dx2 / dn2;
float s2 = dy2 / dn2;
angle_out[i] = atan2f(c1 * s2 - c2 * s1, c2 * c1 + s2 * s1); //得到弧度 类似angle_out = 0.3491
}
}
void nms_angle(float angle_in[], int num, float angle_out[], int kernel) {
int half = kernel / 2;
for (int i = 0; i < num; i++) {
angle_out[i] = angle_in[i];
for (int j = -half; j <= half; j++) {
if (fabs(angle_in[clip(i + j, 0, num - 1)]) > fabs(angle_out[i])) {
angle_out[i] = 0;
break;
}
}
}
}
2024-03-08 19:58:36 +08:00
//*********************************** 交叉相加减dx接近与0导致y基本不变dy接近于1导致x的值变得较多 *********************************//
void GetMidLine_Left(float pts_left[][2], int32_t pts_left_count, float mid_left[][2], int32_t approx_num, float dist)
{
for (int i = 0; i < pts_left_count; i++) {
float dx = pts_left[clip(i + approx_num, 0, pts_left_count - 1)][1] - pts_left[clip(i - approx_num, 0, pts_left_count - 1)][1];
float dy = pts_left[clip(i + approx_num, 0, pts_left_count - 1)][0] - pts_left[clip(i - approx_num, 0, pts_left_count - 1)][0];
float dn = sqrt(dx * dx + dy * dy);
dx /= dn;
dy /= dn;
mid_left[i][0] = pts_left[i][0] + dx * dist;
mid_left[i][1] = pts_left[i][1] - dy * dist;
}
}
void GetMidLine_Right(float pts_right[][2], int32_t pts_right_count, float mid_right[][2], int32_t approx_num, float dist)
{
for (int i = 0; i < pts_right_count; i++) {
float dx = pts_right[clip(i + approx_num, 0, pts_right_count -1)][1] - pts_right[clip(i - approx_num, 0, pts_right_count -1 )][1];
float dy = pts_right[clip(i + approx_num, 0, pts_right_count -1)][0] - pts_right[clip(i - approx_num, 0, pts_right_count -1)][0];
float dn = sqrt(dx * dx + dy * dy);
dx /= dn;//sin
dy /= dn;//cos
mid_right[i][0] = pts_right[i][0] - dx * dist;
mid_right[i][1] = pts_right[i][1] + dy * dist;
}
}
int is_curve(float angle[], int n, float threshold) {
for (int i = 1; i < n - 1; i++) {
float da = fabs(angle[i] - angle[i-1]);
float db = fabs(angle[i+1] - angle[i]);
if (da > threshold && db > threshold) {
return 1; // 是弯道
}
}
return 0; // 不是弯道
}