#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "ai_defs.h"
#include "veh_type.h"
#include "veh_adaboost.h"
#include "opencv2/opencv.hpp"
#include "opencv2/legacy/legacy.hpp"
using namespace std;
using namespace cv;
unsigned __int64 TimerRead(void)
{
u32 u32Ts1, u32Ts2;
unsigned __int64 n64cycle;
__asm
{
rdtsc
mov u32Ts1, eax
mov u32Ts2, edx
}
n64cycle = u32Ts2;
n64cycle = (n64cycle << 32)|u32Ts1;
return n64cycle;
}
static void *g_pvSrcHandle; // 图像源
static u8 g_au8Src[1920 * 1600 * 3];
//Real adaboost
//样本集分为正样本,负样本
//正样本是小图片,负样本则是从不包含正样本的大图中随机挖图得到的
//因此指定一个样本的方法就是大图和Rect
typedef struct _IMG_
{
unsigned int * iix; //积分图像 带入某个特定HaarWeakLeaner才能得到h(x)
float w; //权值
float var_norm_factor;//方差归一化参数,会直接影响训练和分类时的Haar特征提取
}TrainSample;
void loadsave_data(const char *pFileName, void * pclassifier, int size, int load)
{
if(load)
{
FILE *fp;
fp = fopen(pFileName,"rb");
fread(pclassifier, size, 1, fp);
fclose(fp);
}
else
{
FILE *fp;
fp = fopen(pFileName,"wb");
fwrite(pclassifier, size, 1, fp);
fclose(fp);
}
}
static __inline void set_haarwl(HaarWeakLeaner * pHaarWL,
int x, int y, int rw, int rh, int pret, const char * type)
{
pHaarWL[0].x = x;
pHaarWL[0].y = y;
pHaarWL[0].rw = rw;
pHaarWL[0].rh = rh;
pHaarWL[0].pret = pret;
strcpy(pHaarWL[0].type, type);
}
HaarWeakLeaner atHaarWeakLeaner[6000];
//积分图上如果使用A+B-C-D方法计算想要获得准确结果的话,必须在源图左侧和顶行添加全零列/行
//这样下面的计算才不会有误差
//在每个新尺度上实现检测时,都需要对特征的位置进行缩放处理
//但是训练用的样本都被归一化到24x24大小了
//方差归一化在每个haar特征计算时完成(就是下面的var_norm_factor)
//
static __inline float f_function(HaarWeakLeaner * pHaar, unsigned int *iix, float var_norm_factor)
{
int i;
int ret = 0;
for(i=0;i<pHaar->func.cnt; i++)
{
ret += iix[pHaar->func.off[i]] * pHaar->func.coeff[i];
}
return ((float)ret * var_norm_factor);
}
static __inline float f_function_x2y2(HaarWeakLeaner * pHaar, unsigned int *iix, float var_norm_factor)
{
int ret = (int)(iix[pHaar->func.off[0]])
-(int)(iix[pHaar->func.off[1]] << 1)
+(int)(iix[pHaar->func.off[2]])
-(int)(iix[pHaar->func.off[3]])
+(int)(iix[pHaar->func.off[4]] << 1)
-(int)(iix[pHaar->func.off[5]]);
return ((float)ret * var_norm_factor);
}
static __inline float f_function_x3y3(HaarWeakLeaner * pHaar, unsigned int *iix, float var_norm_factor)
{
int ret = ( (int)(iix[pHaar->func.off[0]] + iix[pHaar->func.off[7]]) - (int)(iix[pHaar->func.off[3]] + iix[pHaar->func.off[4]]))
+(((int)(iix[pHaar->func.off[2]] + iix[pHaar->func.off[5]]) - (int)(iix[pHaar->func.off[1]] + iix[pHaar->func.off[6]])) * 3);
return ((float)ret * var_norm_factor);
}
static __inline float f_function_d4(HaarWeakLeaner * pHaar, unsigned int *iix, float var_norm_factor)
{
int ret = -(int)(iix[pHaar->func.off[0]])
+(int)(iix[pHaar->func.off[1]] << 1)
-(int)(iix[pHaar->func.off[2]])
+(int)(iix[pHaar->func.off[3]] << 1)
-(int)(iix[pHaar->func.off[4]] << 2)
+(int)(iix[pHaar->func.off[5]] << 1)
-(int)(iix[pHaar->func.off[6]])
+(int)(iix[pHaar->func.off[7]] << 1)
-(int)(iix[pHaar->func.off[8]]);
return ((float)ret * var_norm_factor);
}
void f_function_generate(HaarWeakLeaner * pHaar, float scaley,float scalex, int stride)
{
int x; //start place of first rectangle
int y;
int y_off;
int rw; //size of each rectangle
int rh; //
x = pHaar->x * scalex;
y = pHaar->y * scaley;
rw = pHaar->rw * scalex;
rh = pHaar->rh * scaley;
if(strcmp(pHaar->type,"x2") == 0)
{
// i0 i1 i2
// i3 i4 i5
//
// ( i4 + i0 - i1 + i3) +
// ( -i5 - i1 + i2 + i4)
//
y_off = y*stride;
pHaar->func.off[0] = x + y_off;
pHaar->func.off[1] = x + rw + y_off;
pHaar->func.off[2] = x + 2*rw + y_off;
y_off += rh*stride;
pHaar->func.off[3] = x + y_off;
pHaar->func.off[4] = x + rw + y_off;
pHaar->func.off[5] = x + 2*rw + y_off;
pHaar->func.coeff[0] = 1;
pHaar->func.coeff[1] = -2;
pHaar->func.coeff[2] = 1;
pHaar->func.coeff[3] = -1;
pHaar->func.coeff[4] = 2;
pHaar->func.coeff[5] = -1;
pHaar->func.cnt = 6;
}
else
if(strcmp(pHaar->type,"y2") == 0)
{
//同上,只是把id翻转一下即可
// i0 i3
// i1 i4
// i2 i5
y_off = y*stride;
pHaar->func.off[0] = x + y_off;
pHaar->func.off[3] = x + rw + y_off;
y_off += rh*stride;
pHaar->func.off[1] = x + y_off;
pHaar->func.off[4] = x + rw + y_off;
y_off += rh*stride;
pHaar->func.off[2] = x + y_off;
pHaar->func.off[5] = x + rw + y_off;
pHaar->func.coeff[0] = 1;
pHaar->func.coeff[1] = -2;
pHaar->func.coeff[2] = 1;
pHaar->func.coeff[3] = -1;
pHaar->func.coeff[4] = 2;
pHaar->func.coeff[5] = -1;
pHaar->func.cnt = 6;
}
else
if(strcmp(pHaar->type,"x3") == 0)
{
// i0 i1 i2 i3
// i4 i5 i6 i7
//
// i0 + i7 - i3 - i4
// -2*i1 - 2*i6 + 2*i2 + 2*i5
y_off = y*stride;
pHaar->func.off[0] = x + y_off;
pHaar->func.off[1] = x + rw + y_off;
pHaar->func.off[2] = x + 2*rw + y_off;
pHaar->func.off[3] = x + 3*rw + y_off;
y_off += rh*stride;
pHaar->func.off[4] = x + y_off;
pHaar->func.off[5] = x + rw + y_off;
pHaar->func.off[6] = x + 2*rw + y_off;
pHaar->func.off[7] = x + 3*rw + y_off;
pHaar->func.coeff[0] = 1;
pHaar->func.coeff[1] = -3;
pHaar->func.coeff[2] = 3;
pHaar->func.coeff[3] = -1;
pHaar->func.coeff[4] = -1;
pHaar->func.coeff[5] = 3;
pHaar->func.coeff[6] = -3;
pHaar->func.coeff[7] = 1;
pHaar->func.cnt = 8;
}
else
if(strcmp(pHaar->type,"y3") == 0)
{
// i0 i4
// i1 i5
// i2 i6
// i3 i7
y_off = y*stride;
pHaar->func.off[0] = x + y_off;
pHaar->func.off[4] = x + rw + y_off;
y_off = y*stride;
pHaar->func.off[1] = x + y_off;
pHaar->func.off[5] = x + rw + y_off;
y_off += rh*stride;
pHaar->func.off[2] = x + y_off;
pHaar->func.off[6] = x + rw + y_off;
y_off += rh*stride;
pHaar->func.off[3] = x + y_off;
pHaar->func.off[7] = x + rw + y_off;
// pHaar->func.coeff[0] = 1;
// pHaar->func.coeff[1] = -2;
// pHaar->func.coeff[2] = 2;
// pHaar->func.coeff[3] = -1;
// pHaar->func.coeff[4] = -1;
// pHaar->func.coeff[5] = 2;
// pHaar->func.coeff[6] = -2;
// pHaar->func.coeff[7] = 1;
pHaar->func.coeff[0] = 1;
pHaar->func.coeff[1] = -3;
pHaar->func.coeff[2] = 3;
pHaar->func.coeff[3] = -1;
pHaar->func.coeff[4] = -1;
pHaar->func.coeff[5] = 3;
pHaar->func.coeff[6] = -3;
pHaar->func.coeff[7] = 1;
pHaar->func.cnt = 8;
}
else
if(strcmp(pHaar->type,"d4") == 0)
{
//
// i0 i1 i2