?? scanner.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: Scanner.cpp,v 1.48 2004/11/11 01:58:58 matz Exp $**/// Scanner scans across an image and finds matches for the // classifier cascade. There's also a Scanner_Train.cpp// implementation file that for training-only functions.////////////////////////////////////////////////////////////////////////// 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 "Scanner.h"#include "Cascade.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// ----------------------------------------------------------------------// class CImageScanner// ----------------------------------------------------------------------CImageScanner::CImageScanner() : m_is_active(true), m_post_process(false){ SetScanParameters();}CImageScanner::CImageScanner(const CImageScanner& src) : m_is_active(src.m_is_active), m_start_scale(src.m_start_scale), m_stop_scale(src.m_stop_scale), m_scale_inc_factor(src.m_scale_inc_factor), m_translation_inc_x(src.m_translation_inc_x), m_translation_inc_y(src.m_translation_inc_y), m_scan_area(src.m_scan_area), m_post_process(src.m_post_process), m_min_scaled_template_width(-1), m_max_scaled_template_width(-1), m_min_scaled_template_height(-1), m_max_scaled_template_height(-1), m_integral(src.m_integral), m_squared_integral(src.m_squared_integral){}void CImageScanner::SetScanParameters( double start_scale /* = 1.0 */, double stop_scale /* = DBL_MAX */, double scale_inc_factor /* = 1.25 */, double translation_inc_x /* = 1.0 */, double translation_inc_y /* = 1.0 */, CRect scan_area /* = CRect(0, 0, INT_MAX, INT_MAX) */ ){ SetScanScales(start_scale, stop_scale); m_scale_inc_factor = scale_inc_factor; m_translation_inc_x = translation_inc_x; m_translation_inc_y = translation_inc_y; m_scan_area = scan_area; m_min_scaled_template_width = -1; m_max_scaled_template_width = -1; m_min_scaled_template_height = -1; m_max_scaled_template_height = -1;}void CImageScanner::GetScanParameters( double* pStart_scale, double* pStop_scale, double* pScale_inc_factor, double* pTranslation_inc_x, double* pTranslation_inc_y, CRect& scan_area, bool* pPostProcessing, bool* pIsActive ) const{ *pStart_scale = m_start_scale; *pStop_scale = m_stop_scale; *pScale_inc_factor = m_scale_inc_factor; *pTranslation_inc_x = m_translation_inc_x; *pTranslation_inc_y = m_translation_inc_y; *pPostProcessing = m_post_process; *pIsActive = m_is_active; scan_area = m_scan_area;}void CImageScanner::SetScanArea(const CRect& scan_area){ m_scan_area = scan_area;}void CImageScanner::SetScanScales(double start_scale, double stop_scale){ m_start_scale = start_scale; m_stop_scale = stop_scale; m_min_scaled_template_width = -1; m_max_scaled_template_width = -1; m_min_scaled_template_height = -1; m_max_scaled_template_height = -1;}// must be called after the actual scan, and the behavior with// multiple active scanners is somewhat undeterminedvoid CImageScanner::GetScaleSizes(int* min_width, int* max_width, int* min_height, int* max_height) const{ *min_width = m_min_scaled_template_width; *max_width = m_max_scaled_template_width; *min_height = m_min_scaled_template_height; *max_height = m_max_scaled_template_height;}void CImageScanner::SetAutoPostProcessing(bool on /*=true*/){ m_post_process = on;}const CRect& CImageScanner::GetScanArea() const{ return m_scan_area;}intCImageScanner::Scan(const CClassifierCascade& cascade, const CByteImage& image, CScanMatchVector& posClsfd) const{ if (!m_is_active) return -1; // make integral of regular and squared image CIntegralImage::CreateSimpleNSquaredFrom(image, m_integral, m_squared_integral, m_scan_area); return Scan(cascade, m_integral, m_squared_integral, posClsfd);}intCImageScanner::Scan(const CClassifierCascade& cascade, const CIntegralImage& integral, const CIntegralImage& squared_integral, CScanMatchVector& posClsfd) const{ if (!m_is_active) return -1; posClsfd.clear(); CScaleParams sclprms; InitScaleParams(cascade, sclprms); m_min_scaled_template_width = sclprms.scaled_template_width; m_min_scaled_template_height = sclprms.scaled_template_height; double N = sclprms.scaled_template_width * sclprms.scaled_template_height; int width = integral.GetWidth(); int height = integral.GetHeight(); CStringVector matches; int scancnt=0; while (sclprms.scaled_template_width<width && sclprms.scaled_template_height<height && sclprms.base_scale<m_stop_scale) { cascade.ScaleFeaturesEvenly(sclprms.actual_scale_x, sclprms.actual_scale_y, sclprms.scaled_template_width, sclprms.scaled_template_height); // for each y-location in the image int top_stop = min(m_scan_area.bottom, height)-sclprms.scaled_template_height; for (int top=max(0, m_scan_area.top); top<top_stop; top+=(int)sclprms.translation_inc_y) { int bottom = top+sclprms.scaled_template_height; // for each x-location in the image int left_stop = min(m_scan_area.right, width)-sclprms.scaled_template_width; for (int left=max(0, m_scan_area.left); left<left_stop; left+=(int)sclprms.translation_inc_x) { int right = left+sclprms.scaled_template_width; double sum_x = integral.GetElement(right-1, bottom-1) - integral.GetElement(right-1, top-1) - integral.GetElement(left-1, bottom-1) + integral.GetElement(left-1, top-1); double mean = sum_x / N; double sum_x2 = squared_integral.GetElement(right-1, bottom-1) - squared_integral.GetElement(right-1, top-1) - squared_integral.GetElement(left-1, bottom-1) + squared_integral.GetElement(left-1, top-1); double stddev = sqrt(fabs(mean*mean - sum_x2/N)); // double stddev_equal = sqrt(fabs(mean*mean - 2.0*sum_x*mean/N + sum_x2/N)); bool is_positive = cascade.Evaluate(integral, mean, stddev, left, top, matches); if (is_positive) { for (int m=0; m<(int)matches.size(); m++) { posClsfd.push_back(CScanMatch(left, top, right, bottom, sclprms.base_scale,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -