-- 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;
解析目标发现,有多个非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("CopyImageToLocal failed");
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 < num_elements; ++i)
{
float_data[i] = static_cast<float>(raw_data[i]) / 255.0f; // 如果是8位数据,则通常将其归一化
if (float_data[i] <= minValue)
{
minValue = float_data[i];
}
if (float_data[i] >= maxValue)
{
maxValue = float_data[i];
}
}
printf("minValue = %f, maxValue = %f\n", 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<uint8_t>(reinterpret_cast<uint8_t*>(float_data), [](uint8_t *p) { delete[] reinterpret_cast<float*>(p); });
hostImage.size = num_elements * sizeof(float);
// 拷贝到设备
ImageData deviceImage;
ret = CopyImageToDevice(deviceImage, hostImage, g_runMode_, MEMORY_DEVICE);
if (ret != ACLLITE_OK) {
ACLLITE_LOG_ERROR("CopyImageToDevice failed");
return ACLLITE_ERROR;
}
// 执行推理
ret = g_model_.CreateInput(deviceImage.data.get(), deviceImage.size,
g_imageInfoBuf_, g_imageInfoSize_);
请帮忙排查一下aipp的问题和opencv进行色域转换时是否有不合理的地方,谢谢!
-- 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("CopyImageToLocal failed");
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 < num_elements; ++i)
{
float_data[i] = static_cast<float>(raw_data[i]) / 255.0f; // 如果是8位数据,则通常将其归一化
if (float_data[i] <= minValue)
{
minValue = float_data[i];
}
if (float_data[i] >= maxValue)
{
maxValue = float_data[i];
}
}
printf("minValue = %f, maxValue = %f\n", 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<uint8_t>(reinterpret_cast<uint8_t*>(float_data), [](uint8_t *p) { delete[] reinterpret_cast<float*>(p); });
hostImage.size = num_elements * sizeof(float);
// 拷贝到设备
ImageData deviceImage;
ret = CopyImageToDevice(deviceImage, hostImage, g_runMode_, MEMORY_DEVICE);
if (ret != ACLLITE_OK) {
ACLLITE_LOG_ERROR("CopyImageToDevice failed");
return ACLLITE_ERROR;
}
// 执行推理
ret = g_model_.CreateInput(deviceImage.data.get(), deviceImage.size,
g_imageInfoBuf_, g_imageInfoSize_);
请帮忙排查一下aipp的问题和opencv进行色域转换时是否有不合理的地方,谢谢!