|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "fuseImg.h"
|
|
|
|
|
|
|
|
|
|
#include "waveDecompose.h"
|
|
|
|
|
#include "waveReconstruct.h"
|
|
|
|
|
|
|
|
|
|
// ֱ<><D6B1>ͼͶӰ
|
|
|
|
|
#include "histProject.h"
|
|
|
|
|
|
|
|
|
|
#include <omp.h>
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD> FuseImg() <20>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
bool FuseImg(cv::Mat &dst, const cv::Mat img1, const cv::Mat img2, const string wname, const unsigned int level)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int imgType = img1.type();
|
|
|
|
|
if (imgType == CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
// <20><>ȡimg1<67><31><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat YCrCb1;
|
|
|
|
|
cv::cvtColor(img1, YCrCb1, cv::COLOR_BGR2YCrCb);
|
|
|
|
|
std::vector<cv::Mat> planes1;
|
|
|
|
|
cv::split(YCrCb1, planes1);
|
|
|
|
|
|
|
|
|
|
// <20><>ȡimg2<67><32><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat YCrCb2;
|
|
|
|
|
cv::cvtColor(img2, YCrCb2, cv::COLOR_BGR2YCrCb);
|
|
|
|
|
std::vector<cv::Mat> planes2;
|
|
|
|
|
cv::split(YCrCb2, planes2);
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat fusion_Y;
|
|
|
|
|
if (false == FuseImg(fusion_Y, planes1[0], planes2[0], wname, level))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
planes1[0] = fusion_Y;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8>ȡƽ<C8A1><C6BD>
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
// ͼ<><CDBC>1 С<><D0A1><EFBFBD>ֽ<EFBFBD>
|
|
|
|
|
std::deque<cv::Mat> coef1;
|
|
|
|
|
std::deque<cv::Vec2i> scf1;
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC>2 С<><D0A1><EFBFBD>ֽ<EFBFBD>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// С<><D0A1>ϵ<EFBFBD><CFB5><EFBFBD>ں<EFBFBD>
|
|
|
|
|
|
|
|
|
|
// 1<><31>Ƶ:ȡ<><C8A1>ֵ
|
|
|
|
|
coef1[0] = (coef1[0] + coef2[1]) / 2;
|
|
|
|
|
|
|
|
|
|
// 2<><32>Ƶ<EFBFBD><C6B5>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵ<EFBFBD>ϴ<EFBFBD><CFB4><EFBFBD>
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD><DDA3><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>ϵ<EFBFBD><CFB5><EFBFBD><EFBFBD><EFBFBD>н϶<D0BD><CFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD>ع<EFBFBD>
|
|
|
|
|
cv::Mat dst_double;
|
|
|
|
|
if (false == waveRec2(dst_double, coef1, scf1, wname, level))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
|
|
|
|
|
double minVal = 0;
|
|
|
|
|
double maxVal = 0;
|
|
|
|
|
cv::minMaxIdx(dst_double, &minVal, &maxVal);
|
|
|
|
|
|
|
|
|
|
cv::Mat preHP; // ֱ<><D6B1>ͼ<EFBFBD><CDBC><EFBFBD>⻯ǰ<E2BBAF><C7B0><EFBFBD>ں<EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
|
|
|
|
|
// ѹ<><D1B9> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>ʧ
|
|
|
|
|
dst_double.convertTo(preHP, CV_8UC1, 255.0 / (maxVal - minVal), -minVal / (maxVal - minVal));
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Ӧֱ<D3A6><D6B1>ͼͶӰ<CDB6><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>Աȶ<D4B1>
|
|
|
|
|
SAHP(dst, preHP);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD> FuseImgRGBplusIR() <20>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
bool FuseImgRGBplusIR(cv::Mat &dst, const cv::Mat CCDimg, const cv::Mat IRimg, const string wname, const unsigned int level)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (IRimg.type() == CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
// <20><>ȡIRimg<6D><67><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat IR;
|
|
|
|
|
std::vector<cv::Mat> planesIR;
|
|
|
|
|
cv::split(IRimg, planesIR);
|
|
|
|
|
planesIR[0].copyTo(IR);
|
|
|
|
|
|
|
|
|
|
// <20><>ȡCCDimg<6D><67><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat YCrCb;
|
|
|
|
|
cv::cvtColor(CCDimg, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
|
|
std::vector<cv::Mat> planesCCD;
|
|
|
|
|
cv::split(YCrCb, planesCCD);
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat dst_Y;
|
|
|
|
|
if (!FuseImg(dst_Y, planesCCD[0], IR, wname, level))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ع<EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
dst_Y.copyTo(planesCCD[0]);
|
|
|
|
|
cv::merge(planesCCD, YCrCb);
|
|
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20><>ȡCCDimg<6D><67><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat YCrCb;
|
|
|
|
|
cv::cvtColor(CCDimg, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
|
|
std::vector<cv::Mat> planesCCD;
|
|
|
|
|
cv::split(YCrCb, planesCCD);
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat dst_Y;
|
|
|
|
|
if (false == FuseImg(dst_Y, planesCCD[0], IRimg, wname, level))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20>ع<EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
dst_Y.copyTo(planesCCD[0]);
|
|
|
|
|
cv::merge(planesCCD, YCrCb);
|
|
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ܣ<EFBFBD><DCA3><EFBFBD><EFBFBD><EFBFBD> FastFuseImgCCDplusIR() <20><><EFBFBD><EFBFBD><EFBFBD>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
bool FastFuseImgRGBplusIR(cv::Mat &dst, const cv::Mat CCDimg, const cv::Mat IRimg)
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Mat IR;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (IRimg.type() == CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
// <20><>ȡIRimg<6D><67><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
std::vector<cv::Mat> planesIR;
|
|
|
|
|
cv::split(IRimg, planesIR);
|
|
|
|
|
planesIR[0].copyTo(IR);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
IR = IRimg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>ȡCCDimg<6D><67><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat YCrCb;
|
|
|
|
|
cv::cvtColor(CCDimg, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
|
|
std::vector<cv::Mat> planesCCD;
|
|
|
|
|
cv::split(YCrCb, planesCCD);
|
|
|
|
|
|
|
|
|
|
// <20>ں<EFBFBD><DABA><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat dst_Y = 0.5 * planesCCD[0] + 0.5 * IR;
|
|
|
|
|
|
|
|
|
|
// <20><>ǿ<EFBFBD><C7BF><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>
|
|
|
|
|
cv::Mat enchanceDstY;
|
|
|
|
|
SAHP(enchanceDstY, dst_Y);
|
|
|
|
|
|
|
|
|
|
// <20>ع<EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
planesCCD[0] = enchanceDstY;
|
|
|
|
|
cv::merge(planesCCD, YCrCb);
|
|
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|