|
|
#include "stdafx.h"
|
|
|
#include "fuseImg.h"
|
|
|
|
|
|
#include "waveDecompose.h"
|
|
|
#include "waveReconstruct.h"
|
|
|
|
|
|
// 直方图投影
|
|
|
#include "histProject.h"
|
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
// 功能:函数 FuseImg() 融合两幅输入图像
|
|
|
bool FuseImg(cv::Mat &dst, const cv::Mat img1, const cv::Mat img2, const string wname, const unsigned int level)
|
|
|
{
|
|
|
// 输入有效性判断
|
|
|
if (img1.empty() == true || (img1.type() != CV_8UC1 && img1.type() != CV_8UC3))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (img2.empty() == true || (img2.type() != CV_8UC1 && img2.type() != CV_8UC3))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (img1.type() != img2.type()
|
|
|
|| img1.size != img2.size)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (wname == "" || level < 1)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 图像类型
|
|
|
int imgType = img1.type();
|
|
|
if (imgType == CV_8UC3)
|
|
|
{
|
|
|
// 提取img1的亮度分量
|
|
|
cv::Mat YCrCb1;
|
|
|
cv::cvtColor(img1, YCrCb1, cv::COLOR_BGR2YCrCb);
|
|
|
std::vector<cv::Mat> planes1;
|
|
|
cv::split(YCrCb1, planes1);
|
|
|
|
|
|
// 提取img2的亮度分量
|
|
|
cv::Mat YCrCb2;
|
|
|
cv::cvtColor(img2, YCrCb2, cv::COLOR_BGR2YCrCb);
|
|
|
std::vector<cv::Mat> planes2;
|
|
|
cv::split(YCrCb2, planes2);
|
|
|
|
|
|
// 融合两幅图像亮度分量
|
|
|
cv::Mat fusion_Y;
|
|
|
if (false == FuseImg(fusion_Y, planes1[0], planes2[0], wname, level))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
planes1[0] = fusion_Y;
|
|
|
|
|
|
// 其余两个通道取平均
|
|
|
planes1[1] = (planes1[1] + planes2[1]) / 2;
|
|
|
planes1[2] = (planes1[2] + planes2[2]) / 2;
|
|
|
|
|
|
cv::merge(planes1, YCrCb1);
|
|
|
cv::cvtColor(YCrCb1, dst, cv::COLOR_YCrCb2BGR);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 图像1 小波分解
|
|
|
std::deque<cv::Mat> coef1;
|
|
|
std::deque<cv::Vec2i> scf1;
|
|
|
|
|
|
// 图像2 小波分解
|
|
|
std::deque<cv::Mat> coef2;
|
|
|
std::deque<cv::Vec2i> scf2;
|
|
|
|
|
|
bool ret1 = true;
|
|
|
bool ret2 = true;
|
|
|
|
|
|
#pragma omp parallel sections
|
|
|
{
|
|
|
#pragma omp section
|
|
|
{
|
|
|
ret1 = waveDec2(coef1, scf1, img1, wname, level);
|
|
|
}
|
|
|
|
|
|
#pragma omp section
|
|
|
{
|
|
|
ret2 = waveDec2(coef2, scf2, img2, wname, level);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (ret1 == false || ret2 == false)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 小波系数融合
|
|
|
|
|
|
// 1低频:取均值
|
|
|
coef1[0] = (coef1[0] + coef2[1]) / 2;
|
|
|
|
|
|
// 2高频:取绝对值较大者
|
|
|
// 理论依据:大的小波系数含有较多的能量
|
|
|
for (unsigned int m = 1; m < coef1.size(); m++)
|
|
|
{
|
|
|
int rows = coef1[m].rows;
|
|
|
int cols = coef1[m].cols;
|
|
|
|
|
|
for (int i = 0; i < rows; i++)
|
|
|
{
|
|
|
for (int j = 0; j < cols; j++)
|
|
|
{
|
|
|
if (abs(coef2[m].at<double>(i, j)) > abs(coef1[m].at<double>(i, j)))
|
|
|
{
|
|
|
coef1[m].at<double>(i, j) = coef2[m].at<double>(i, j);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 图像重构
|
|
|
cv::Mat dst_double;
|
|
|
if (false == waveRec2(dst_double, coef1, scf1, wname, level))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 类型转换
|
|
|
double minVal = 0;
|
|
|
double maxVal = 0;
|
|
|
cv::minMaxIdx(dst_double, &minVal, &maxVal);
|
|
|
|
|
|
cv::Mat preHP; // 直方图均衡化前的融合图像
|
|
|
|
|
|
// 压缩 减少信息损失
|
|
|
dst_double.convertTo(preHP, CV_8UC1, 255.0 / (maxVal - minVal), -minVal / (maxVal - minVal));
|
|
|
|
|
|
// 自适应直方图投影,提高图像对比度
|
|
|
SAHP(dst, preHP);
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 功能:函数 FuseImgRGBplusIR() 融合两幅输入图像
|
|
|
bool FuseImgRGBplusIR(cv::Mat &dst, const cv::Mat CCDimg, const cv::Mat IRimg, const string wname, const unsigned int level)
|
|
|
{
|
|
|
// 输入有效性判断
|
|
|
if (CCDimg.empty() == true || CCDimg.type() != CV_8UC3)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (IRimg.empty() == true || (IRimg.type() != CV_8UC1 && IRimg.type() != CV_8UC3))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (CCDimg.size != IRimg.size)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (wname == "" || level < 1)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 根据类型区分
|
|
|
if (IRimg.type() == CV_8UC3)
|
|
|
{
|
|
|
// 提取IRimg亮度分量
|
|
|
cv::Mat IR;
|
|
|
std::vector<cv::Mat> planesIR;
|
|
|
cv::split(IRimg, planesIR);
|
|
|
planesIR[0].copyTo(IR);
|
|
|
|
|
|
// 提取CCDimg亮度分量
|
|
|
cv::Mat YCrCb;
|
|
|
cv::cvtColor(CCDimg, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
std::vector<cv::Mat> planesCCD;
|
|
|
cv::split(YCrCb, planesCCD);
|
|
|
|
|
|
// 融合两幅图像亮度分量
|
|
|
cv::Mat dst_Y;
|
|
|
if (!FuseImg(dst_Y, planesCCD[0], IR, wname, level))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 重构图像
|
|
|
dst_Y.copyTo(planesCCD[0]);
|
|
|
cv::merge(planesCCD, YCrCb);
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 提取CCDimg亮度分量
|
|
|
cv::Mat YCrCb;
|
|
|
cv::cvtColor(CCDimg, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
std::vector<cv::Mat> planesCCD;
|
|
|
cv::split(YCrCb, planesCCD);
|
|
|
|
|
|
// 融合两幅图像亮度分量
|
|
|
cv::Mat dst_Y;
|
|
|
if (false == FuseImg(dst_Y, planesCCD[0], IRimg, wname, level))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 重构图像
|
|
|
dst_Y.copyTo(planesCCD[0]);
|
|
|
cv::merge(planesCCD, YCrCb);
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// 功能:函数 FastFuseImgCCDplusIR() 快速融合两幅输入图像
|
|
|
bool FastFuseImgRGBplusIR(cv::Mat &dst, const cv::Mat CCDimg, const cv::Mat IRimg)
|
|
|
{
|
|
|
// 输入有效性判断
|
|
|
if (CCDimg.empty() == true || CCDimg.type() != CV_8UC3)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (IRimg.empty() == true || (IRimg.type() != CV_8UC1 && IRimg.type() != CV_8UC3))
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (CCDimg.size != IRimg.size)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 单通道红外图像
|
|
|
cv::Mat IR;
|
|
|
|
|
|
// 根据类型区分
|
|
|
if (IRimg.type() == CV_8UC3)
|
|
|
{
|
|
|
// 提取IRimg亮度分量
|
|
|
std::vector<cv::Mat> planesIR;
|
|
|
cv::split(IRimg, planesIR);
|
|
|
planesIR[0].copyTo(IR);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
IR = IRimg;
|
|
|
}
|
|
|
|
|
|
// 提取CCDimg亮度分量
|
|
|
cv::Mat YCrCb;
|
|
|
cv::cvtColor(CCDimg, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
std::vector<cv::Mat> planesCCD;
|
|
|
cv::split(YCrCb, planesCCD);
|
|
|
|
|
|
// 融合两幅图像亮度分量
|
|
|
cv::Mat dst_Y = 0.5 * planesCCD[0] + 0.5 * IR;
|
|
|
|
|
|
// 增强亮度分量
|
|
|
cv::Mat enchanceDstY;
|
|
|
SAHP(enchanceDstY, dst_Y);
|
|
|
|
|
|
// 重构图像
|
|
|
planesCCD[0] = enchanceDstY;
|
|
|
cv::merge(planesCCD, YCrCb);
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
|
|
|
return true;
|
|
|
} |