Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of gr-peach-opencv-project-sd-card by
bif.cpp
00001 /* 00002 By downloading, copying, installing or using the software you agree to this license. 00003 If you do not agree to this license, do not download, install, 00004 copy or use the software. 00005 00006 00007 License Agreement 00008 For Open Source Computer Vision Library 00009 (3-clause BSD License) 00010 00011 Copyright (C) 2000-2015, Intel Corporation, all rights reserved. 00012 Copyright (C) 2009-2011, Willow Garage Inc., all rights reserved. 00013 Copyright (C) 2009-2015, NVIDIA Corporation, all rights reserved. 00014 Copyright (C) 2010-2013, Advanced Micro Devices, Inc., all rights reserved. 00015 Copyright (C) 2015, OpenCV Foundation, all rights reserved. 00016 Copyright (C) 2015, Itseez Inc., all rights reserved. 00017 Third party copyrights are property of their respective owners. 00018 00019 Redistribution and use in source and binary forms, with or without modification, 00020 are permitted provided that the following conditions are met: 00021 00022 * Redistributions of source code must retain the above copyright notice, 00023 this list of conditions and the following disclaimer. 00024 00025 * Redistributions in binary form must reproduce the above copyright notice, 00026 this list of conditions and the following disclaimer in the documentation 00027 and/or other materials provided with the distribution. 00028 00029 * Neither the names of the copyright holders nor the names of the contributors 00030 may be used to endorse or promote products derived from this software 00031 without specific prior written permission. 00032 00033 This software is provided by the copyright holders and contributors "as is" and 00034 any express or implied warranties, including, but not limited to, the implied 00035 warranties of merchantability and fitness for a particular purpose are disclaimed. 00036 In no event shall copyright holders or contributors be liable for any direct, 00037 indirect, incidental, special, exemplary, or consequential damages 00038 (including, but not limited to, procurement of substitute goods or services; 00039 loss of use, data, or profits; or business interruption) however caused 00040 and on any theory of liability, whether in contract, strict liability, 00041 or tort (including negligence or otherwise) arising in any way out of 00042 the use of this software, even if advised of the possibility of such damage. 00043 */ 00044 00045 00046 /* 00047 This file contains implementation of the bio-inspired features (BIF) approach 00048 for computing image descriptors, applicable for human age estimation. For more 00049 details we refer to [1,2]. 00050 00051 REFERENCES 00052 [1] Guo, Guodong, et al. "Human age estimation using bio-inspired features." 00053 Computer Vision and Pattern Recognition, 2009. CVPR 2009. 00054 [2] Spizhevoi, A. S., and A. V. Bovyrin. "Estimating human age using 00055 bio-inspired features and the ranking method." Pattern Recognition and 00056 Image Analysis 25.3 (2015): 547-552. 00057 */ 00058 00059 #include "precomp.hpp" 00060 #include "opencv2/face/bif.hpp" 00061 #include <iostream> 00062 #include <vector> 00063 00064 namespace { 00065 00066 // The constants below are taken from paper [1]. 00067 00068 const int kNumBandsMax = 8; 00069 00070 const cv::Size kCellSizes[kNumBandsMax] = { 00071 cv::Size(6,6), cv::Size(8,8), cv::Size(10,10), cv::Size(12,12), 00072 cv::Size(14,14), cv::Size(16,16), cv::Size(18,18), cv::Size(20,20) 00073 }; 00074 00075 const cv::Size kGaborSize[kNumBandsMax][2] = { 00076 {cv::Size(5,5), cv::Size(7,7)}, {cv::Size(9,9), cv::Size(11,11)}, 00077 {cv::Size(13,13), cv::Size(15,15)}, {cv::Size(17,17), cv::Size(19,19)}, 00078 {cv::Size(21,21), cv::Size(23,23)}, {cv::Size(25,25), cv::Size(27,27)}, 00079 {cv::Size(29,29), cv::Size(31,31)}, {cv::Size(33,33), cv::Size(35,35)} 00080 }; 00081 00082 const double kGaborGamma = 0.3; 00083 00084 const double kGaborSigmas[kNumBandsMax][2] = { 00085 {2.0, 2.8}, {3.6, 4.5}, {5.4, 6.3}, {7.3, 8.2}, 00086 {9.2, 10.2}, {11.3, 12.3}, {13.4, 14.6}, {15.8, 17.0} 00087 }; 00088 00089 const double kGaborWavelens[kNumBandsMax][2] = { 00090 {2.5, 3.5}, {4.6, 5.6}, {6.8, 7.9}, {9.1, 10.3}, 00091 {11.5, 12.7}, {14.1, 15.4}, {16.8, 18.2}, {19.7, 21.2} 00092 }; 00093 00094 class BIFImpl : public cv::face::BIF { 00095 public: 00096 BIFImpl(int num_bands, int num_rotations) { 00097 initUnits(num_bands, num_rotations); 00098 } 00099 00100 virtual int getNumBands() const { return num_bands_; } 00101 00102 virtual int getNumRotations() const { return num_rotations_; } 00103 00104 virtual void compute(cv::InputArray image, 00105 cv::OutputArray features) const; 00106 00107 private: 00108 struct UnitParams { 00109 cv::Size cell_size; 00110 cv::Mat filter1, filter2; 00111 }; 00112 00113 void initUnits(int num_bands, int num_rotations); 00114 void computeUnit(int unit_idx, const cv::Mat &img, cv::Mat &dst) const; 00115 00116 int num_bands_; 00117 int num_rotations_; 00118 std::vector<UnitParams> units_; 00119 }; 00120 00121 void BIFImpl::compute(cv::InputArray _image, 00122 cv::OutputArray _features) const { 00123 cv::Mat image = _image.getMat(); 00124 CV_Assert(image.type() == CV_32F); 00125 00126 std::vector<cv::Mat> fea_units(units_.size()); 00127 int fea_dim = 0; 00128 00129 for (size_t i = 0; i < units_.size(); ++i) { 00130 computeUnit(static_cast<int>(i), image, fea_units[i]); 00131 fea_dim += fea_units[i].rows; 00132 } 00133 00134 _features.create(fea_dim, 1, CV_32F); 00135 cv::Mat fea = _features.getMat(); 00136 00137 int offset = 0; 00138 for (size_t i = 0; i < fea_units.size(); ++i) { 00139 cv::Mat roi = fea.rowRange(offset, offset + fea_units[i].rows); 00140 fea_units[i].copyTo(roi); 00141 offset += fea_units[i].rows; 00142 } 00143 CV_Assert(offset == fea_dim); 00144 } 00145 00146 void BIFImpl::initUnits(int num_bands, int num_rotations) { 00147 CV_Assert(num_bands > 0 && num_bands <= kNumBandsMax); 00148 CV_Assert(num_rotations > 0); 00149 00150 num_bands_ = num_bands; 00151 num_rotations_ = num_rotations; 00152 00153 for (int ri = 0; ri < num_rotations; ++ri) { 00154 double angle = CV_PI / num_rotations * ri; 00155 00156 for (int bi = 0; bi < num_bands; ++bi) { 00157 cv::Mat kernel[2]; 00158 for (int i = 0; i < 2; ++i) { 00159 kernel[i] = cv::getGaborKernel( 00160 kGaborSize[bi][i], kGaborSigmas[bi][i], angle, 00161 kGaborWavelens[bi][i], kGaborGamma, 0, CV_32F); 00162 00163 // Make variance for the Gaussian part of the Gabor filter 00164 // the same across all filters. 00165 kernel[i] /= 2 * kGaborSigmas[bi][i] * kGaborSigmas[bi][i] 00166 / kGaborGamma; 00167 } 00168 00169 UnitParams unit; 00170 unit.cell_size = kCellSizes[bi]; 00171 unit.filter1 = kernel[0]; 00172 unit.filter2 = kernel[1]; 00173 units_.push_back(unit); 00174 } 00175 } 00176 } 00177 00178 void BIFImpl::computeUnit(int unit_idx, const cv::Mat &img, 00179 cv::Mat &dst) const { 00180 cv::Mat resp1, resp2; 00181 cv::filter2D(img, resp1, CV_32F, units_[unit_idx].filter1); 00182 cv::filter2D(img, resp2, CV_32F, units_[unit_idx].filter2); 00183 00184 cv::Mat resp, sum, sumsq; 00185 cv::max(resp1, resp2, resp); 00186 cv::integral (resp, sum, sumsq); 00187 00188 int Hhalf = units_[unit_idx].cell_size.height / 2; 00189 int Whalf = units_[unit_idx].cell_size.width / 2; 00190 00191 int nrows = (resp.rows + Hhalf - 1) / Hhalf; 00192 int ncols = (resp.cols + Whalf - 1) / Whalf; 00193 dst.create(nrows*ncols, 1, CV_32F); 00194 00195 for (int pos = 0, yc = 0; yc < resp.rows; yc += Hhalf) { 00196 int y0 = std::max(0, yc - Hhalf); 00197 int y1 = std::min(resp.rows, yc + Hhalf); 00198 00199 for (int xc = 0; xc < resp.cols; xc += Whalf, ++pos) { 00200 int x0 = std::max(0, xc - Whalf); 00201 int x1 = std::min(resp.cols, xc + Whalf); 00202 int area = (y1-y0) * (x1-x0); 00203 00204 double mean = sum.at<double>(y1,x1) - sum.at<double>(y1,x0) 00205 - sum.at<double>(y0,x1) + sum.at<double>(y0,x0); 00206 mean /= area; 00207 00208 double sd = sumsq.at<double>(y1,x1) - sumsq.at<double>(y1,x0) 00209 - sumsq.at<double>(y0,x1) + sumsq.at<double>(y0,x0); 00210 sd = sqrt(std::max(0.0, sd / area - mean * mean)); 00211 00212 dst.at<float>(pos) = static_cast<float>(sd); 00213 } 00214 } 00215 } 00216 00217 } // namespace 00218 00219 cv::Ptr<cv::face::BIF> cv::face::createBIF(int num_bands, int num_rotations) { 00220 return cv::Ptr<cv::face::BIF>(new BIFImpl(num_bands, num_rotations)); 00221 } 00222
Generated on Tue Jul 12 2022 14:46:01 by
1.7.2
