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;
}