(同态滤波器)HomoFilter based on C++

HIT2018暑期创新训练课

图像工程导论作业源码

-------------------------------------------------- by cx

1. Enhancement.h(头文件:声明所用库,名字空间以及所用函数)

#ifndef ENHANCEMENT_H_INCLUDED

#define ENHANCEMENT_H_INCLUDED

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

#include <vector>

 

using namespace cv;

using namespace std;

 

void Equalized(Mat image);

void Laplace(Mat image);

void cx_HomoFilter(Mat image, Mat &dst);

 

#endif

2. main.cpp(主函数:读取图片或者视频帧)

#include"Enhancement.h"

 

int main()

{

    //图像

    //Mat src_mat = imread("lalala.jpg", 3);

    //imshow("src:", src_mat);

    //Mat dst_mat(src_mat.rows, src_mat.cols, src_mat.type());

    Equalized(frame);

    Laplace(frame);

    //cx_HomoFilter(src_mat, dst_mat);

    //waitKey(0);

    //return 0;

 

    //视频

    VideoCapture capture("MAQ01240.MP4");

    if (!capture.isOpened())

    return 1;

    double rate = capture.get(CV_CAP_PROP_FPS);

    bool stop(false);

    Mat frame;

    int delay = 1000 / rate;

    while (!stop)

    {

    if (!capture.read(frame))

    break;

    Mat dst_mat(frame.rows, frame.cols, frame.type());

    //Equalized(frame);

    //Laplace(frame);

    cx_HomoFilter(frame, dst_mat);

    int c = waitKey(delay);

    //按下ESC或者到达指定的结束帧后退出读取视频

    if ((char)c == 27 )

    {

         stop = true;

    }

    //按下按键后会停留在当前帧,等待下一次按键

    if (c >= 0)

    {

         waitKey(0);

    }

    waitKey(delay);

    if (waitKey(delay) >= 0)

         stop = true;

    }

    capture.release();

    waitKey(0);

    return 0;

}

3. Equalized.cpp(直方图均衡函数定义)

#include"Enhancement.h"

 

void Equalized(Mat image)

{

    Mat YCrCb_image;

    YCrCb_image.create(image.size(), image.type());

    cvtColor(image, YCrCb_image, CV_BGR2YCrCb);

    imshow("YCrCb", YCrCb_image);

 

    vector<Mat> channels;

    channels.resize(3);

 

    split(YCrCb_image, channels);

 

 

    equalizeHist(channels[0], channels[0]);

 

    merge(channels, YCrCb_image);

    cvtColor(YCrCb_image, YCrCb_image, CV_YCrCb2BGR); //change the color image from YCrCb to BGR format (to display image properly)

   

    imshow("Equalized", YCrCb_image);

    imshow("Original", image);

}

4. cx_HomoFilter.cpp(同态滤波函数定义)

#include"Enhancement.h"

 

void cx_HomoFilter(Mat image, Mat &dst)

{

    resize(image, image, Size(480, 480)); //vc::dct只能处理方阵

    imshow("image", image);

 

    //转HSV

    Mat YUV_image(image.size(), CV_64FC3);

    cvtColor(image, YUV_image, CV_BGR2YUV);

    //imshow("YUV", YUV_image);

 

    vector<Mat> channels;

    channels.resize(3);

 

    split(YUV_image, channels);

 

    Mat y0 = channels.at(0); //imshow("Y0", y0); //保存原始值用于test

    Mat u0 = channels.at(1); //imshow("U0", u0);

    Mat v0 = channels.at(2); //imshow("V0", v0);

 

    Mat y = channels.at(0);   //imshow("Y", y); //YUV

    Mat u = channels.at(1); //imshow("U", u);

    Mat v = channels.at(2); //imshow("V", v);

 

    y.convertTo(y, CV_64FC1); //转换格式为CV_64FC1

    u.convertTo(u, CV_64FC1);

    v.convertTo(v, CV_64FC1);

 

    //1.求对数

    for (int i = 0; i < y.rows; i++)

    {

         double* srcdata = y.ptr<double>(i);

         double* logdata = y.ptr<double>(i);

         for (int j = 0; j < y.cols; j++)

         {

             srcdata[j] = srcdata[j] / 255.0 + 1; //避免图像变成白色

             logdata[j] = log(srcdata[j]);

         }

    }

    //imshow("LnImgY", y);

    for (int i = 0; i < u.rows; i++)

    {

         double* srcdata = u.ptr<double>(i);

         double* logdata = u.ptr<double>(i);

         for (int j = 0; j < u.cols; j++)

         {

             srcdata[j] = srcdata[j] / 255.0 + 1;

             logdata[j] = log(srcdata[j]);

         }

    }

    //imshow("LnImgU", u);

    for (int i = 0; i < v.rows; i++)

    {

         double* srcdata = v.ptr<double>(i);

         double* logdata = v.ptr<double>(i);

         for (int j = 0; j < v.cols; j++)

         {

             srcdata[j] = srcdata[j] / 255.0 + 1;

             logdata[j] = log(srcdata[j]);

         }

    }

    //imshow("LnImgV", v);

 

    //2.DCT

 

    //定义DCT系数的三个通道

    Mat DCTY(image.size(), CV_64FC1);

    Mat DCTU(image.size(), CV_64FC1);

    Mat DCTV(image.size(), CV_64FC1);

 

    dct(y, DCTY);

    dct(u, DCTU);

    dct(v, DCTV);

 

    imshow("DCTY", DCTY);

    imshow("DCTU", DCTU);

    imshow("DCTV", DCTV);

 

    //3.高通滤波

    double gammaH = 3.5;//调节gammaH与gammaL的值,调节对比度

    double gammaL = 2.5;

    double C = 5;

    //double d0 = (image.rows / 2)*(image.rows / 2) + (image.cols / 2)*(image.cols / 2);

    double d0 = 5; //截止值

    double d2 = 0;

 

    Mat HFilter = Mat::zeros(image.size(), CV_64FC1);

 

    double totalWeight = 0.0;

    for (int i = 0; i < image.rows; i++)

    {

         double * dataH_u_v = HFilter.ptr<double>(i);

         for (int j = 0; j < image.cols; j++)

         {

             d2 = pow((i), 2.0) + pow((j), 2.0);

             dataH_u_v[j] = (gammaH - gammaL)*(1 - exp(-C*d2 / d0)) + gammaL;

             totalWeight += dataH_u_v[j];

         }

    }

    HFilter.ptr<double>(0)[0] = 9.5;//(0,0)处设置亮度

 

    //imshow("HFilter", HFilter);

 

    DCTY = DCTY.mul(HFilter);

    DCTU = DCTU.mul(HFilter);

    DCTV = DCTV.mul(HFilter);

 

    //imshow("DCTY_Filter", DCTY);

    //imshow("DCTU_Filter", DCTU);

    //imshow("DCTV_Filter", DCTV);

 

    //4.IDCT

    Mat DSTY;

    Mat DSTU;

    Mat DSTV;

 

    idct(DCTY, DSTY);

    idct(DCTU, DSTU);

    idct(DCTV, DSTV);

 

    imshow("DSTY", DSTY);

    imshow("DSTU", DSTU);

    imshow("DSTV", DSTV);

 

    for (int i = 0; i < DSTY.rows; i++)

    {

         double* srcdata = DSTY.ptr<double>(i);

         double* dstdata = DSTY.ptr<double>(i);

         for (int j = 0; j < DSTY.cols; j++)

         {

             dstdata[j] = exp(srcdata[j]);

             dstdata[j] = (dstdata[j] - 1) * 255.0;

         }

    }

    for (int i = 0; i < DSTU.rows; i++)

    {

         double* srcdata = DSTU.ptr<double>(i);

         double* dstdata = DSTU.ptr<double>(i);

         for (int j = 0; j < DSTU.cols; j++)

         {

             dstdata[j] = exp(srcdata[j]);

             dstdata[j] = (dstdata[j] - 1) * 255.0;

         }

    }

    for (int i = 0; i < DSTV.rows; i++)

    {

         double* srcdata = DSTV.ptr<double>(i);

         double* dstdata = DSTV.ptr<double>(i);

         for (int j = 0; j < DSTV.cols; j++)

         {

             dstdata[j] = exp(srcdata[j]);

             dstdata[j] = (dstdata[j] - 1) * 255.0;

         }

    }

   

    DSTY.convertTo(DSTY, CV_8UC1);

    DSTU.convertTo(DSTU, CV_8UC1);

    DSTV.convertTo(DSTV, CV_8UC1);

 

    u0.convertTo(DSTU, CV_8UC1);

    v0.convertTo(DSTV, CV_8UC1);

 

    imshow("DSTY_8U", DSTY);

    imshow("DSTU_8U", DSTU);

    imshow("DSTV_8U", DSTV);

 

    y.convertTo(y, CV_32FC1);

    u.convertTo(u, CV_32FC1);

    v.convertTo(v, CV_32FC1);

 

    channels.at(0) = DSTY;

    channels.at(1) = DSTU;

    channels.at(2) = DSTV;

    //channels.at(1) = u0;//test 只对Y处理,或者只对YV处理,或者YUV一起处理

    //channels.at(2) = v0;

 

    Mat DstImage;

    merge(channels, DstImage);

    imshow("456", DstImage);

    cvtColor(DstImage, DstImage, CV_YUV2BGR);

    imshow("图像", DstImage);

}

最后处理效果如下:(测试图像为彩色图像,但是由于曝光不足,处理之前与处理之后看起来都像是黑白图像)

原图:

滤波之后:

------------------------ 转载或用于商业用途需声明以及告知本人

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值