wzpan
2/23/2014 - 7:49 AM

A backup for image filters.

A backup for image filters.

#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
/**
 * @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;
}