目前做目标检测最好的一个算法。
基本是下面两篇博客的拼接,算不上原创,挂羊头卖狗肉,看官见谅。
pozen同学的博客:http://blog.youkuaiyun.com/pozen/article/details/7023742
Json_Nie同学的博客:http://blog.youkuaiyun.com/dreamd1987/article/details/7396620
我的环境如题:Win7+VS2010+Matlab2011b。
将voc-release4.01压缩包解压后,进行下列修改和操作能运行demo()文件了。
1,dt.cc 添加一句:#define int32_t int
2,features.cc & resize.cc中添加:
#define bzero(a, b) memset(a, 0, b)
int round(float a) { float tmp = a - (int)a; if( tmp >= 0.5 ) return (int)a + 1; else return (int)a; }
3,resize.cc中: alphainfo ofs[len]; 这句改成:alphainfo *ofs = new alphainfo[len]; 当然在同一作用域后面加上:delete []ofs,下面是Json_Nie贴出的代码,可以帮助我们准确放置delete [] ofs:
- #include <math.h>
- #include <assert.h>
- #include <string.h>
- #include "mex.h"
- #define bzero(a, b) memset(a, 0, b)
- int round(float a) { float tmp = a - (int)a; if( tmp >= 0.5 ) return (int)a + 1; else return (int)a; }
- // struct used for caching interpolation values
- struct alphainfo {
- int si, di;
- double alpha;
- };
- // copy src into dst using interpolation values
- void alphacopy(double *src, double *dst, struct alphainfo *ofs, int n) {
- struct alphainfo *end = ofs + n;
- while (ofs != end) {
- dst[ofs->di] += ofs->alpha * src[ofs->si];
- ofs++;
- }
- }
- // resize along each column
- // result is transposed, so we can apply it twice for a complete resize
- void resize1dtran(double *src, int sheight, double *dst, int dheight,
- int width, int chan) {
- double scale = (double)dheight/(double)sheight;
- double invscale = (double)sheight/(double)dheight;
- // we cache the interpolation values since they can be
- // shared among different columns
- int len = (int)ceil(dheight*invscale) + 2*dheight;
- //alphainfo ofs[len];
- alphainfo *ofs = new alphainfo[len];
- int k = 0;
- for (int dy = 0; dy < dheight; dy++) {
- double fsy1 = dy * invscale;
- double fsy2 = fsy1 + invscale;
- int sy1 = (int)ceil(fsy1);
- int sy2 = (int)floor(fsy2);
- if (sy1 - fsy1 > 1e-3) {
- assert(k < len);
- assert(sy1-1 >= 0);
- ofs[k].di = dy*width;
- ofs[k].si = sy1-1;
- ofs[k++].alpha = (sy1 - fsy1) * scale;
- }
- for (int sy = sy1; sy < sy2; sy++) {
- assert(k < len);
- assert(sy < sheight);
- ofs[k].di = dy*width;
- ofs[k].si = sy;
- ofs[k++].alpha = scale;
- }
- if (fsy2 - sy2 > 1e-3) {
- assert(k < len);
- assert(sy2 < sheight);
- ofs[k].di = dy*width;
- ofs[k].si = sy2;
- ofs[k++].alpha = (fsy2 - sy2) * scale;
- }
- }
- // delete [] ofs;
- // resize each column of each color channel
- bzero(dst, chan*width*dheight*sizeof(double));
- for (int c = 0; c < chan; c++) {
- for (int x = 0; x < width; x++) {
- double *s = src + c*width*sheight + x*sheight;
- double *d = dst + c*width*dheight + x;
- alphacopy(s, d, ofs, k);
- }
- }
- delete [] ofs;
- }
- // main function
- // takes a double color image and a scaling factor
- // returns resized image
- mxArray *resize(const mxArray *mxsrc, const mxArray *mxscale) {
- double *src = (double *)mxGetPr(mxsrc);
- const int *sdims = (int*)mxGetDimensions(mxsrc);
- if (mxGetNumberOfDimensions(mxsrc) != 3 ||
- mxGetClassID(mxsrc) != mxDOUBLE_CLASS)
- mexErrMsgTxt("Invalid input");
- double scale = mxGetScalar(mxscale);
- if (scale > 1)
- mexErrMsgTxt("Invalid scaling factor");
- int ddims[3];
- ddims[0] = (int)round(sdims[0]*scale);
- ddims[1] = (int)round(sdims[1]*scale);
- ddims[2] = sdims[2];
- mxArray *mxdst = mxCreateNumericArray(3, (mwSize*)ddims, mxDOUBLE_CLASS, mxREAL);
- double *dst = (double *)mxGetPr(mxdst);
- double *tmp = (double *)mxCalloc(ddims[0]*sdims[1]*sdims[2], sizeof(double));
- resize1dtran(src, sdims[0], tmp, ddims[0], sdims[1], sdims[2]);
- resize1dtran(tmp, sdims[1], dst, ddims[1], ddims[0], sdims[2]);
- mxFree(tmp);
- return mxdst;
- }
- // matlab entry point
- // dst = resize(src, scale)
- // image should be color with double values
- void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
- if (nrhs != 2)
- mexErrMsgTxt("Wrong number of inputs");
- if (nlhs != 1)
- mexErrMsgTxt("Wrong number of outputs");
- plhs[0] = resize(prhs[0], prhs[1]);
- }
4,compile.m中:结尾加上mex -O fconv.cc
- mex -O resize.cc
- mex -O dt.cc
- mex -O features.cc
- mex -O getdetections.cc
- % use one of the following depending on your setup
- % 0 is fastest, 3 is slowest
- % 0) multithreaded convolution using SSE
- % mex -O fconvsse.cpp -o fconv
- % 1) multithreaded convolution using blas
- % WARNING: the blas version does not work with matlab >= 2010b
- % and Intel CPUs
- % mex -O fconvblasMT.cc -lmwblas -o fconv
- % 2) mulththreaded convolution without blas
- % mex -O fconvMT.cc -o fconv
- % 3) convolution using blas
- % mex -O fconvblas.cc -lmwblas -o fconv
- % 4) basic convolution, very compatible
- % mex -O fconv.cc -o fconv
- mex -O fconv.cc
5,将fconv.cc文件中
- void *process(void *thread_arg)
- void process(void *thread_arg)
【可选步骤】如果是新安装好的matlab或者VS2010,则在matlab中运行mex -setup配置默认的C++编译器。
6,在matlab中输入compile()重新编译一下
7,在matlab中输入demo(),运行成功。分别显示了一幅汽车、行人、自行车的图像,对象的模型,检测结果等。