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);
}
最后处理效果如下:(测试图像为彩色图像,但是由于曝光不足,处理之前与处理之后看起来都像是黑白图像)
原图:
滤波之后:
------------------------ 转载或用于商业用途需声明以及告知本人