merged ICFPreprocessor and Channels -> ChannelFeatureBuilder
This commit is contained in:
parent
49ec664238
commit
f3227c3f1a
@ -51,11 +51,12 @@ sft::ICFFeaturePool::ICFFeaturePool(cv::Size m, int n) : FeaturePool(), model(m)
|
||||
{
|
||||
CV_Assert(m != cv::Size() && n > 0);
|
||||
fill(nfeatures);
|
||||
builder = cv::ChannelFeatureBuilder::create();
|
||||
}
|
||||
|
||||
void sft::ICFFeaturePool::preprocess(cv::InputArray frame, cv::OutputArray integrals) const
|
||||
{
|
||||
preprocessor.apply(frame, integrals);
|
||||
(*builder)(frame, integrals);
|
||||
}
|
||||
|
||||
float sft::ICFFeaturePool::apply(int fi, int si, const Mat& integrals) const
|
||||
|
@ -119,7 +119,7 @@ private:
|
||||
|
||||
static const unsigned int seed = 0;
|
||||
|
||||
cv::ICFPreprocessor preprocessor;
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> builder;
|
||||
|
||||
enum { N_CHANNELS = 10 };
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ if(ANDROID OR IOS OR NOT PYTHONLIBS_FOUND OR NOT PYTHON_USE_NUMPY)
|
||||
endif()
|
||||
|
||||
set(the_description "The python bindings")
|
||||
ocv_add_module(python BINDINGS opencv_core opencv_flann opencv_imgproc opencv_video opencv_ml opencv_features2d opencv_highgui opencv_calib3d opencv_photo opencv_objdetect opencv_contrib opencv_legacy OPTIONAL opencv_nonfree)
|
||||
ocv_add_module(python BINDINGS opencv_core opencv_flann opencv_imgproc opencv_video opencv_ml opencv_features2d opencv_highgui opencv_calib3d opencv_photo opencv_objdetect opencv_contrib opencv_legacy opencv_softcascade OPTIONAL opencv_nonfree)
|
||||
|
||||
add_definitions(-DPYTHON_USE_NUMPY=1)
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "opencv2/ml/ml.hpp"
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "opencv2/objdetect/objdetect.hpp"
|
||||
#include "opencv2/softcascade/softcascade.hpp"
|
||||
#include "opencv2/video/tracking.hpp"
|
||||
#include "opencv2/video/background_segm.hpp"
|
||||
#include "opencv2/photo/photo.hpp"
|
||||
@ -124,6 +125,8 @@ typedef Ptr<DescriptorExtractor> Ptr_DescriptorExtractor;
|
||||
typedef Ptr<Feature2D> Ptr_Feature2D;
|
||||
typedef Ptr<DescriptorMatcher> Ptr_DescriptorMatcher;
|
||||
|
||||
typedef Ptr<ChannelFeatureBuilder> Ptr_ChannelFeatureBuilder;
|
||||
|
||||
typedef SimpleBlobDetector::Params SimpleBlobDetector_Params;
|
||||
|
||||
typedef cvflann::flann_distance_t cvflann_flann_distance_t;
|
||||
|
@ -93,53 +93,15 @@ public:
|
||||
// Implementation of Integral Channel Feature.
|
||||
// ========================================================================== //
|
||||
|
||||
class CV_EXPORTS_W IntegralChannelBuilder : public Algorithm
|
||||
class CV_EXPORTS_W ChannelFeatureBuilder : public Algorithm
|
||||
{
|
||||
public:
|
||||
CV_WRAP IntegralChannelBuilder();
|
||||
CV_WRAP virtual ~IntegralChannelBuilder();
|
||||
virtual ~ChannelFeatureBuilder();
|
||||
|
||||
cv::AlgorithmInfo* info() const;
|
||||
// apply channels to source frame
|
||||
CV_WRAP_AS(compute) virtual void operator()(InputArray src, CV_OUT OutputArray channels) const = 0;
|
||||
|
||||
// Load channel builder config.
|
||||
CV_WRAP virtual void read(const FileNode& fileNode);
|
||||
|
||||
private:
|
||||
struct Fields;
|
||||
cv::Ptr<Fields> fields;
|
||||
|
||||
};
|
||||
|
||||
// Create channel integrals for Soft Cascade detector.
|
||||
class CV_EXPORTS Channels
|
||||
{
|
||||
public:
|
||||
// constrictor form resizing factor.
|
||||
// Param shrinkage is a resizing factor. Resize is applied before the computing integral sum
|
||||
Channels(const int shrinkage);
|
||||
|
||||
// Appends specified number of HOG first-order features integrals into given vector.
|
||||
// Param gray is an input 1-channel gray image.
|
||||
// Param integrals is a vector of integrals. Hog-channels will be appended to it.
|
||||
// Param bins is a number of hog-bins
|
||||
void appendHogBins(const cv::Mat& gray, std::vector<cv::Mat>& integrals, int bins) const;
|
||||
|
||||
// Converts 3-channel BGR input frame in Luv and appends each channel to the integrals.
|
||||
// Param frame is an input 3-channel BGR colored image.
|
||||
// Param integrals is a vector of integrals. Computed from the frame luv-channels will be appended to it.
|
||||
void appendLuvBins(const cv::Mat& frame, std::vector<cv::Mat>& integrals) const;
|
||||
|
||||
private:
|
||||
int shrinkage;
|
||||
};
|
||||
|
||||
class CV_EXPORTS_W ICFPreprocessor
|
||||
{
|
||||
public:
|
||||
CV_WRAP ICFPreprocessor();
|
||||
CV_WRAP void apply(cv::InputArray _frame, cv::OutputArray _integrals) const;
|
||||
protected:
|
||||
enum {BINS = 10};
|
||||
CV_WRAP static cv::Ptr<ChannelFeatureBuilder> create();
|
||||
};
|
||||
|
||||
// ========================================================================== //
|
||||
|
@ -1,170 +0,0 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2013, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * 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.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// 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 Intel Corporation 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.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
cv::ICFPreprocessor::ICFPreprocessor() {}
|
||||
void cv::ICFPreprocessor::apply(cv::InputArray _frame, cv::OutputArray _integrals) const
|
||||
{
|
||||
CV_Assert(_frame.type() == CV_8UC3);
|
||||
|
||||
cv::Mat frame = _frame.getMat();
|
||||
cv::Mat& integrals = _integrals.getMatRef();
|
||||
|
||||
int h = frame.rows;
|
||||
int w = frame.cols;
|
||||
|
||||
cv::Mat channels, gray;
|
||||
|
||||
channels.create(h * BINS, w, CV_8UC1);
|
||||
channels.setTo(0);
|
||||
|
||||
cvtColor(frame, gray, CV_BGR2GRAY);
|
||||
|
||||
cv::Mat df_dx, df_dy, mag, angle;
|
||||
cv::Sobel(gray, df_dx, CV_32F, 1, 0);
|
||||
cv::Sobel(gray, df_dy, CV_32F, 0, 1);
|
||||
|
||||
cv::cartToPolar(df_dx, df_dy, mag, angle, true);
|
||||
mag *= (1.f / (8 * sqrt(2.f)));
|
||||
|
||||
cv::Mat nmag;
|
||||
mag.convertTo(nmag, CV_8UC1);
|
||||
|
||||
angle *= 6 / 360.f;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
uchar* magnitude = nmag.ptr<uchar>(y);
|
||||
float* ang = angle.ptr<float>(y);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
channels.ptr<uchar>(y + (h * (int)ang[x]))[x] = magnitude[x];
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat luv, shrunk;
|
||||
cv::cvtColor(frame, luv, CV_BGR2Luv);
|
||||
|
||||
std::vector<cv::Mat> splited;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
splited.push_back(channels(cv::Rect(0, h * (7 + i), w, h)));
|
||||
split(luv, splited);
|
||||
|
||||
float shrinkage = static_cast<float>(integrals.cols - 1) / channels.cols;
|
||||
|
||||
CV_Assert(shrinkage == 0.25);
|
||||
|
||||
cv::resize(channels, shrunk, cv::Size(), shrinkage, shrinkage, CV_INTER_AREA);
|
||||
cv::integral(shrunk, integrals, cv::noArray(), CV_32S);
|
||||
}
|
||||
|
||||
cv::Channels::Channels(int shr) : shrinkage(shr) {}
|
||||
|
||||
void cv::Channels::appendHogBins(const cv::Mat& gray, std::vector<cv::Mat>& integrals, int bins) const
|
||||
{
|
||||
CV_Assert(gray.type() == CV_8UC1);
|
||||
int h = gray.rows;
|
||||
int w = gray.cols;
|
||||
CV_Assert(!(w % shrinkage) && !(h % shrinkage));
|
||||
|
||||
cv::Mat df_dx, df_dy, mag, angle;
|
||||
cv::Sobel(gray, df_dx, CV_32F, 1, 0);
|
||||
cv::Sobel(gray, df_dy, CV_32F, 0, 1);
|
||||
|
||||
cv::cartToPolar(df_dx, df_dy, mag, angle, true);
|
||||
mag *= (1.f / (8 * sqrt(2.f)));
|
||||
|
||||
cv::Mat nmag;
|
||||
mag.convertTo(nmag, CV_8UC1);
|
||||
|
||||
angle *= bins/360.f;
|
||||
|
||||
std::vector<cv::Mat> hist;
|
||||
for (int bin = 0; bin < bins; ++bin)
|
||||
hist.push_back(cv::Mat::zeros(h, w, CV_8UC1));
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
uchar* magnitude = nmag.ptr<uchar>(y);
|
||||
float* ang = angle.ptr<float>(y);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
hist[ (int)ang[x] ].ptr<uchar>(y)[x] = magnitude[x];
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < bins; ++i)
|
||||
{
|
||||
cv::Mat shrunk, sum;
|
||||
cv::resize(hist[i], shrunk, cv::Size(), 1.0 / shrinkage, 1.0 / shrinkage, CV_INTER_AREA);
|
||||
cv::integral(shrunk, sum, cv::noArray(), CV_32S);
|
||||
integrals.push_back(sum);
|
||||
}
|
||||
|
||||
cv::Mat shrMag;
|
||||
cv::resize(nmag, shrMag, cv::Size(), 1.0 / shrinkage, 1.0 / shrinkage, CV_INTER_AREA);
|
||||
cv::integral(shrMag, mag, cv::noArray(), CV_32S);
|
||||
integrals.push_back(mag);
|
||||
}
|
||||
|
||||
void cv::Channels::appendLuvBins(const cv::Mat& frame, std::vector<cv::Mat>& integrals) const
|
||||
{
|
||||
CV_Assert(frame.type() == CV_8UC3);
|
||||
CV_Assert(!(frame.cols % shrinkage) && !(frame.rows % shrinkage));
|
||||
|
||||
cv::Mat luv, shrunk;
|
||||
cv::cvtColor(frame, luv, CV_BGR2Luv);
|
||||
cv::resize(luv, shrunk, cv::Size(), 1.0 / shrinkage, 1.0 / shrinkage, CV_INTER_AREA);
|
||||
|
||||
std::vector<cv::Mat> splited;
|
||||
split(shrunk, splited);
|
||||
|
||||
for (size_t i = 0; i < splited.size(); ++i)
|
||||
{
|
||||
cv::Mat sum;
|
||||
cv::integral(splited[i], sum, cv::noArray(), CV_32S);
|
||||
integrals.push_back(sum);
|
||||
}
|
||||
}
|
@ -42,14 +42,77 @@
|
||||
|
||||
#include "precomp.hpp"
|
||||
|
||||
struct cv::IntegralChannelBuilder::Fields
|
||||
namespace {
|
||||
|
||||
class ICF : public cv::ChannelFeatureBuilder
|
||||
{
|
||||
virtual ~ICF() {}
|
||||
virtual cv::AlgorithmInfo* info() const;
|
||||
virtual void operator()(cv::InputArray _frame, CV_OUT cv::OutputArray _integrals) const
|
||||
{
|
||||
CV_Assert(_frame.type() == CV_8UC3);
|
||||
|
||||
cv::Mat frame = _frame.getMat();
|
||||
int h = frame.rows;
|
||||
int w = frame.cols;
|
||||
_integrals.create(h / 4 * 10 + 1, w / 4 + 1, CV_32SC1);
|
||||
cv::Mat& integrals = _integrals.getMatRef();
|
||||
|
||||
cv::Mat channels, gray;
|
||||
|
||||
channels.create(h * 10, w, CV_8UC1);
|
||||
channels.setTo(0);
|
||||
|
||||
cvtColor(frame, gray, CV_BGR2GRAY);
|
||||
|
||||
cv::Mat df_dx, df_dy, mag, angle;
|
||||
cv::Sobel(gray, df_dx, CV_32F, 1, 0);
|
||||
cv::Sobel(gray, df_dy, CV_32F, 0, 1);
|
||||
|
||||
cv::cartToPolar(df_dx, df_dy, mag, angle, true);
|
||||
mag *= (1.f / (8 * sqrt(2.f)));
|
||||
|
||||
cv::Mat nmag;
|
||||
mag.convertTo(nmag, CV_8UC1);
|
||||
|
||||
angle *= 6 / 360.f;
|
||||
|
||||
for (int y = 0; y < h; ++y)
|
||||
{
|
||||
uchar* magnitude = nmag.ptr<uchar>(y);
|
||||
float* ang = angle.ptr<float>(y);
|
||||
|
||||
for (int x = 0; x < w; ++x)
|
||||
{
|
||||
channels.ptr<uchar>(y + (h * (int)ang[x]))[x] = magnitude[x];
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat luv, shrunk;
|
||||
cv::cvtColor(frame, luv, CV_BGR2Luv);
|
||||
|
||||
std::vector<cv::Mat> splited;
|
||||
for (int i = 0; i < 3; ++i)
|
||||
splited.push_back(channels(cv::Rect(0, h * (7 + i), w, h)));
|
||||
split(luv, splited);
|
||||
|
||||
float shrinkage = static_cast<float>(integrals.cols - 1) / channels.cols;
|
||||
|
||||
CV_Assert(shrinkage == 0.25);
|
||||
|
||||
cv::resize(channels, shrunk, cv::Size(), shrinkage, shrinkage, CV_INTER_AREA);
|
||||
cv::integral(shrunk, integrals, cv::noArray(), CV_32S);
|
||||
}
|
||||
};
|
||||
|
||||
cv::IntegralChannelBuilder::IntegralChannelBuilder() : fields(new Fields()) {}
|
||||
cv::IntegralChannelBuilder::~IntegralChannelBuilder() {}
|
||||
}
|
||||
|
||||
void cv::IntegralChannelBuilder::read(const FileNode& fn)
|
||||
CV_INIT_ALGORITHM(ICF, "ChannelFeatureBuilder.ICF", );
|
||||
|
||||
cv::ChannelFeatureBuilder::~ChannelFeatureBuilder() {}
|
||||
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> cv::ChannelFeatureBuilder::create()
|
||||
{
|
||||
Algorithm::read(fn);
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> builder(new ICF());
|
||||
return builder;
|
||||
}
|
@ -169,37 +169,30 @@ struct Level
|
||||
return (sarea == 0.0f)? threshold : (threshold * scaling[idx] * sarea);
|
||||
}
|
||||
};
|
||||
|
||||
struct ChannelStorage
|
||||
{
|
||||
std::vector<cv::Mat> hog;
|
||||
cv::Mat hog;
|
||||
int shrinkage;
|
||||
int offset;
|
||||
int step;
|
||||
int model_height;
|
||||
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> builder;
|
||||
|
||||
enum {HOG_BINS = 6, HOG_LUV_BINS = 10};
|
||||
|
||||
ChannelStorage(const cv::Mat& colored, int shr) : shrinkage(shr)
|
||||
{
|
||||
hog.clear();
|
||||
hog.reserve(10);
|
||||
cv::Channels ints(shr);
|
||||
builder = cv::ChannelFeatureBuilder::create();
|
||||
(*builder)(colored, hog);
|
||||
|
||||
// convert to gray
|
||||
cv::Mat grey;
|
||||
cv::cvtColor(colored, grey, CV_BGR2GRAY);
|
||||
|
||||
ints.appendHogBins(grey, hog, 6);
|
||||
ints.appendLuvBins(colored, hog);
|
||||
|
||||
step = hog[0].cols;
|
||||
step = hog.step1();
|
||||
model_height = colored.rows / shrinkage;
|
||||
}
|
||||
|
||||
float get(const int channel, const cv::Rect& area) const
|
||||
{
|
||||
// CV_Assert(channel < HOG_LUV_BINS);
|
||||
const cv::Mat& m = hog[channel];
|
||||
int *ptr = ((int*)(m.data)) + offset;
|
||||
const int *ptr = hog.ptr<const int>(0) + model_height * channel * step + offset;
|
||||
|
||||
int a = ptr[area.y * step + area.x];
|
||||
int b = ptr[area.y * step + area.width];
|
||||
@ -509,7 +502,7 @@ void cv::SoftCascadeDetector::detectNoRoi(const cv::Mat& image, std::vector<Dete
|
||||
}
|
||||
}
|
||||
|
||||
if (rejCriteria != NO_REJECT) suppress(rejCriteria, objects);
|
||||
// if (rejCriteria != NO_REJECT) suppress(rejCriteria, objects);
|
||||
}
|
||||
|
||||
void cv::SoftCascadeDetector::detect(cv::InputArray _image, cv::InputArray _rois, std::vector<Detection>& objects) const
|
||||
|
@ -51,13 +51,11 @@ CV_INIT_ALGORITHM(SoftCascadeDetector, "SoftCascade.SoftCascadeDetector",
|
||||
obj.info()->addParam(obj, "scales", obj.scales);
|
||||
obj.info()->addParam(obj, "rejCriteria", obj.rejCriteria));
|
||||
|
||||
CV_INIT_ALGORITHM(IntegralChannelBuilder, "SoftCascade.IntegralChannelBuilder", );
|
||||
|
||||
bool initModule_softcascade(void)
|
||||
{
|
||||
Ptr<Algorithm> sc1 = createSoftCascadeDetector();
|
||||
Ptr<Algorithm> sc2 = createIntegralChannelBuilder();
|
||||
return (sc1->info() != 0) && (sc2->info() != 0);
|
||||
return (sc1->info() != 0);
|
||||
}
|
||||
|
||||
}
|
60
modules/softcascade/test/test_channel_features.cpp
Normal file
60
modules/softcascade/test/test_channel_features.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/*M///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2013, Willow Garage Inc., all rights reserved.
|
||||
// Third party copyrights are property of their respective owners.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification,
|
||||
// are permitted provided that the following conditions are met:
|
||||
//
|
||||
// * Redistribution's of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// * 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.
|
||||
//
|
||||
// * The name of the copyright holders may not be used to endorse or promote products
|
||||
// derived from this software without specific prior written permission.
|
||||
//
|
||||
// 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 Intel Corporation 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.
|
||||
//
|
||||
//M*/
|
||||
|
||||
#include "test_precomp.hpp"
|
||||
|
||||
TEST(ChannelFeatureBuilderTest, info)
|
||||
{
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> builder = cv::ChannelFeatureBuilder::create();
|
||||
ASSERT_TRUE(builder->info() != 0);
|
||||
}
|
||||
|
||||
TEST(ChannelFeatureBuilderTest, compute)
|
||||
{
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> builder = cv::ChannelFeatureBuilder::create();
|
||||
|
||||
cv::Mat colored = cv::imread(cvtest::TS::ptr()->get_data_path() + "cascadeandhog/images/image_00000000_0.png");
|
||||
cv::Mat ints;
|
||||
(*builder)(colored, ints);
|
||||
|
||||
ASSERT_FALSE(ints.empty());
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user