70 lines
3.3 KiB
C
70 lines
3.3 KiB
C
#include "result_json.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
static const char* task_name(yolo_task_type_t task) {
|
|
switch (task) {
|
|
case YOLO_TASK_SEG: return "seg";
|
|
case YOLO_TASK_CLS: return "cls";
|
|
case YOLO_TASK_OBB: return "obb";
|
|
case YOLO_TASK_POSE: return "pose";
|
|
default: return "detect";
|
|
}
|
|
}
|
|
|
|
static void write_escaped(FILE* file, const char* text) {
|
|
for (const unsigned char* cursor = (const unsigned char*)text; cursor && *cursor; ++cursor) {
|
|
if (*cursor == '"' || *cursor == '\\') fputc('\\', file);
|
|
if (*cursor >= 0x20) fputc(*cursor, file);
|
|
}
|
|
}
|
|
|
|
int write_result_json(const char* path, const char* model_config, const yolo_result_list_t* report) {
|
|
if (!path || !model_config || !report) return -1;
|
|
FILE* file = fopen(path, "wb");
|
|
if (!file) return -2;
|
|
fprintf(file, "{\n \"schemaVersion\": \"1\",\n \"model\": \"");
|
|
write_escaped(file, model_config);
|
|
fprintf(file, "\",\n \"task\": \"%s\",\n", task_name(report->task));
|
|
fprintf(file, " \"performance\": {\"preprocessMs\": %.3f, \"inferenceMs\": %.3f, \"postprocessMs\": %.3f, \"totalMs\": %.3f},\n",
|
|
report->performance.preprocess_ms, report->performance.inference_ms,
|
|
report->performance.postprocess_ms, report->performance.total_ms);
|
|
fprintf(file, " \"results\": [");
|
|
for (int index = 0; index < report->count; ++index) {
|
|
const yolo_result_t* result = &report->results[index];
|
|
fprintf(file, "%s\n {\"task\": \"%s\", \"classId\": %d, \"label\": \"",
|
|
index ? "," : "", task_name(result->task), result->class_id);
|
|
write_escaped(file, result->label);
|
|
fprintf(file, "\", \"score\": %.6f", result->score);
|
|
if (result->task != YOLO_TASK_CLS) {
|
|
fprintf(file, ", \"bbox\": {\"x\": %.3f, \"y\": %.3f, \"width\": %.3f, \"height\": %.3f",
|
|
result->bbox.x, result->bbox.y, result->bbox.width, result->bbox.height);
|
|
if (result->bbox.has_angle) fprintf(file, ", \"angle\": %.6f", result->bbox.angle);
|
|
fputc('}', file);
|
|
}
|
|
if (result->task == YOLO_TASK_SEG) {
|
|
fprintf(file, ", \"maskBBox\": {\"x\": %.3f, \"y\": %.3f, \"width\": %.3f, \"height\": %.3f}",
|
|
result->mask_bbox.x, result->mask_bbox.y,
|
|
result->mask_bbox.width, result->mask_bbox.height);
|
|
fprintf(file, ", \"mask\": {\"width\": %d, \"height\": %d, \"strideBytes\": %d, \"originX\": %d, \"originY\": %d}",
|
|
result->mask_width, result->mask_height, result->mask_stride_bytes,
|
|
result->mask_origin_x, result->mask_origin_y);
|
|
}
|
|
if (result->task == YOLO_TASK_POSE) {
|
|
fputs(", \"keypoints\": [", file);
|
|
for (int keypoint = 0; keypoint < result->keypoint_count; ++keypoint) {
|
|
fprintf(file, "%s{\"x\": %.3f, \"y\": %.3f, \"score\": %.6f}",
|
|
keypoint ? "," : "",
|
|
result->keypoints[keypoint].x,
|
|
result->keypoints[keypoint].y,
|
|
result->keypoints[keypoint].score);
|
|
}
|
|
fputc(']', file);
|
|
}
|
|
fputc('}', file);
|
|
}
|
|
fprintf(file, "%s ]\n}\n", report->count ? "\n" : "");
|
|
fclose(file);
|
|
return 0;
|
|
}
|