Skip to content

Instantly share code, notes, and snippets.

@wzpan
Created February 23, 2014 07:49
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save wzpan/9168408 to your computer and use it in GitHub Desktop.
A backup for image filters.
/**
* @file ImageFilter.cpp
* @author Joseph Pan <cs.wzpan@gmail.com>
* @date Sat Feb 22 16:34:00 2014
*
* @brief Create filters
*
* [Johnston80] - J D Johnston, "A filter family designed for use in quadrature
* mirror filter banks", Proc. ICASSP, pp 291-294, 1980.
*
* [Daubechies88] - I Daubechies, "Orthonormal bases of compactly supported wavelets",
* Commun. Pure Appl. Math, vol. 42, pp 909-996, 1988.
*
* [Simoncelli88] - E P Simoncelli, "Orthogonal sub-band image transforms",
* PhD Thesis, MIT Dept. of Elec. Eng. and Comp. Sci. May 1988.
* Also available as: MIT Media Laboratory Vision and Modeling Technical
* Report #100.
*
* [Simoncelli90] - E P Simoncelli and E H Adelson, "Subband image coding",
* Subband Transforms, chapter 4, ed. John W Woods, Kluwer Academic
* Publishers, Norwell, MA, 1990, pp 143--192.
*
*/
#include "ImageFilter.h"
/**
* ImageFilter - construct function
*
* @param TYPE - filter type
* @param size - kernel size
*/
ImageFilter::ImageFilter(const filter_type TYPE, const int size)
{
create(TYPE, size);
}
/**
* create - construct a filter kernel
*
* @param TYPE - filter type
* @param size - kernel size
*
* @return true if success
*/
bool ImageFilter::create(const filter_type TYPE, const int size)
{
bool flag;
switch (TYPE) {
case FILTER_BINOM:
flag = binomialFilter(size);
break;
case FILTER_GAUSS:
flag = gaussianKernel(size);
break;
case FILTER_QMF:
flag = qmfFilter(size);
break;
case FILTER_HAAR:
flag = haarFilter();
break;
case FILTER_DAUB:
flag = daubFilter(size);
break;
default:
perror("Error filter type!");
flag = false;
break;
}
return flag;
}
/**
* binomialFilter - binomial coefficient filter of order N-1
*
* @param size - kernel size
*
* @return
*/
bool ImageFilter::binomialFilter(const int size)
{
cv::Mat temp;
if (size < 2) {
perror("Size argument must be larger than 1");
return false;
}
kernel = cv::Mat(1, 2, CV_32F, cv::Scalar(0));
kernel.at<float>(0) = kernel.at<float>(1) = 0.5;
temp = kernel.clone();
for (int i=0; i < size-2; ++i) {
cv::filter2D(kernel, kernel, CV_32F, temp);
}
return true;
}
/**
* gaussianKernel - Gaussian Filter
*
* @param size - kernel size
*
* @return
*/
bool ImageFilter::gaussianKernel(const int size)
{
kernel = cv::Mat(1, size, CV_32F, cv::Scalar(0));
switch(size) {
case 5:
kernel.at<float>(0) = kernel.at<float>(4) =0.0625;
kernel.at<float>(1) = kernel.at<float>(3) = 0.25;
kernel.at<float>(2) = 0.375;
break;
case 3:
kernel.at<float>(0) = kernel.at<float>(2) = 0.25;
kernel.at<float>(1) = 0.5;
break;
default:
perror("Error kernel size!");
return false;
}
kernel = sqrt(2) * kernel;
return true;
}
/**
* qmfFilter - Symmetric Quadrature Mirror Filters
*
* @param size - kernel size
*
* @return true if success
*/
bool ImageFilter::qmfFilter(const int size)
{
kernel = cv::Mat(1, size, CV_32F, cv::Scalar(0));
switch(size) {
case 5:
kernel.at<float>(0) = kernel.at<float>(4) = -0.076103;
kernel.at<float>(1) = kernel.at<float>(3) = 0.3535534;
kernel.at<float>(2) = 0.8593118;
break;
case 8:
kernel.at<float>(0) = kernel.at<float>(7) = 0.00938715;
kernel.at<float>(1) = kernel.at<float>(6) = -0.07065183;
kernel.at<float>(2) = kernel.at<float>(5) = 0.06942827;
kernel.at<float>(3) = kernel.at<float>(4) = 0.4899808;
break;
case 9:
kernel.at<float>(0) = kernel.at<float>(8) = 0.02807382;
kernel.at<float>(1) = kernel.at<float>(7) = -0.060944743;
kernel.at<float>(2) = kernel.at<float>(6) = -0.073386624;
kernel.at<float>(3) = kernel.at<float>(5) = 0.41472545;
kernel.at<float>(4) = 0.7973934;
break;
case 12:
kernel.at<float>(0) = kernel.at<float>(11) = -0.003809699;
kernel.at<float>(1) = kernel.at<float>(10) = 0.01885659;
kernel.at<float>(2) = kernel.at<float>(9) = -0.002710326;
kernel.at<float>(3) = kernel.at<float>(8) = -0.08469594;
kernel.at<float>(4) = kernel.at<float>(7) = 0.08846992;
kernel.at<float>(5) = kernel.at<float>(6) = 0.4843894;
break;
case 13:
kernel.at<float>(0) = kernel.at<float>(12) = -0.014556438;
kernel.at<float>(1) = kernel.at<float>(11) = 0.021651438;
kernel.at<float>(2) = kernel.at<float>(10) = 0.039045125;
kernel.at<float>(3) = kernel.at<float>(9) = -0.09800052;
kernel.at<float>(4) = kernel.at<float>(8) = -0.057827797;
kernel.at<float>(5) = kernel.at<float>(7) = 0.42995453;
kernel.at<float>(6) = 0.7737113;
break;
case 16:
kernel.at<float>(0) = kernel.at<float>(15) = 0.001050167;
kernel.at<float>(1) = kernel.at<float>(14) = -0.005054526;
kernel.at<float>(2) = kernel.at<float>(13) = -0.002589756;
kernel.at<float>(3) = kernel.at<float>(12) = 0.0276414;
kernel.at<float>(4) = kernel.at<float>(11) = -0.009666376;
kernel.at<float>(5) = kernel.at<float>(10) = -0.09039223;
kernel.at<float>(6) = kernel.at<float>(9) = 0.09779817;
kernel.at<float>(7) = kernel.at<float>(8) = 0.4810284;
break;
default:
perror("Error kernel size!");
return false;
}
kernel = sqrt(2) * kernel;
return true;
}
/**
* haarFilter - Haar wavelet.
*
* @return true if success
*/
bool ImageFilter::haarFilter()
{
double m[2] = {1, 1};
kernel = cv::Mat(2, 1, CV_32F, m).inv();
kernel = kernel / sqrt(2);
return true;
}
/**
* daubFilter - Daubechies wavelet [Daubechies88].
*
*
* @param size - kernel size
*
* @return
*/
bool ImageFilter::daubFilter(const int size)
{
kernel = cv::Mat(1, 2 * size, CV_32F, cv::Scalar(0));
switch(size) {
case 2:
kernel.at<float>(0) = 0.482962913145;
kernel.at<float>(1) = 0.836516303738;
kernel.at<float>(2) = 0.224143868042;
kernel.at<float>(3) = -0.129409522551;
break;
case 3:
kernel.at<float>(0) = 0.332670552950;
kernel.at<float>(1) = 0.806891509311;
kernel.at<float>(2) = 0.459877502118;
kernel.at<float>(3) = -0.135011020010;
kernel.at<float>(4) = -0.085441273882;
kernel.at<float>(5) = 0.035226291882;
break;
case 4:
kernel.at<float>(0) = 0.230377813309;
kernel.at<float>(1) = 0.714846570553;
kernel.at<float>(2) = 0.630880767930;
kernel.at<float>(3) = -0.027983769417;
kernel.at<float>(4) = -0.187034811719;
kernel.at<float>(5) = 0.030841381836;
kernel.at<float>(6) = 0.032883011667;
kernel.at<float>(7) = -0.010597401785;
break;
default:
perror("Error kernel size!");
return false;
}
return true;
}
/**
* getKernel - return filter kernel
*
*
* @return filter kernel
*/
cv::Mat ImageFilter::getKernel()
{
return kernel;
}
/**
* setKernel - set filter kernel
*
* @param kn - filter kernel
*/
void ImageFilter::setKernel(cv::Mat kn)
{
kernel = kn;
}
#ifndef IMAGEFILTER_H
#define IMAGEFILTER_H
#include <stdio.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
enum filter_type{FILTER_BINOM, FILTER_GAUSS, FILTER_QMF, FILTER_HAAR, FILTER_DAUB};
// Image filters
class ImageFilter {
public:
// construct a filter kernel
ImageFilter(){}
ImageFilter(const filter_type TYPE, const int size = 0);
bool create(const filter_type TYPE, const int size = 0);
cv::Mat getKernel();
void setKernel(cv::Mat);
private:
cv::Mat kernel;
bool gaussianKernel(const int size);
bool binomialFilter(const int size);
bool qmfFilter(const int size);
bool haarFilter();
bool daubFilter(const int size);
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment