#include<iostream>
#include<stdio.h>
#include<vector>
#include<fstream>
#include<opencv2/opencv.hpp>
#define video_index_max 101
/************************************************************************
函数功能:从已经获取ucf101数据集所有类名称的txt文件中读入视频类别名称,共101类
输入参数:filename是.txt文件路径,videoname是保存101类的名称
输出参数:
************************************************************************/
void ReadVideoClass(const std::string& filename, std::vector<std::string>&videoname)
{
std::fstream file0;
file0.open(filename);
if (!file0.is_open())
{
std::cerr << "fail to open the all name file" << std::endl;
exit(0);
}
char temp0[1000];
while (!file0.eof())
{
file0.getline(temp0, 1000);
std::string line(temp0);
videoname.push_back(line);
}
if (videoname.size() != video_index_max) //如果读入的所有名称数量小于101类,则输入文件有误
{
std::cerr << " video class file have error size" << std::endl;
exit(0);
}
file0.close();
}
/************************************************************************
函数功能:获取所有的从C3D网络输出并保存的.prob文件的路径
输入参数:filename是.txt文件路径,videoname是保存101类的名称
输出参数:
************************************************************************/
void ReadAllTestResultPath(const std::string& filename, std::vector<std::string>&ResultPath)
{
std::fstream file1;
file1.open(filename);//读取视频文件路径
if (!file1.is_open())
{
std::cerr << "fail to open the test result file" << std::endl;
exit(0);
}
char temp[1000];
while (!file1.eof())
{
file1.getline(temp, 1000);
std::string line(temp);
//去除可能存在的空格,并添加后缀.prob
std::string PostfixLine;//测试结果文件保存路径
std::string::size_type npos0 = line.find_last_of(" ");
if (npos0 == line.size() - 1) {
PostfixLine = line.substr(0, npos0);
PostfixLine += ".prob";
}
else
PostfixLine = line + ".prob";
std::cout << PostfixLine << std::endl;
ResultPath.push_back(PostfixLine);
}
file1.close();
}
/************************************************************************
函数功能:
输入参数:
输出参数:
************************************************************************/
void ReadLine(const std::string & path, std::string &Videopath, int &StartIndex, std::string& ground_truth)
{
std::string line = path;
StartIndex = atoi(line.substr(line.find_last_of("/") + 1, line.size() - 5).c_str());
ground_truth = line.substr(line.find("output/") + strlen("output/"), line.find("/v_") - strlen("output/"));
line.erase(0, 6); line.erase(line.find_last_of("/"), line.size());
line.insert(0, "F:/ucf101"); line += ".avi";
Videopath = line;
}
/************************************************************************
函数功能:从.prob文件中读入C3D网络的输出结果
输入参数:.prob文件路径
输出参数:101类的预测输出结果 blob
************************************************************************/
bool read_blob(const std::string &probfile, std::vector<float>&blob)
{
/*读取模型提取的特征文件中的参数*/
std::ifstream fin(probfile, std::ios::binary);
if (!fin.is_open()) { std::cerr << probfile << "file not exist " << std::endl; return 0; }
int num = 0, channel = 0, length = 0, height = 0, width = 0;
fin.read((char*)&num, sizeof(int));
fin.read((char*)&channel, sizeof(int)); if (channel != video_index_max) return 0;
fin.read((char*)&length, sizeof(int)); fin.read((char*)&height, sizeof(int));
fin.read((char*)&width, sizeof(int));
float ptr = 0;
for (int i = 0; i < channel; i++)
{
fin.read((char*)&ptr, sizeof(float));
blob.push_back(ptr);
}
return 1;
}
/************************************************************************
函数功能:从数组vec中找出最大值,返回最大值和最大值对应的序号
输入参数:数组vec,数组大小num,引用返回的数组最大值rate
输出参数:最大值对应的序号
************************************************************************/
int find_sec_max(std::vector<float>vec, int num, float &rate)
{
int index = -1;
if (vec.size() != num)
return -1;
float maxc = 0;
for (int i = 0; i < vec.size(); i++)
{
if (vec[i]>maxc)
{
maxc = vec[i]; index = i;
}
}
rate = maxc;
return index;
}
int main()
{
using namespace std;
using namespace cv;
std::vector<std::string>videoname;
ReadVideoClass("output\\list.txt", videoname);
std::vector<std::string>ResultPath;
ReadAllTestResultPath("output\\last-test-output.lst", ResultPath);
VideoWriter writer("VideoTest.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25.0, Size(320, 240));
vector<string>TestResultAll;
vector<float>TestResultAllRate;
vector<string>GroundTrueAll;
for (size_t i = 0; i < ResultPath.size(); i++)
{
std::string Videopath; int StartIndex; std::string ground_truth;
ReadLine(ResultPath[i], Videopath, StartIndex, ground_truth);
std::vector<float>blob;
int flag = read_blob(ResultPath[i], blob);
if (!flag) { cerr << "blob read failed" << endl; exit(0); }
float maxrate = 0;
int TestResult = find_sec_max(blob, video_index_max, maxrate);
VideoCapture capture;
capture.open(Videopath);
int count = StartIndex;
int countcopy = count;
Mat frame;
while (countcopy--)//每次写视频时,都跳过前count帧开始写
{
capture >> frame;
}
while (count < StartIndex + 16)//每个视频段的大小都是16帧,
{
capture >> frame;//先读入至frame中
writer << frame;//将frame保存到writer中
TestResultAll.push_back(videoname[TestResult]);//每一帧都赋予一个检测结果(string类型),并将检测结果保存在TestResultAll中
TestResultAllRate.push_back(maxrate);//每一帧每一帧都赋予一个检测概率(float类型),并将检测概率值保存在TestResultAllRate中
GroundTrueAll.push_back(ground_truth);//每一帧都有一个ground truth
count++;
}
}
//writer.release();
VideoCapture writercapture; writercapture.open("VideoTest.avi");
VideoWriter VideoTest("VideoTestAll.avi", CV_FOURCC('M', 'J', 'P', 'G'), 25.0, Size(320, 240));
int count = 0;
while (1)
{
Mat frame;
writercapture >> frame;
if (!frame.data)
break;
string result = TestResultAll[count];
float ratio = TestResultAllRate[count];
char stemp[200];
sprintf(stemp, "( %.3f )", ratio);
string truth = GroundTrueAll[count];
cv::putText(frame, "test result: " + result + stemp, cv::Point(5, 25), CV_FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 255, 255));
cv::putText(frame, "ground truth: " + truth, cv::Point(5, 48), CV_FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 255));
imshow("frame", frame);
waitKey(30);
VideoTest << frame;
count++;
}
VideoTest.release();
return 0;
}
C3D
最新推荐文章于 2022-01-05 21:06:28 发布