📄 integralfeatures.cpp
字号:
/** * cubicles * * This is an implementation of the Viola-Jones object detection * method and some extensions. The code is mostly platform- * independent and uses only standard C and C++ libraries. It * can make use of MPI for parallel training and a few Windows * MFC functions for classifier display. * * Mathias Kolsch, matz@cs.ucsb.edu * * $Id: IntegralFeatures.cpp,v 1.61 2005/10/28 17:47:04 matz Exp $**/// IntegralFeatures describe the rectangular areas whose pixel// sums are compared to a weak classifier's threshold. There// are many different types of IntegralFeatures.// Functions for reading from files are flex/bison generated from// CascadeFileScanner.lex and CascadeFileParser.yy.////////////////////////////////////////////////////////////////////////// By downloading, copying, installing or using the software you // agree to this license. If you do not agree to this license, // do not download, install, copy or use the software.//// Copyright (C) 2004, Mathias Kolsch, all rights reserved.// Third party copyrights are property of their respective owners.//// Redistribution and use in binary form, with or without // modification, is permitted for non-commercial purposes only.// Redistribution in source, with or without modification, is // prohibited without prior written permission.// If granted in writing in another document, personal use and // modification are permitted provided that the following two// conditions are met://// 1.Any modification of source code must retain the above // copyright notice, this list of conditions and the following // disclaimer.//// 2.Redistribution's in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided// with the distribution.//// This software is provided by the copyright holders and // contributors "as is" and any express or implied warranties, // including, but not limited to, the implied warranties of // merchantability and fitness for a particular purpose are // disclaimed. In no event shall the copyright holder or // contributors be liable for any direct, indirect, incidental, // special, exemplary, or consequential damages (including, but not // limited to, procurement of substitute goods or services; loss of // use, data, or profits; or business interruption) however caused// and on any theory of liability, whether in contract, strict // liability, or tort (including negligence or otherwise) arising // in any way out of the use of this software, even if advised of // the possibility of such damage.//////////////////////////////////////////////////////////////////////#include "cubicles.hpp"#include "IntegralFeatures.h"#include "Exceptions.h"#include <math.h>#include <iostream>#ifdef _DEBUG#ifdef USE_MFC#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif // USE_MFC#endif // _DEBUG#if defined(WIN32) && defined(DEBUG)#include <streams.h>#endif#ifdef USE_MFCCBrush* g_pBlackbrush = NULL;CBrush* g_pWhitebrush = NULL;#endif // USE_MFCint g_verbose = 0;FILE* g_ostream = stdout;#ifdef WIN32#include <malloc.h>#define alloca _alloca#endif///////////////////////////////////////////////////////////////////////////////// CIntegralFeature implementation///////////////////////////////////////////////////////////////////////////////const II_TYPE CIntegralFeature::SCALE_DIFFERENCE_EPSILON = .000000001;CIntegralFeature::CIntegralFeature(int templateWidth, int templateHeight, featnum num_incarnations, bool is_partial, int cost): m_template_width(templateWidth), m_template_height(templateHeight), m_num_incarnations(num_incarnations), m_is_partial(is_partial), m_cost(cost){#ifdef USE_MFC if (g_pBlackbrush==NULL) { ASSERT(g_pWhitebrush==NULL); g_pWhitebrush = new CBrush(RGB(255, 255, 255)); g_pBlackbrush = new CBrush(RGB(0, 0, 0)); }#endif // USE_MFC}ostream& operator<<(ostream& os, const CIntegralFeature& clsf){ return clsf.output(os);}CIntegralFeature* CIntegralFeature::CreateFrom(istream& is, int template_width, int template_height){ CIntegralFeature* feature = NULL; string subclass; is >> subclass; if (subclass=="LeftRight") { feature = new CLeftRightIF(is, template_width, template_height); } else if (subclass=="UpDown") { feature = new CUpDownIF(is, template_width, template_height); } else if (subclass=="LeftCenterRight") { feature = new CLeftCenterRightIF(is, template_width, template_height); } else if (subclass=="SevenColumns") { feature = new CSevenColumnsIF(is, template_width, template_height); } else if (subclass=="Diag") { feature = new CDiagIF(is, template_width, template_height); } else if (subclass=="LeftRightSame") { feature = new CLeftRightSameIF(is, template_width, template_height); } else if (subclass=="UpDownSame") { feature = new CUpDownSameIF(is, template_width, template_height); } else if (subclass=="LeftCenterRightSame") { feature = new CLeftCenterRightSameIF(is, template_width, template_height); } else if (subclass=="SevenColumnsSame") { feature = new CSevenColumnsSameIF(is, template_width, template_height); } else if (subclass=="SevenColumnsSimilar") { feature = new CSevenColumnsSimilarIF(is, template_width, template_height); } else if (subclass=="DiagSame") { feature = new CDiagSameIF(is, template_width, template_height); } else if (subclass=="DiagSimilar") { feature = new CDiagSimilarIF(is, template_width, template_height); } else if (subclass=="FourBoxes") { feature = new CFourBoxesIF(is, template_width, template_height); } else if (subclass=="FourBoxesSame") { feature = new CFourBoxesSameIF(is, template_width, template_height); } else { // error VERBOSE1(1, "can not create IntegralFeature from string '%s'.", subclass.c_str()); ASSERT(0); } return feature;}/* use ScaleEvenly to scale by non-integer values, otherwise use* Scale*/void CIntegralFeature::ScaleEvenly(II_TYPE scale_x, II_TYPE scale_y, int scaled_template_width, int scaled_template_height){ Scale(scale_x, scale_y); EvenOutScales(&scale_x, &scale_y, scaled_template_width, scaled_template_height); m_global_scale = scale_x*scale_y;}featnum CIntegralFeature::GetNumIncarnations() const{ if (m_num_incarnations==IT_INVALID_FEATURE) { // count some other feature, we don't want to change // this one at all. CIntegralFeature* counter = this->Copy(); counter->SetToFirstIncarnation(); featnum cnt = 0; bool has_more_incarnations = true; do { cnt++; if (cnt==IT_MAX_VALID_FEATURE) { throw ITException("int overflow in GetNumIncarnations()"); } has_more_incarnations = counter->SetToNextIncarnation(); } while (has_more_incarnations); ((CIntegralFeature*) this)->m_num_incarnations = cnt; delete counter; } ASSERT(m_num_incarnations>=0 && m_num_incarnations!=IT_INVALID_FEATURE); return m_num_incarnations;}///////////////////////////////////////////////////////////////////////////////// CLeftRightIF classes implementation///////////////////////////////////////////////////////////////////////////////CLeftRightIF::CLeftRightIF(int templateWidth, int templateHeight) : CIntegralFeature(templateWidth, templateHeight, IT_INVALID_FEATURE, false, 6*COST_GET+7*COST_ADD) {}CLeftRightIF::CLeftRightIF(const CLeftRightIF& frm) : CIntegralFeature(frm.m_template_width, frm.m_template_height, frm.m_num_incarnations, frm.m_is_partial, 6*COST_GET+7*COST_ADD) { toprow = frm.toprow; bottomrow = frm.bottomrow; leftrect_leftcol = frm.leftrect_leftcol; centercol = frm.centercol; rightrect_rightcol = frm.rightrect_rightcol; if (m_is_partial) { start_toprow = frm.start_toprow; start_bottomrow = frm.start_bottomrow; start_leftrect_leftcol = frm.start_leftrect_leftcol; start_centercol = frm.start_centercol; start_rightrect_rightcol = frm.start_rightrect_rightcol; m_remaining_incarnations = frm.m_remaining_incarnations; m_stop_after_num_incarnations = frm.m_stop_after_num_incarnations; } SetNonOverlap();}CLeftRightIF::CLeftRightIF(int template_width, int template_height, int _toprow, int _bottomrow, int _leftrect_leftcol, int _centercol, int _rightrect_rightcol) : CIntegralFeature(template_width, template_height, IT_INVALID_FEATURE, 0, 6*COST_GET+7*COST_ADD){ toprow = _toprow; bottomrow = _bottomrow; leftrect_leftcol = _leftrect_leftcol; centercol = _centercol; rightrect_rightcol = _rightrect_rightcol; SetNonOverlap();}CLeftRightIF::CLeftRightIF(istream& is, int template_width, int template_height) : CIntegralFeature(template_width, template_height, IT_INVALID_FEATURE, 0, 6*COST_GET+7*COST_ADD){ char a, b, c; string str; is >> toprow >> a >> bottomrow >> str >> leftrect_leftcol >> b >> centercol >> c >> rightrect_rightcol; if (a!=',' || b!=',' || c!=',' || str!="x") { char* buf = (char*) alloca((256+str.length())*sizeof(char)); sprintf(buf, "error during construction of LeftRightIF (%c|%c|%c|%s)\n", a, b, c, str.c_str()); throw ITException(buf); } SetNonOverlap();}bool CLeftRightIF::Equals(const CLeftRightIF& frm) const{ bool equal = (toprow == frm.toprow && bottomrow == frm.bottomrow && leftrect_leftcol == frm.leftrect_leftcol && centercol == frm.centercol && rightrect_rightcol == frm.rightrect_rightcol); return equal;}void CLeftRightIF::SetNonOverlap() { m_non_overlap = ((centercol-leftrect_leftcol) - (rightrect_rightcol-centercol)) * (bottomrow-toprow);}II_TYPE CLeftRightIF::Compute(const CIntegralImage& image) const{ II_TYPE botcen = image.GetElement(centercol, bottomrow); ASSERT(!isnan(botcen)); II_TYPE topcen = image.GetElement(centercol, toprow); ASSERT(!isnan(topcen)); II_TYPE val_leftrect = botcen - image.GetElement(leftrect_leftcol, bottomrow) - topcen + image.GetElement(leftrect_leftcol, toprow); ASSERT(!isnan(val_leftrect)); II_TYPE val_rightrect = image.GetElement(rightrect_rightcol, bottomrow) - botcen - image.GetElement(rightrect_rightcol, toprow) + topcen; ASSERT(!isnan(val_rightrect)); ASSERT(!isnan(val_leftrect-val_rightrect)); return val_leftrect-val_rightrect;}II_TYPE CLeftRightIF::ComputeScaled(const CIntegralImage& image, II_TYPE mean, int left, int top) const{ int placed_toprow = top + scaled_toprow; int placed_bottomrow = top + scaled_bottomrow; int placed_leftrect_leftcol = left + scaled_leftrect_leftcol; int placed_centercol = left + scaled_centercol; int placed_rightrect_rightcol = left + scaled_rightrect_rightcol; II_TYPE botcen = image.GetElement(placed_centercol, placed_bottomrow); II_TYPE topcen = image.GetElement(placed_centercol, placed_toprow); II_TYPE val_leftrect = botcen - image.GetElement(placed_leftrect_leftcol, placed_bottomrow) - topcen + image.GetElement(placed_leftrect_leftcol, placed_toprow); II_TYPE val_rightrect = image.GetElement(placed_rightrect_rightcol, placed_bottomrow) - botcen - image.GetElement(placed_rightrect_rightcol, placed_toprow) + topcen; II_TYPE val = val_leftrect-val_rightrect; II_TYPE scaled_val = val/m_global_scale; II_TYPE mean_adjust = m_non_overlap*mean; return scaled_val-mean_adjust;}void CLeftRightIF::Scale(II_TYPE scale_x, II_TYPE scale_y){ if (toprow==-1) { scaled_toprow = -1; scaled_bottomrow = (int)((II_TYPE)(bottomrow+1)*scale_y) - 1; } else { scaled_toprow = (int)((II_TYPE)toprow*scale_y); scaled_bottomrow = (int)((II_TYPE)bottomrow*scale_y); } if (leftrect_leftcol==-1) { scaled_leftrect_leftcol = -1; scaled_centercol = (int)((II_TYPE)(centercol+1)*scale_x) - 1; scaled_rightrect_rightcol = (int)((II_TYPE)(rightrect_rightcol-centercol)*scale_x) + scaled_centercol; } else { scaled_leftrect_leftcol = (int)((II_TYPE)leftrect_leftcol*scale_x); scaled_centercol = (int)((II_TYPE)centercol*scale_x); scaled_rightrect_rightcol = (int)((II_TYPE)rightrect_rightcol*scale_x); } m_global_scale = scale_x*scale_y;}void CLeftRightIF::EvenOutScales(II_TYPE* pScale_x, II_TYPE* pScale_y, int scaled_template_width, int /*scaled_template_height*/){ int leftrect = centercol-leftrect_leftcol; int rightrect = rightrect_rightcol-centercol; II_TYPE ratio = (II_TYPE)leftrect/(II_TYPE)rightrect; int sleftrect = scaled_centercol-scaled_leftrect_leftcol; int srightrect = scaled_rightrect_rightcol-scaled_centercol;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -