我用下面一段代码测试了oepncv SoftCascade的输出结构,测试模块已经有了,我只是将其提出来单独测试下,方便理解训练过程
#include <opencv\cv.h>
#include <opencv\highgui.h>
#include <opencv2\highgui.hpp>
#include <opencv2\softcascade.hpp>
#include <vector>
#include <fstream>
using namespace std;
using namespace cv::softcascade;
typedef vector<cv::String> svector;
class ScaledDataset : public Dataset
{
public:
ScaledDataset(const string& path, const int octave);
virtual cv::Mat get(SampleType type, int idx) const;
virtual int available(SampleType type) const;
virtual ~ScaledDataset();
private:
svector pos;
svector neg;
};
ScaledDataset::ScaledDataset(const string& path, const int oct)
{
cv::glob(path + cv::format("/octave_%d/*.png", oct), pos);
cv::glob(path + "/*.png", neg);
// Check: files not empty
CV_Assert(pos.size() != size_t(0));
CV_Assert(neg.size() != size_t(0));
}
cv::Mat ScaledDataset::get(SampleType type, int idx) const
{
const std::string& src = (type == POSITIVE)? pos[idx]: neg[idx];
return cv::imread(src);
}
int ScaledDataset::available(SampleType type) const
{
return (int)((type == POSITIVE)? pos.size():neg.size());
}
ScaledDataset::~ScaledDataset(){}
int main( int argc, char** argv )
{
//配置SoftCascade的参数文件
//参考了源码里面test_softcascade的部分
string configXmlPath = "SoftCascade_config.xml";//cv::tempfile(".xml");
cv::FileStorage fso(configXmlPath, cv::FileStorage::WRITE);
if(!fso.isOpened())
{
cout<<"Can't open file "<<configXmlPath<<"..."<<endl;
}
std::vector<int> octaves;
{
//这里面看你要设置几个octave了,论文没细看
//大致是用来训练各个尺度的模型然后不用图像放缩从而提高速度的方法
//最好用4到5个吧 为什么? 直觉。。。做sift的时候也用了5个不是么
octaves.push_back(-1);
octaves.push_back(0);
}
fso << "regression-cascade"
<< "{"
<< "stageType" << "BOOST"
<< "featureType" << "ICF"
<< "octavesNum" << 5
<< "width" << 64
<< "height" << 128
<< "shrinkage" << 4
<< "octaves" << "[";
for (std::vector<int>::const_iterator it = octaves.begin(); it != octaves.end(); ++it)
{
int nfeatures = 100;
int shrinkage = 4;
float octave = powf(2.f, (float)(*it));
cv::Size model = cv::Size( cvRound(64 * octave) / shrinkage, cvRound(128 * octave) / shrinkage );//这里面的64和128是宽和高,做样本的时候要注意octave是原图片,然后负方向是缩小的,正方向是放大的
cv::Ptr<FeaturePool> pool = FeaturePool::create(model, nfeatures, 10);
nfeatures = pool->size();
int npositives = 10;
int nnegatives = 20;
cv::Rect boundingBox = cv::Rect( cvRound(20 * octave), cvRound(20 * octave),
cvRound(64 * octave), cvRound(128 * octave));
cv::Ptr<ChannelFeatureBuilder> builder = ChannelFeatureBuilder::create("HOG6MagLuv");
cv::Ptr<Octave> boost = Octave::create(boundingBox, npositives, nnegatives, *it, shrinkage, builder);
std::string path = "cascadeandhog/sample_training_set";
ScaledDataset dataset(path, *it);
if (boost->train(&dataset, pool, 3, 2))
{
cv::Mat thresholds;
boost->setRejectThresholds(thresholds);
//boost->write(fso, pool, thresholds);
}
}
fso << "]" << "}";
fso.release();
cv::FileStorage actual(configXmlPath, cv::FileStorage::READ);
cv::FileNode root = actual.getFirstTopLevelNode();
cv::FileNode fn = root["octaves"];
cout<<configXmlPath<<endl;
getchar();
return 0;
}