您的位置:首页 > 编程语言

Harr特征描述子代码实现

2017-03-04 14:26 134 查看
main函数

//  main.cpp
//  HaarFeature
//  Created by qianxin_dh on 14-9-13.
//  Copyright (c) 2014年 qianxin_dh. All rights reserved.

#include "stdafx.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include "HaarFeature.h"

using namespace cv;
using namespace std;

const int featureNUM=192;

int main()
{
Mat image=imread("lena.bmp");

//cvtColor(image,image,CV_RGB2GRAY);

if (image.empty())
{
cout<<"Load the image error!"<<endl;
return -1;
}

vector<HaarFeature> m_features;

//用于生成特征模板
float x[] = {0.2f, 0.4f, 0.6f, 0.8f};
float y[] = {0.2f, 0.4f, 0.6f, 0.8f};
float s[] = {0.2f, 0.4f};
for (int iy = 0; iy < 4; ++iy)
{
for (int ix = 0; ix < 4; ++ix)
{
for (int is = 0; is < 2; ++is)
{
FloatRect r(x[ix]-s[is]/2, y[iy]-s[is]/2, s[is], s[is]);  //32种尺寸

for (int it = 0; it < 6; ++it)        //这里主要实现6种hair特征,32*6=192种特征模板
{
m_features.push_back(HaarFeature(r, it));
}
}
}
}

float m_feat;

FloatRect rect(10,10,100,50);

for(int i=0;i<featureNUM;i++){
m_feat= m_features[i].caluHf(image,rect);

cout<<m_feat<<" "<<endl;
}

return 0;
}


HaarFeature类

#include <opencv2/opencv.hpp>
#include <vector>

#include "RECT.h"
using namespace cv;

class HaarFeature
{
public:
HaarFeature(FloatRect& bb, int type);
~HaarFeature();

float caluHf(Mat& _image,FloatRect& _rect);  //计算haar特征值

private:
float sum(Mat& _image,IntRect& _rect);

private:
FloatRect m_box;
std::vector<FloatRect> m_rects;
std::vector<float> m_weights;
float m_factor;

Mat _imageIntegral;
};


include “HaarFeature.h”

include

using namespace std;

HaarFeature::HaarFeature(FloatRect& bb, int type) :

m_box(bb)

{

assert(type < 6); //分别实现六种haar特征,可以参照文章开头时引用的图片进行对应

switch (type)
{
case 0:
{
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin(), bb.Width(), bb.Height()/2));
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin()+bb.Height()/2, bb.Width(), bb.Height()/2));
m_weights.push_back(1.f);
m_weights.push_back(-1.f);
m_factor = 255*1.f/2;
break;
}
case 1:
{
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin(), bb.Width()/2, bb.Height()));
m_rects.push_back(FloatRect(bb.XMin()+bb.Width()/2, bb.YMin(), bb.Width()/2, bb.Height()));
m_weights.push_back(1.f);
m_weights.push_back(-1.f);
m_factor = 255*1.f/2;
break;
}
case 2:
{
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin(), bb.Width()/3, bb.Height()));
m_rects.push_back(FloatRect(bb.XMin()+bb.Width()/3, bb.YMin(), bb.Width()/3, bb.Height()));
m_rects.push_back(FloatRect(bb.XMin()+2*bb.Width()/3, bb.YMin(), bb.Width()/3, bb.Height()));
m_weights.push_back(1.f);
m_weights.push_back(-2.f);
m_weights.push_back(1.f);
m_factor = 255*2.f/3;
break;
}
case 3:
{
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin(), bb.Width(), bb.Height()/3));
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin()+bb.Height()/3, bb.Width(), bb.Height()/3));
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin()+2*bb.Height()/3, bb.Width(), bb.Height()/3));
m_weights.push_back(1.f);
m_weights.push_back(-2.f);
m_weights.push_back(1.f);
m_factor = 255*2.f/3;
break;
}
case 4:
{
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin(), bb.Width()/2, bb.Height()/2));
m_rects.push_back(FloatRect(bb.XMin()+bb.Width()/2, bb.YMin()+bb.Height()/2, bb.Width()/2, bb.Height()/2));
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin()+bb.Height()/2, bb.Width()/2, bb.Height()/2));
m_rects.push_back(FloatRect(bb.XMin()+bb.Width()/2, bb.YMin(), bb.Width()/2, bb.Height()/2));
m_weights.push_back(1.f);
m_weights.push_back(1.f);
m_weights.push_back(-1.f);
m_weights.push_back(-1.f);
m_factor = 255*1.f/2;
break;
}
case 5:
{
m_rects.push_back(FloatRect(bb.XMin(), bb.YMin(), bb.Width(), bb.Height()));
m_rects.push_back(FloatRect(bb.XMin()+bb.Width()/4, bb.YMin()+bb.Height()/4, bb.Width()/2, bb.Height()/2));
m_weights.push_back(1.f);
m_weights.push_back(-4.f);
m_factor = 255*3.f/4;
break;
}
}


}

HaarFeature::~HaarFeature()

{

}

float HaarFeature::sum(Mat& _image,IntRect& _rect)

{

int xMin=_rect.XMin();

int yMin=_rect.YMin();

int xMax=_rect.XMin()+_rect.Width();

int yMax=_rect.YMin()+_rect.Height();

int tempValue=0;

tempValue +=
_imageIntegral.at<int>(yMin, xMin) +
_imageIntegral.at<int>(yMax, xMax) -
_imageIntegral.at<int>(yMin, xMax) -
_imageIntegral.at<int>(yMax, xMin);

//cout<<weight<<endl;

//cout<<tempValue<<endl;

return tempValue;


}

float HaarFeature::caluHf(Mat& _image,FloatRect& _rect)

{

int value = 0;

integral(_image, _imageIntegral, CV_32F);

//cout<<_imageIntegral<<" "<<endl;

for (int i = 0; i < (int)m_rects.size(); ++i)      //m_rects.size()=2;
{
FloatRect& r = m_rects[i];

IntRect sampleRect((int)(_rect.XMin()+r.XMin()*_rect.Width()+0.5f), (int)(_rect.YMin()+r.YMin()*_rect.Height()+0.5f),
(int)(r.Width()*_rect.Width()), (int)(r.Height()*_rect.Height()));

value +=m_weights[i]*sum(_image,sampleRect);   //sum函数返回的是积分图像对应的数值
}
return value / (m_factor*(_rect.Area())*(m_box.Area()));


}

#pragma once

#include <iostream>
#include <algorithm>

template <typename T>
class Rect
{
public:
Rect() :
m_xMin(0),
m_yMin(0),
m_width(0),
m_height(0)
{
}

Rect(T xMin, T yMin, T width, T height) :
m_xMin(xMin),
m_yMin(yMin),
m_width(width),
m_height(height)
{
}

template <typename T2>
Rect(const Rect<T2>& rOther) :
m_xMin((T)rOther.XMin()),
m_yMin((T)rOther.YMin()),
m_width((T)rOther.Width()),
m_height((T)rOther.Height())
{
}

inline T XMin() const { return m_xMin; }
inline T YMin() const { return m_yMin; }
inline T Width() const { return m_width; }
inline T Height() const { return m_height; }
inline T Area() const { return m_width * m_height; }

private:
T m_xMin;
T m_yMin;
T m_width;
T m_height;
};

typedef Rect<int> IntRect;
typedef Rect<float> FloatRect;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: