Add reverse workspace filter option
This commit is contained in:
@@ -14,7 +14,7 @@ time_period_P_r30_linaro
|
|||||||
|
|
||||||
- 目标设备运行库较旧,需要使用 Linaro GCC 7.4.1 交叉编译,避免引入高版本 `glibc/libstdc++` 依赖。
|
- 目标设备运行库较旧,需要使用 Linaro GCC 7.4.1 交叉编译,避免引入高版本 `glibc/libstdc++` 依赖。
|
||||||
- 支持按时间段控制是否执行推理。
|
- 支持按时间段控制是否执行推理。
|
||||||
- 支持 workspace 区域过滤,只上传区域内目标。
|
- 支持 workspace 区域过滤,默认只上传区域内目标,也可通过 `-R` 反向为只上传区域外目标。
|
||||||
- 优化识别结果上报逻辑,降低多进程运行时漏帧/低置信波动造成的漏报。
|
- 优化识别结果上报逻辑,降低多进程运行时漏帧/低置信波动造成的漏报。
|
||||||
- 增加低置信度、过滤原因、上传决策等日志,便于现场复盘。
|
- 增加低置信度、过滤原因、上传决策等日志,便于现场复盘。
|
||||||
|
|
||||||
@@ -100,6 +100,7 @@ file /home/smos/yolov5-linaro-build/yolov5
|
|||||||
-w, --workspace 检测区域,多边形点坐标,逗号分隔
|
-w, --workspace 检测区域,多边形点坐标,逗号分隔
|
||||||
-r, --threshold 置信度阈值,整数 30 到 90
|
-r, --threshold 置信度阈值,整数 30 到 90
|
||||||
-P, --time-period 推理生效时间段
|
-P, --time-period 推理生效时间段
|
||||||
|
-R, --reverse-workspace 反向 workspace 过滤,上传 -w 区域外目标
|
||||||
```
|
```
|
||||||
|
|
||||||
示例:
|
示例:
|
||||||
@@ -120,6 +121,14 @@ workspace 示例:
|
|||||||
./yolov5 -s input.h264 -m abc -c camera001 -t 19 -p 8080 -w 100,100,500,100,500,500,100,500
|
./yolov5 -s input.h264 -m abc -c camera001 -t 19 -p 8080 -w 100,100,500,100,500,500,100,500
|
||||||
```
|
```
|
||||||
|
|
||||||
|
反向 workspace 示例:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./yolov5 -s input.h264 -m abc -c camera001 -t 19 -p 8080 -w 100,100,500,100,500,500,100,500 -R
|
||||||
|
```
|
||||||
|
|
||||||
|
开启 `-R` 后,`-w` 画出的区域会作为排除区域:区域内目标不上报,只上报区域外目标。`-R` 必须配合 `-w` 使用。
|
||||||
|
|
||||||
如果不传 `-w`,默认全画面有效。
|
如果不传 `-w`,默认全画面有效。
|
||||||
|
|
||||||
time-period 示例:
|
time-period 示例:
|
||||||
@@ -166,10 +175,10 @@ h264 分段文件会写到:
|
|||||||
常见日志事件:
|
常见日志事件:
|
||||||
|
|
||||||
- `frame_seen`:本次推理帧序号和原始检测数量。
|
- `frame_seen`:本次推理帧序号和原始检测数量。
|
||||||
- `strong_present`:超过阈值且在 workspace 内。
|
- `strong_present`:超过阈值且通过 workspace 过滤。
|
||||||
- `weak_present`:高于 `0.30`、低于阈值且在 workspace 内。
|
- `weak_present`:高于 `0.30`、低于阈值且通过 workspace 过滤。
|
||||||
- `filtered_low_conf`:低于 `0.30`。
|
- `filtered_low_conf`:低于 `0.30`。
|
||||||
- `filtered_workspace`:不在 workspace 内。
|
- `filtered_workspace`:未通过 workspace 过滤。`workspace_mode=normal` 表示普通模式,`workspace_mode=reverse` 表示 `-R` 反向模式。
|
||||||
- `no_target`:本帧没有可上传目标。
|
- `no_target`:本帧没有可上传目标。
|
||||||
- `upload_positive`:本帧触发正例上传。
|
- `upload_positive`:本帧触发正例上传。
|
||||||
- `upload_skip_throttle`:同一 `class_idx` 500ms 节流跳过。
|
- `upload_skip_throttle`:同一 `class_idx` 500ms 节流跳过。
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
# `-R` 反向 workspace 过滤设计记录
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
当前推理程序通过 `-w/--workspace` 配置一个多边形工作区域。检测结果在进入上报候选前,会用目标框中心点调用 `is_point_in_workspace(left, top, right, bottom)` 判断是否位于该区域内:
|
||||||
|
|
||||||
|
- 在 workspace 内:继续进入 `current_objects`,后续按类别编码合并并上报。
|
||||||
|
- 在 workspace 外:记录 `filtered_workspace`,不参与上报。
|
||||||
|
- 未传 `-w`:`init_polygon(NULL, 0)`,默认全画面有效。
|
||||||
|
|
||||||
|
本次需求是新增 `-R` 参数,让 `-w` 画出来的区域变成排除区域:开启 `-R` 后,区域内的识别结果不上报,只上报区域外的内容。
|
||||||
|
|
||||||
|
## 准备实现方式
|
||||||
|
|
||||||
|
1. 在命令行参数解析里新增无参数开关:
|
||||||
|
- 短参数:`-R`
|
||||||
|
- 长参数建议:`--reverse-workspace` 或沿用旧目录线索里的 `--reverse-detect`
|
||||||
|
- 默认关闭,保持现有行为完全不变。
|
||||||
|
|
||||||
|
2. 增加一个全局配置变量,例如:
|
||||||
|
- `bool ReverseWorkspace = false;`
|
||||||
|
- 放在 `vertix.cpp/vertix.h` 或更靠近推理过滤逻辑的公共头文件中,供 `main.cpp` 设置、`rknn.cpp` 读取。
|
||||||
|
|
||||||
|
3. 不改 YOLO 后处理、NMS、阈值、类别编码和上传 JSON,只改 workspace 过滤判定。
|
||||||
|
|
||||||
|
4. 在 `rknn.cpp::print_object_detect_result` 中,把直接判断:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (!is_point_in_workspace(left, top, right, bottom)) {
|
||||||
|
...
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
调整成先计算原始位置关系,再根据 `-R` 反转:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
bool in_workspace = is_point_in_workspace(left, top, right, bottom);
|
||||||
|
bool pass_workspace = ReverseWorkspace ? !in_workspace : in_workspace;
|
||||||
|
if (!pass_workspace) {
|
||||||
|
...
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
这样 `-R` 只改变“是否允许上报”,不改变多边形算法本身。
|
||||||
|
|
||||||
|
5. 低置信度日志里的 workspace 判断也需要同步使用同一个通过规则。否则开启 `-R` 后,低置信度日志仍会按原来的“区域内”记录 `weak_present`,和上报语义不一致。
|
||||||
|
|
||||||
|
6. 日志名称建议保留现有兼容字段,同时增加模式信息:
|
||||||
|
- 正常模式下继续用 `strong_present`、`weak_present`、`filtered_workspace`。
|
||||||
|
- `-R` 模式下被过滤的目标本质是“命中排除区域”,建议日志里增加 `workspace_mode=reverse` 或新增 `filtered_reverse_workspace`,便于现场排查。
|
||||||
|
- 命令行输出的 `in result` / `not in result` 也建议区分“在多边形内”和“通过过滤后可上报”,避免 `-R` 模式下读日志误判。
|
||||||
|
|
||||||
|
## 边界约定
|
||||||
|
|
||||||
|
- `-R` 单独使用、未传 `-w` 时,当前默认 workspace 是全画面。如果直接反转,会变成全画面都被排除,导致无目标上报。建议实现时明确处理:
|
||||||
|
- 推荐方案:`-R` 必须配合 `-w` 使用;如果未传 `-w`,启动时报错并退出。
|
||||||
|
- 备选方案:未传 `-w` 时忽略 `-R` 并打印警告。这个更宽松,但容易让现场误以为反向过滤已生效。
|
||||||
|
|
||||||
|
- 多边形仍使用目标框中心点判断,不改成框与区域相交判断。这样和现有 `-w` 行为保持一致。
|
||||||
|
|
||||||
|
- `-P/--time-period`、阈值 `-r`、心跳、G1000 截图通知、同 `class_idx` 合并逻辑都不需要变化。
|
||||||
|
|
||||||
|
## 需要改动的文件
|
||||||
|
|
||||||
|
- `main.cpp`
|
||||||
|
- `long_options` 增加 `-R` 对应长参数。
|
||||||
|
- `getopt_long_only` 的短参数串加入 `R`。
|
||||||
|
- `case 'R'` 中设置全局反向开关。
|
||||||
|
- `print_usage` 的帮助信息补充 `-R` 说明。
|
||||||
|
|
||||||
|
- `vertix.h` / `vertix.cpp` 或其他公共配置位置
|
||||||
|
- 声明和定义反向 workspace 开关。
|
||||||
|
- 可选:封装一个 `is_box_allowed_by_workspace(...)`,把反转逻辑集中起来,避免 `rknn.cpp` 多处重复判断。
|
||||||
|
|
||||||
|
- `rknn.cpp`
|
||||||
|
- 上报候选过滤处使用统一的 `pass_workspace`。
|
||||||
|
- 低置信度 `weak_present` / `filtered_low_conf` 日志处同步使用统一规则。
|
||||||
|
- 日志追加 `workspace_mode=normal|reverse` 或新增反向过滤事件名。
|
||||||
|
|
||||||
|
- `README.md` 或运行说明文档
|
||||||
|
- 增加 `-R` 用法和示例。
|
||||||
|
|
||||||
|
## 验证计划
|
||||||
|
|
||||||
|
1. 编译验证:
|
||||||
|
- 按 `docs/cross_compile_wsl_linaro.md` 的 Linaro 路线构建。
|
||||||
|
- 确认 aarch64 产物正常生成,且不引入高版本 `glibc/libstdc++` 依赖。
|
||||||
|
|
||||||
|
2. 行为验证:
|
||||||
|
- 不带 `-R`:`-w` 内目标上报,外部目标过滤,行为和当前版本一致。
|
||||||
|
- 带 `-R -w ...`:`-w` 内目标过滤,外部目标上报。
|
||||||
|
- 带 `-R` 但不带 `-w`:按最终选定边界策略报错或警告。
|
||||||
|
|
||||||
|
3. 日志验证:
|
||||||
|
- 反向模式下能看出过滤原因是命中排除区域。
|
||||||
|
- `upload_positive` 和 `upload_positive_payload` 只出现于通过反向过滤后的区域外目标。
|
||||||
|
|
||||||
|
## 历史线索
|
||||||
|
|
||||||
|
`updata/main.cpp` 里曾出现过 `--reverse-detect` 和 `ReverseDetectBox = 1`,但当前主线 `main.cpp/rknn.cpp/vertix.*` 没有完整接入该变量。后续实现可以参考命名,但不要直接认为旧目录已经完成当前需求。
|
||||||
|
|
||||||
|
## 实现状态
|
||||||
|
|
||||||
|
已按本文方案实现:
|
||||||
|
|
||||||
|
- `main.cpp`:新增 `-R/--reverse-workspace`,并要求必须配合 `-w/--workspace` 使用。
|
||||||
|
- `vertix.cpp` / `vertix.h`:新增 `ReverseWorkspace` 开关和 workspace 模式说明函数。
|
||||||
|
- `rknn.cpp`:强置信上报候选和低置信日志都按 `ReverseWorkspace ? !in_workspace : in_workspace` 判定。
|
||||||
|
- `README.md`:补充 `-R` 参数、示例和日志说明。
|
||||||
|
|
||||||
|
构建验证已通过:
|
||||||
|
|
||||||
|
```text
|
||||||
|
wsl -d Ubuntu bash -lc "cd /mnt/c/Users/Smos.DESKTOP-6MT98U8/Desktop/yolov5-inference/build-aarch64 && cmake /mnt/c/Users/Smos.DESKTOP-6MT98U8/Desktop/yolov5-inference -DCMAKE_TOOLCHAIN_FILE=/mnt/c/Users/Smos.DESKTOP-6MT98U8/Desktop/yolov5-inference/toolchain-aarch64.cmake && make -j16 && file yolov5"
|
||||||
|
```
|
||||||
|
|
||||||
|
输出产物为 `ELF 64-bit LSB executable, ARM aarch64`。构建过程中出现 `Clock skew detected` 提示,属于 Windows/WSL 时间戳差异提示,不是本次代码编译错误。
|
||||||
@@ -96,8 +96,10 @@ static const char *help_info[100] = {
|
|||||||
"camera id",
|
"camera id",
|
||||||
"type id",
|
"type id",
|
||||||
"upload port",
|
"upload port",
|
||||||
"workspace, use comma spearated coordinate, like 0,1,2,3"
|
"workspace, use comma spearated coordinate, like 0,1,2,3",
|
||||||
"threshold, like 0.7, default is 0.6"};
|
"threshold, like 0.7, default is 0.6",
|
||||||
|
"time period, like 08:00:00-18:00:00",
|
||||||
|
"reverse workspace filter, upload targets outside -w"};
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
{"server", required_argument, NULL, 's'},
|
{"server", required_argument, NULL, 's'},
|
||||||
@@ -109,6 +111,7 @@ static struct option long_options[] = {
|
|||||||
{"workspace", required_argument, NULL, 'w'},
|
{"workspace", required_argument, NULL, 'w'},
|
||||||
{"threshold", required_argument, NULL, 'r'},
|
{"threshold", required_argument, NULL, 'r'},
|
||||||
{"time-period", required_argument, NULL, 'P'},
|
{"time-period", required_argument, NULL, 'P'},
|
||||||
|
{"reverse-workspace", no_argument, NULL, 'R'},
|
||||||
{0, 0, 0}};
|
{0, 0, 0}};
|
||||||
|
|
||||||
void print_usage(char *cmd)
|
void print_usage(char *cmd)
|
||||||
@@ -154,12 +157,13 @@ void parse_options(int argc, char **argv)
|
|||||||
float *points;
|
float *points;
|
||||||
int thresh;
|
int thresh;
|
||||||
conf_threshold = DEFAULT_CONF_THRESHOLD;
|
conf_threshold = DEFAULT_CONF_THRESHOLD;
|
||||||
|
ReverseWorkspace = false;
|
||||||
char *cmd = argv[0];
|
char *cmd = argv[0];
|
||||||
int ok;
|
int ok;
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
c = getopt_long_only(argc, argv, "es:m:w:c:t:p:r:P:", long_options, &option_index);
|
c = getopt_long_only(argc, argv, "es:m:w:c:t:p:r:P:R", long_options, &option_index);
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -209,12 +213,20 @@ void parse_options(int argc, char **argv)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'R':
|
||||||
|
ReverseWorkspace = true;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
print_usage(cmd);
|
print_usage(cmd);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ReverseWorkspace && !polygon_inited) {
|
||||||
|
printf("-R/--reverse-workspace must be used with -w/--workspace\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
if (!polygon_inited) {
|
if (!polygon_inited) {
|
||||||
init_polygon(NULL, 0);
|
init_polygon(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -658,19 +658,31 @@ int print_object_detect_result(rknn_app_context_t *rknn, object_detect_result_li
|
|||||||
int low_top = group->results[i].box.top;
|
int low_top = group->results[i].box.top;
|
||||||
int low_right = group->results[i].box.right;
|
int low_right = group->results[i].box.right;
|
||||||
int low_bottom = group->results[i].box.bottom;
|
int low_bottom = group->results[i].box.bottom;
|
||||||
if (group->results[i].prop >= LOW_CONF_SNAPSHOT_MIN && is_point_in_workspace(low_left, low_top, low_right, low_bottom))
|
bool low_in_workspace = is_point_in_workspace(low_left, low_top, low_right, low_bottom);
|
||||||
|
bool low_pass_workspace = ReverseWorkspace ? !low_in_workspace : low_in_workspace;
|
||||||
|
if (group->results[i].prop >= LOW_CONF_SNAPSHOT_MIN && low_pass_workspace)
|
||||||
{
|
{
|
||||||
detect_log_line("%s ts=%ld camera=%s weak_present frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f thresh=%f label=%s",
|
detect_log_line("%s ts=%ld camera=%s weak_present frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f thresh=%f label=%s workspace_mode=%s in_workspace=%d",
|
||||||
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
||||||
codes[group->results[i].cls_id], low_left, low_top, low_right, low_bottom,
|
codes[group->results[i].cls_id], low_left, low_top, low_right, low_bottom,
|
||||||
group->results[i].prop, conf_threshold, label);
|
group->results[i].prop, conf_threshold, label,
|
||||||
|
workspace_filter_mode(), low_in_workspace ? 1 : 0);
|
||||||
|
}
|
||||||
|
else if (group->results[i].prop >= LOW_CONF_SNAPSHOT_MIN)
|
||||||
|
{
|
||||||
|
detect_log_line("%s ts=%ld camera=%s filtered_workspace frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f label=%s workspace_mode=%s in_workspace=%d",
|
||||||
|
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
||||||
|
codes[group->results[i].cls_id], low_left, low_top, low_right, low_bottom,
|
||||||
|
group->results[i].prop, label,
|
||||||
|
workspace_filter_mode(), low_in_workspace ? 1 : 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
detect_log_line("%s ts=%ld camera=%s filtered_low_conf frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f min=%f label=%s",
|
detect_log_line("%s ts=%ld camera=%s filtered_low_conf frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f min=%f label=%s workspace_mode=%s in_workspace=%d",
|
||||||
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
||||||
codes[group->results[i].cls_id], low_left, low_top, low_right, low_bottom,
|
codes[group->results[i].cls_id], low_left, low_top, low_right, low_bottom,
|
||||||
group->results[i].prop, LOW_CONF_SNAPSHOT_MIN, label);
|
group->results[i].prop, LOW_CONF_SNAPSHOT_MIN, label,
|
||||||
|
workspace_filter_mode(), low_in_workspace ? 1 : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -679,16 +691,19 @@ int print_object_detect_result(rknn_app_context_t *rknn, object_detect_result_li
|
|||||||
int top = group->results[i].box.top;
|
int top = group->results[i].box.top;
|
||||||
int right = group->results[i].box.right;
|
int right = group->results[i].box.right;
|
||||||
int bottom = group->results[i].box.bottom;
|
int bottom = group->results[i].box.bottom;
|
||||||
|
bool in_workspace = is_point_in_workspace(left, top, right, bottom);
|
||||||
|
bool pass_workspace = ReverseWorkspace ? !in_workspace : in_workspace;
|
||||||
|
|
||||||
if (!is_point_in_workspace(left, top, right, bottom))
|
if (!pass_workspace)
|
||||||
{
|
{
|
||||||
printf("not in ");
|
printf(ReverseWorkspace ? "excluded " : "not in ");
|
||||||
if (should_log_detail)
|
if (should_log_detail)
|
||||||
{
|
{
|
||||||
detect_log_line("%s ts=%ld camera=%s filtered_workspace frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f label=%s",
|
detect_log_line("%s ts=%ld camera=%s filtered_workspace frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f label=%s workspace_mode=%s in_workspace=%d",
|
||||||
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
||||||
codes[group->results[i].cls_id], left, top, right, bottom,
|
codes[group->results[i].cls_id], left, top, right, bottom,
|
||||||
group->results[i].prop, label);
|
group->results[i].prop, label,
|
||||||
|
workspace_filter_mode(), in_workspace ? 1 : 0);
|
||||||
}
|
}
|
||||||
printf("result %2d: (%3d %3d %3d %3d) %f, %s\n", i, left, top, right, bottom, group->results[i].prop, label);
|
printf("result %2d: (%3d %3d %3d %3d) %f, %s\n", i, left, top, right, bottom, group->results[i].prop, label);
|
||||||
continue;
|
continue;
|
||||||
@@ -696,13 +711,14 @@ int print_object_detect_result(rknn_app_context_t *rknn, object_detect_result_li
|
|||||||
|
|
||||||
if (group->results[i].prop >= conf_threshold)
|
if (group->results[i].prop >= conf_threshold)
|
||||||
{
|
{
|
||||||
printf("in ");
|
printf(ReverseWorkspace ? "outside " : "in ");
|
||||||
if (should_log_detail)
|
if (should_log_detail)
|
||||||
{
|
{
|
||||||
detect_log_line("%s ts=%ld camera=%s strong_present frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f thresh=%f label=%s",
|
detect_log_line("%s ts=%ld camera=%s strong_present frame=%lld result=%2d code=%d box=(%3d %3d %3d %3d) prop=%f thresh=%f label=%s workspace_mode=%s in_workspace=%d",
|
||||||
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
now_text, now_ts, CameraID ? CameraID : "", frame_seq, i,
|
||||||
codes[group->results[i].cls_id], left, top, right, bottom,
|
codes[group->results[i].cls_id], left, top, right, bottom,
|
||||||
group->results[i].prop, conf_threshold, label);
|
group->results[i].prop, conf_threshold, label,
|
||||||
|
workspace_filter_mode(), in_workspace ? 1 : 0);
|
||||||
}
|
}
|
||||||
append_upload_box(¤t_objects[group->results[i].cls_id], left, top, right, bottom, group->results[i].prop, label);
|
append_upload_box(¤t_objects[group->results[i].cls_id], left, top, right, bottom, group->results[i].prop, label);
|
||||||
current_objects[group->results[i].cls_id].number += 1;
|
current_objects[group->results[i].cls_id].number += 1;
|
||||||
|
|||||||
+12
@@ -5,6 +5,7 @@
|
|||||||
#include "pose_body.h"
|
#include "pose_body.h"
|
||||||
|
|
||||||
Polygon workspace;
|
Polygon workspace;
|
||||||
|
bool ReverseWorkspace = false;
|
||||||
time_gap_t global_time_gap = {
|
time_gap_t global_time_gap = {
|
||||||
.in = 0,
|
.in = 0,
|
||||||
.size = 0,
|
.size = 0,
|
||||||
@@ -143,6 +144,17 @@ bool is_point_in_workspace(int left, int top, int right, int bottom)
|
|||||||
return inside;
|
return inside;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_box_allowed_by_workspace(int left, int top, int right, int bottom)
|
||||||
|
{
|
||||||
|
bool inside = is_point_in_workspace(left, top, right, bottom);
|
||||||
|
return ReverseWorkspace ? !inside : inside;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *workspace_filter_mode()
|
||||||
|
{
|
||||||
|
return ReverseWorkspace ? "reverse" : "normal";
|
||||||
|
}
|
||||||
|
|
||||||
// 获取今天的秒数
|
// 获取今天的秒数
|
||||||
int get_today_seconds() {
|
int get_today_seconds() {
|
||||||
time_t current_time;
|
time_t current_time;
|
||||||
|
|||||||
@@ -38,11 +38,14 @@ typedef struct
|
|||||||
} Polygon;
|
} Polygon;
|
||||||
|
|
||||||
extern Polygon workspace;
|
extern Polygon workspace;
|
||||||
|
extern bool ReverseWorkspace;
|
||||||
|
|
||||||
#define DUMP_POLYGON_INFO
|
#define DUMP_POLYGON_INFO
|
||||||
|
|
||||||
void init_polygon(float *datas, int size);
|
void init_polygon(float *datas, int size);
|
||||||
|
|
||||||
bool is_point_in_workspace(int left, int top, int right, int bottom);
|
bool is_point_in_workspace(int left, int top, int right, int bottom);
|
||||||
|
bool is_box_allowed_by_workspace(int left, int top, int right, int bottom);
|
||||||
|
const char *workspace_filter_mode();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Reference in New Issue
Block a user