void YOLO::postprocess(Mat& frame,const vector<Mat>& outs)// Remove the bounding boxes with low confidence using non-maxima suppression {
vector<int> classIds;
vector<float> confidences;
vector<Rect> boxes;
for(size_t i =0; i < outs.size();++i)
{
// Scan through all the bounding boxes output from the network and keep only the
// ones with high confidence scores. Assign the box's class label as the class
// with the highest score for the box.
// outs[i]每⼀⾏有85个元素,头四个元素代表center_x, center_y, width和height。第五个元素表⽰包含着⽬标的边界框的置信度。
// 剩下80个元素是和每个类别(如⽬标种类coconame⾥⾯定义的)有关的置信度
rectangle函数opencvfloat* data =(float*)outs[i].data;
for(int j =0; j < outs[i].rows;++j, data += outs[i].cols)
{
cv::Mat look = outs[i];
Mat scores = outs[i].row(j).colRange(5, outs[i].cols);//取每⼀⾏后80个元素,即每⼀类对应的置信度
Point classIdPoint;
double confidence;
// Get the value and location of the maximum score
minMaxLoc(scores,0,&confidence,0,&classIdPoint);
if(confidence >this->confThreshold)
{
int centerX =(int)(data[0]* ls);
int centerY =(int)(data[1]* ws);
int width =(int)(data[2]* ls);
int height =(int)(data[3]* ws);
int left = centerX - width /2;
int top = centerY - height /2;
classIds.push_back(classIdPoint.x);//记录对应的类
confidences.push_back((float)confidence);//记录对应类的置信度
boxes.push_back(Rect(left, top, width, height));//记录包围框
}
}
}
// Perform non maximum suppression to eliminate redundant overlapping boxes with
// lower confidences
vector<int> indices;
NMSBoxes(boxes, confidences,this->confThreshold,this->nmsThreshold, indices);
for(size_t i =0; i < indices.size();++i)
{
int idx = indices[i];
Rect box = boxes[idx];
this->drawPred(classIds[idx], confidences[idx], box.x, box.y,
box.x + box.width, box.y + box.height, frame);
}
}
void YOLO::drawPred(int classId,float conf,int left,int top,int right,int bottom, Mat& frame)// Draw the predicted bounding box
{
//Draw a rectangle displaying the bounding box
rectangle(frame,Point(left, top),Point(right, bottom),Scalar(0,0,255),3);
//Get the label for the class name and its confidence
string label =format("%.2f", conf);
if(!this-&pty())
{
CV_Assert(classId <(int)this->classes.size());
label =this->classes[classId]+":"+ label;
}
//Display the label at the top of the bounding box
//Display the label at the top of the bounding box
int baseLine;
Size labelSize =getTextSize(label, FONT_HERSHEY_SIMPLEX,0.5,1,&baseLine);
top =max(top, labelSize.height);
//rectangle(frame, Point(left, top - int(1.5 * labelSize.height)), Point(left + int(1.5 * labelSize.width), top + baseLine), Scalar(0, 255, 0), FILLED); putText(frame, label,Point(left, top), FONT_HERSHEY_SIMPLEX,0.75,Scalar(0,255,0),1);
}
void YOLO::detect(Mat& frame)
{
//将输⼊图像frame转为神经⽹络的输⼊类型bolb,图像像素值从0~255归⼀化到0~1,并调整尺⼨为--Size(this->inpWidth, this->inpHeight)
Mat blob;
blobFromImage(frame, blob,1/255.0,Size(this->inpWidth,this->inpHeight),Scalar(0,0,0),true,false);
//设置⽹络输⼊
this->net.setInput(blob);
vector<Mat> outs;
//Runs the forward pass to get output of the output layers 运⾏前向⽹络得到输出
this->net.forward(outs,this-&UnconnectedOutLayersNames());
//去掉置信度过低的包围框
this->postprocess(frame, outs);
vector<double> layersTimes;
double freq =getTickFrequency()/1000;
//Put efficiency information. The function getPerfProfile returns the
//overall time for inference(t) and the timings for each of the layers(in layersTimes)
double t = PerfProfile(layersTimes)/ freq;
string label =format("%s Inference time : %.2f ms",this->netname, t);
putText(frame, label,Point(0,30), FONT_HERSHEY_SIMPLEX,1,Scalar(0,0,255),2);
//imwrite(format("%s_out.jpg", this->netname), frame);
}
int main()
{
YOLO yolo_model(yolo_nets[0]);
string imgpath ="person.jpg";
Mat srcimg =imread(imgpath);
yolo_model.detect(srcimg);
static const string kWinName ="Deep learning object detection in OpenCV";
namedWindow(kWinName, WINDOW_NORMAL);
imshow(kWinName, srcimg);
waitKey(10);
destroyAllWindows();
}
三、跟踪结果
跟踪速度还算可以,⽤GPU可能会快点
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论