样本的抠取和制备是训练模型的基础,在做图像识别的时候,具体的思路是:
软件抠取(得到txt)—-Rect区域截取—训练(or)测试样本的制取;
1.软件
这里用到一款强大的软件,可实现video和image的抠取(图较大时会有bug),按save Gt会保存一个txt文件,里面对应(image.jpg,样本数;下一行对应目标rect区域)
软件下载地址: 链接: http://pan.baidu.com/s/1o8bIPIE 密码: mb4a
2.Rect区域截取
(1)图片
#include "opencv2/opencv.hpp"
#include "opencv2/ml.hpp"
#include <stdio.h>
#include <string.h>
#include <cctype>
#include<iostream>
#include <fstream>
using namespace cv;
using namespace cv::ml;
using namespace std;
void ImgRectExtraction()
{
double x, y, w, h;
char c;
int frameno, carcnt;
Rect TrainRec;
char path[512];
int nFramNum = 0;
//解析文本
char filename[256];
string buffer;
vector<string> imagePath;
Mat trainImage;
CvSize winSize = cvSize(45, 27);
ifstream trainingData("C:\\Users\\Administrator\\Desktop\\resize\\题号目标.txt");
while (1)
{
if (trainingData.is_open())
{
if (!trainingData.eof())//pos文件结束
{
trainingData >> frameno >> c >> carcnt;
sprintf(filename, "C:\\Users\\Administrator\\Desktop\\resize\\%d.jpg", frameno);
Mat src = imread(filename);
if (NULL != src.data)
{
for (int j = 0; j < carcnt; ++j)
{
trainingData >> x >> c >> y >> c >> w >> c >> h;
TrainRec.x = x;
TrainRec.y = y;
TrainRec.width = w;
TrainRec.height = h;
resize(src(TrainRec), trainImage, winSize);
printf("%d %d\n", nFramNum, frameno);
sprintf(path, "E:\\GeekBigData\\image\\trainimg\\NUM\\%d.jpg", nFramNum);
imwrite(path, trainImage);
//rectangle(src, TrainRec, CV_RGB(255, 0, 0));
imshow("trainImage", trainImage);
waitKey(10);
nFramNum++;
}
}
}
}
else
break;
}
}
(2)video
#include "opencv2/opencv.hpp"
#include "opencv2/ml.hpp"
#include <stdio.h>
#include <string.h>
#include <cctype>
#include<iostream>
#include <fstream>
using namespace cv;
using namespace cv::ml;
using namespace std;
#define FILEPATH "E:/BSD视频/标记样本/ROItxt/别人采集的txt/"
CvRect rect;
int ImgProcesse()
{
VideoCapture cap("E:\\BSD视频\\80km.h\\800_SYNC.avi");
Mat fram;
Mat Riofram;
string buffer;
ifstream trainingData(string(FILEPATH)+"8_R.txt");
unsigned long n;
double x,y,w,h;
char c;
int frameno,carcnt;
Rect TrainRec;
char path[512];
int nFramNum = 2268;
//解析文本
while(1)
{
if( trainingData.is_open())
{
if(!trainingData.eof())//pos文件结束
{
trainingData >> frameno >> c >> carcnt;//frameno,carcnt对应groundtruth中的帧号及当前帧下的车数目
cap>>fram;
if(!fram.data)
{
break;
}
Riofram = fram(Rect(0,0,600,500));
for(int i = 0;i < carcnt;++i)
{
float g;
trainingData>> x >> c >> y >> c>> w >> c >>h;
printf("%f\t", (float) (max(w, h) / min(w, h)));
if(float (max(w, h) / min(w, h)) < 1.2)///这部分可根据图片的要求修改
{
TrainRec.x = x;
TrainRec.y = y;
TrainRec.width = max(w, h);
TrainRec.height = max(w, h);
printf("%d\n",nFramNum);
sprintf(path,"E:\\BSD视频\\标记样本\\样本图\\别人采集的图\\正样本\\right\\8\\%04d.bmp",nFramNum);
imwrite(path, fram(TrainRec));
//rectangle(Riofram,TrainRec,CV_RGB(255,0,0));
nFramNum++;
}
}
}
imshow("Train_Rio",Riofram);
waitKey(10);
}
}
return 1;
}
3.训练(or)测试样本的制取
将得到的rect图片找到索引位置并赋予标签
#include "opencv2/opencv.hpp"
#include <iostream>
#include <fstream>
using namespace std;
using namespace cv;
int save_Txt()
{
int i;
char filename[256];
ofstream config_file;
config_file.open("E:\\GeekBigData\\image\\trainimg\\C.txt",ios::out );
for(i = 0; i < 5000; i++)
{
sprintf(filename , "E:\\GeekBigData\\image\\trainimg\\C\\%d.jpg" , i );
IplImage* src = cvLoadImage(filename,1);
if((src != NULL))
{
cvShowImage( "src", src);
cvWaitKey(10);
config_file << filename << endl << 3 << endl;///对应标签按要求修改
printf("%d\n", i);
cvReleaseImage(&src);
}
}
config_file.close();
return 1;
}
完整代码请见: