以下是以Doxygen标准添加的中文注释:
/**
* @brief 检测图像中的目标。
*
* 此函数接收一帧图像,使用 YOLOv8 模型进行目标检测,并绘制检测结果。
*
* @param frame 输入的 cv::Mat 类型图像,表示待检测的图像帧。
*/
void YOLOV8::detect(cv::Mat& frame)
{
int neww = 0, newh = 0, padw = 0, padh = 0;
// 调整输入图像的大小
cv::Mat simg = this->resize_img(frame, &neww, &newh, &padw, &padh);
// 创建用于神经网络输入的 blob
cv::Mat blob = cv::dnn::blobFromImage(simg, 1.0 / 255.0,
cv::Size(this->inpHeight, this->inpWidth),
cv::Scalar(0, 0, 0), true, false);
// 设置网络输入
this->net.setInput(blob);
std::vector<cv::Mat> outs;
// 前向传播获取输出
this->net.forward(outs, this->net.getUnconnectedOutLayersNames());
int numproposal = outs[0].size[2]; // 获取提案数量
int nout = outs[0].size[1]; // 获取输出维度
outs[0] = outs[0].reshape(0, nout); // 重塑输出矩阵形状
cv::transpose(outs[0], outs[0]); // 转置输出矩阵
std::vector<int> ids; // 存储类别 ID 的向量
std::vector<float> confs; // 存储置信度的向量
std::vector<cv::Rect> boxes; // 存储边界框的向量
float ratiow = (float)frame.cols / neww; // 原始宽度与新宽度的比例
float ratioh = (float)frame.rows / newh; // 原始高度与新高度的比例
float* pdata = (float*)outs[0].data; // 输出数据指针
for (int n = 0; n < numproposal; ++n)
{
float maxss = 0.0;
int idp = 0;
// 找到最大置信度及其对应类别 ID
for (int k = 0; k < nout - 4; ++k)
{
if (pdata[k + 4] > maxss)
{
maxss = pdata[k + 4];
idp = k;
}
}
// 如果最大置信度大于阈值,则保存检测结果
if (maxss >= this->confThreshold)
{
float cx = (pdata[0] - padw) * ratiow;
float cy = (pdata[1] - padh) * ratioh;
float w = pdata[2] * ratiow;
float h = pdata[3] * ratioh;
int left = int(cx - 0.5 * w);
int top = int(cy - 0.5 * h);
boxes.push_back(cv::Rect(left, top, int(w), int(h)));
confs.push_back(maxss);
ids.push_back(idp);
}
pdata += nout; // 移动到下一个提案数据位置
}
// 应用非极大抑制(NMS)以消除冗余框
std::vector<int> indices;
cv::dnn::NMSBoxes(boxes, confs, this->confThreshold, this->nmsThreshold, indices);
// 绘制最终检测到的目标结果
for (int idx : indices)
this->drawPred(frame, boxes[idx], ids[idx], confs[idx]);
}
这些注释详细描述了函数的功能、参数以及其内部逻辑,有助于其他开发者理解代码。
内容由零声教学AI助手提供,问题来源于学员提问