Files
QDAC-firmware/app/gl_handle_img.c
2024-03-27 16:20:49 +08:00

240 lines
8.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 = Q_sqrt(dx0 * dx0 + dy0 * dy0);
float dist1 = Q_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;
}
//*************************** 函数中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;
}
}
}
}
//*********************************** 交叉相加减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 = Q_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 = Q_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-3]);
float db = fabs(angle[i+3] - angle[i]);
if (da > threshold && db > threshold) {
return 1; // 是弯道
}
}
return 0; // 不是弯道
}