From 447567a8700dcd79ea40aeb0c210261cef8c8ada Mon Sep 17 00:00:00 2001 From: Jim Martens Date: Tue, 30 May 2017 17:29:48 +0200 Subject: [PATCH] [CCV] Added oriented and laplacian pyramid Signed-off-by: Jim Martens --- ccv/saliency/includes/laplacian_pyramid.h | 33 +++++++++++ ccv/saliency/includes/oriented_pyramid.h | 57 +++++++++++++++++++ ccv/saliency/laplacian_pyramid.cpp | 19 +++++++ ccv/saliency/oriented_pyramid.cpp | 68 +++++++++++++++++++++++ 4 files changed, 177 insertions(+) create mode 100644 ccv/saliency/includes/laplacian_pyramid.h create mode 100644 ccv/saliency/includes/oriented_pyramid.h create mode 100644 ccv/saliency/laplacian_pyramid.cpp create mode 100644 ccv/saliency/oriented_pyramid.cpp diff --git a/ccv/saliency/includes/laplacian_pyramid.h b/ccv/saliency/includes/laplacian_pyramid.h new file mode 100644 index 0000000..4a95656 --- /dev/null +++ b/ccv/saliency/includes/laplacian_pyramid.h @@ -0,0 +1,33 @@ +#ifndef SHEET5_LAPLACIAN_PYRAMID_H +#define SHEET5_LAPLACIAN_PYRAMID_H + +#include +#include "gauss_pyramid.h" + +class laplacian_pyramid { +private: + std::vector _layers; +public: + /** + * Initializes the laplacian pyramid. + * @param pyramid the gaussian pyramid + * @param sigma the blur factor + */ + laplacian_pyramid(const gauss_pyramid& pyramid, float sigma); + + /** + * Returns the number of layers. + * @return + */ + unsigned long get_number_of_layers() const; + + /** + * Returns the pyramid element at given layer. + * @param layer the requested pyramid layer + * @return pyramid layer + */ + cv::Mat get(int layer) const; +}; + + +#endif //SHEET5_LAPLACIAN_PYRAMID_H diff --git a/ccv/saliency/includes/oriented_pyramid.h b/ccv/saliency/includes/oriented_pyramid.h new file mode 100644 index 0000000..df696f8 --- /dev/null +++ b/ccv/saliency/includes/oriented_pyramid.h @@ -0,0 +1,57 @@ +#ifndef SHEET5_ORIENTED_PYRAMID_H +#define SHEET5_ORIENTED_PYRAMID_H + +#include +#include "laplacian_pyramid.h" + +class oriented_pyramid { +private: + std::vector> _orientation_maps; + std::vector _gabor_filters; + std::vector _feature_maps; + cv::Mat _C; + + /** + * Initializes the Gabor filters. + * @param num_orientations the number of orientations to use + */ + void initialize_gabor_filters(float num_orientations); +public: + /** + * Initializes the oriented pyramid. + * @param pyramid the laplacian pyramid + * @param num_orientations the number of Gabor filters to apply + */ + oriented_pyramid(const laplacian_pyramid& pyramid, int num_orientations); + + /** + * Computes the feature maps. + */ + void compute_feature_maps(); + + /** + * Computes the conspicuity map. + */ + void compute_conspicuity_map(); + + /** + * Returns the conspicuity map. + * Has to be called after compute_conspicuity_map. + * + * @return conspicuity map + */ + cv::Mat get_conspicuity_map(); + + /** + * Returns the feature map for the nth orientation. + * + * compute_feature_maps must be called first. + * + * @param orientation the nth orientation + * @return the feature map + */ + cv::Mat get_feature_map(int orientation); +}; + + +#endif //SHEET5_ORIENTED_PYRAMID_H diff --git a/ccv/saliency/laplacian_pyramid.cpp b/ccv/saliency/laplacian_pyramid.cpp new file mode 100644 index 0000000..8e13f66 --- /dev/null +++ b/ccv/saliency/laplacian_pyramid.cpp @@ -0,0 +1,19 @@ +#include "includes/laplacian_pyramid.h" + +laplacian_pyramid::laplacian_pyramid(const gauss_pyramid &pyramid, float sigma) { + _layers = std::vector(); + unsigned long number_of_layers = pyramid.get_number_of_layers(); + for (int i = 0; i < number_of_layers; i++) { + cv::Mat blurred; + cv::GaussianBlur(pyramid.get(i), blurred, cv::Size(), sigma, sigma, cv::BORDER_CONSTANT); + _layers.push_back(pyramid.get(i) - blurred); + } +} + +cv::Mat laplacian_pyramid::get(int layer) const { + return _layers.at((unsigned long) layer); +} + +unsigned long laplacian_pyramid::get_number_of_layers() const { + return _layers.size(); +} diff --git a/ccv/saliency/oriented_pyramid.cpp b/ccv/saliency/oriented_pyramid.cpp new file mode 100644 index 0000000..a3c816e --- /dev/null +++ b/ccv/saliency/oriented_pyramid.cpp @@ -0,0 +1,68 @@ +#include "includes/oriented_pyramid.h" +#include "includes/fusion.h" + +oriented_pyramid::oriented_pyramid(const laplacian_pyramid &pyramid, int num_orientations) { + _gabor_filters = std::vector(); + _orientation_maps = std::vector>(); + _feature_maps = std::vector(); + + initialize_gabor_filters(num_orientations); + unsigned long number_of_layers = pyramid.get_number_of_layers(); + for (unsigned long i = 0; i < num_orientations; i++) { + std::vector orientation_vector = std::vector(); + for (int layer = 0; layer < number_of_layers; layer++) { + cv::Mat filtered_image; + cv::filter2D(pyramid.get(layer), filtered_image, -1, _gabor_filters.at(i), cv::Point(-1, -1), 0, cv::BORDER_CONSTANT); + orientation_vector.push_back(filtered_image.clone()); + } + _orientation_maps.push_back(orientation_vector); + } + +} + +void oriented_pyramid::initialize_gabor_filters(float num_orientations) { + cv::Size size = cv::Size(20, 20); + double wavelength = 3; + double standard_deviation = 18; + + double start_level = num_orientations / 2.0; + for (double level = start_level; level >= 0; level--) { + _gabor_filters.push_back(cv::getGaborKernel(size, standard_deviation, (level/num_orientations) * CV_PI, wavelength, + 1, 0, CV_32F)); + } + + double end_level = start_level; + start_level = num_orientations - 1; + + for (double level = start_level; level > end_level; level--) { + _gabor_filters.push_back(cv::getGaborKernel(size, standard_deviation, (level/num_orientations) * CV_PI, wavelength, + 1, 0, CV_32F)); + } +} + +void oriented_pyramid::compute_feature_maps() { + unsigned long num_orientations = _orientation_maps.size(); + for (unsigned long i = 0; i < num_orientations; i++) { + cv::Mat feature_map = (cv::Mat &&) _orientation_maps.at(i).front(); + cv::Size original_size = feature_map.size(); + unsigned long num_layers = _orientation_maps.at(i).size(); + for (unsigned long layer = 1; layer < num_layers; layer++) { + cv::Mat resized_image; + cv::resize(_orientation_maps.at(i).at(layer), resized_image, original_size, 0, 0, cv::INTER_CUBIC); + feature_map += resized_image; + } + _feature_maps.push_back(feature_map.clone()); + } +} + +void oriented_pyramid::compute_conspicuity_map() { + _C = max_fusion_generic(_feature_maps); +} + +cv::Mat oriented_pyramid::get_conspicuity_map() { + return _C; +} + +cv::Mat oriented_pyramid::get_feature_map(int orientation) { + return _feature_maps.at((unsigned long) orientation); +}