yolov5推理结果不正确
收藏回复举报
yolov5推理结果不正确
t('forum.solved') 已解决
发表于2023-08-14 09:40:28
0 查看

-- CANN 版本 : 6.2.RC2
--Python 版本 Python 3.7.5
--操作系统版本 Ubuntu 22.04


在Ascend200I DK A2上,调用AscendCL接口进行数据预处理推理结果错误。模型是单类别模型,没有增加aipp(调用ais_bench接口)预测结果正确;使用AscendCL C++接口对模型进行推理,增加aipp预测出来的类别有多种,并且可能预测出非目标的置信度在0到100之外的噪点。
同样的模型和代码已在Atlas200 DK和Atlas300I Pro上进行了验证,增加aipp(使用AscendCL)结果均正确,在Atlas200I DK A2结果有误。
初步定位是DVPP预处理或者AIPP的问题
模型为v5s.pt
onnx模型为v5s_nms.onnx
转换后的om模型为v5s_nms_aipp_bt709_narrow.om
输入为rtsp视频流

测试时输入的文件为video1080p.mp4
模型文件等放在了链接:https://pan.baidu.com/s/1ffq0H9ZLxvohNw3rqCh5gA
提取码:30ho

模型的输入是1280*1280,使用的样例为https://gitee.com/ascend/samples/tree/master/cplusplus/level2_simple_inference/2_object_detection/YOLOV3_coco_detection_video_DVPP_with_AIPP
将其中的yolov3模型替换成了我自己的yolov5模型,其中需要对模型输出的检测框进行重新解析,后处理的解析代码如下,后处理解析代码已在atlas300I Pro和atlas200DK上验证无误。

uint32_t sliceBoxNum[4] = {0};
float widthScale = (float) (g_videoWidth) / g_modelInputWidth;
float heightScale = (float) (g_videoHeight) / g_modelInputHeight;
vector sliceDetectResults[split_num];
for (int index = 0; index < batch_size * split_num; index++) {
int shift = index * batch_size * split_num;
int totalBox = (int) boxNum[shift * 2 + 0];
sliceBoxNum[index] = 0;

// 偏移值
int shift2 = index * 6 * 1024;
for (int i = 0; i < totalBox; i++) {
    BBox boundBox;
    boundBox.score = (detectData[shift2 + totalBox * SCORE + i] * 100);
    boundBox.rect.ltX = (uint32_t) detectData[shift2 + totalBox * TOPLEFTX + i];
    boundBox.rect.ltY = (uint32_t) detectData[shift2 + totalBox * TOPLEFTY + i];
    boundBox.rect.rbX = (uint32_t) detectData[shift2 + totalBox * BOTTOMRIGHTX + i];
    boundBox.rect.rbY = (uint32_t) detectData[shift2 + totalBox * BOTTOMRIGHTY + i];
    boundBox.cls = (uint32_t) detectData[shift2 + totalBox * LABEL + i];

    printf("score = %f, ltX = %d, ltY = %d, rbX = %d, rbY = %d, objIndex = %d\n", boundBox.score,
           boundBox.rect.ltX, boundBox.rect.ltY, boundBox.rect.rbX, boundBox.rect.rbY, boundBox.cls);
    sliceDetectResults[index].emplace_back(boundBox);
    sliceBoxNum[index]++;           
}

解析目标发现,有多个非0标签的目标,并且置信度也不合理。
score = 194.433594, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 191.894531, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 195.996094, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 191.210938, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 189.160156, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 184.179688, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 185.839844, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 182.421875, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 180.371094, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 179.199219, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1
score = 177.246094, ltX = 1, ltY = 1, rbX = 1, rbY = 1, objIndex = 1

尝试使用opencv代替aipp的色域转换功能,但是没有预测到任何目标

// 拷贝到本地

ImageData localImage;

ret = CopyImageToLocal(localImage, resizedImage, g_runMode_);

if (ret != ACLLITE_OK) {

    ACLLITE_LOG_ERROR(&quot;CopyImageToLocal failed&quot;);

    return ACLLITE_ERROR;

}

// 使用 opencv 的 COLOR_YUV2BGR_NV12 进行转换

cv::Mat yuvImage(localImage.height * 3 / 2, localImage.width, CV_8UC1, localImage.data.get());

cv::Mat bgrImage;

cv::cvtColor(yuvImage, bgrImage, cv::COLOR_YUV2BGR_NV12);

// 创建新的shared_ptr来保存floatImg数据

// 4915200 = 1638400 * 3

int num_elements = bgrImage.total() * bgrImage.channels();

float* float_data = new float[num_elements];

uint8_t* raw_data = bgrImage.data;

float minValue = 10000000;

float maxValue = -1;

for (size_t i = 0; i &lt; num_elements; ++i)

{

    float_data[i] = static_cast&lt;float&gt;(raw_data[i]) / 255.0f; // 如果是8位数据,则通常将其归一化

    if (float_data[i] &lt;= minValue)

    {

        minValue = float_data[i];

    }

    if (float_data[i] &gt;= maxValue)

    {

        maxValue = float_data[i];

    }

}

printf(&quot;minValue = %f, maxValue = %f\n&quot;, minValue, maxValue);

ImageData hostImage;

hostImage.width = localImage.width;

hostImage.height = localImage.height;

hostImage.alignWidth = localImage.alignWidth;

hostImage.alignHeight = localImage.alignHeight;

hostImage.data = std::shared_ptr&lt;uint8_t&gt;(reinterpret_cast&lt;uint8_t*&gt;(float_data), [](uint8_t *p) { delete[] reinterpret_cast&lt;float*&gt;(p); });

hostImage.size = num_elements * sizeof(float);

// 拷贝到设备

ImageData deviceImage;

ret = CopyImageToDevice(deviceImage, hostImage, g_runMode_, MEMORY_DEVICE);

if (ret != ACLLITE_OK) {

    ACLLITE_LOG_ERROR(&quot;CopyImageToDevice failed&quot;);

    return ACLLITE_ERROR;

}

// 执行推理

ret = g_model_.CreateInput(deviceImage.data.get(), deviceImage.size,

                        g_imageInfoBuf_, g_imageInfoSize_);

请帮忙排查一下aipp的问题和opencv进行色域转换时是否有不合理的地方,谢谢!

我要发帖子