|
|
|
|
#include "stdafx.h"
|
|
|
|
|
#include "DecreaseHazeControl.h"
|
|
|
|
|
#include "omp.h" // <20><><EFBFBD>˱<EFBFBD><CBB1><EFBFBD>
|
|
|
|
|
|
|
|
|
|
#include "histProject.h"
|
|
|
|
|
//#include "DarkChannelDehaze.h"
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>㰵ͨ<E3B0B5><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ:A_MAX
|
|
|
|
|
double GetDarkChannelMaxVal(const cv::Mat &img)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
|
|
|
|
|
if (img.empty() == true || img.type() != 16 || img.cols <= 0 || img.rows <= 0)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int patch = 8;
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD>ߴ<EFBFBD>
|
|
|
|
|
int imgWidth = img.cols;
|
|
|
|
|
int imgHeight = img.rows;
|
|
|
|
|
|
|
|
|
|
// <20>߽<EFBFBD><DFBD><EFBFBD>չͼ<D5B9><CDBC>
|
|
|
|
|
cv::Mat Mid(imgHeight + 2 * patch, imgWidth + 2 * patch, CV_8UC3);
|
|
|
|
|
cv::copyMakeBorder(img, Mid, patch, patch, patch, patch, IPL_BORDER_REFLECT);
|
|
|
|
|
|
|
|
|
|
// <20><>ͨ<EFBFBD><CDA8>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Mat DarkChannel(imgHeight, imgWidth, CV_8UC1);
|
|
|
|
|
for (int i = 0; i < imgHeight; ++i)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < imgWidth; ++j)
|
|
|
|
|
{
|
|
|
|
|
// <20>ֲ<EFBFBD><D6B2><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
cv::Mat patchRegion = Mid(cv::Rect(j, i, 2 * patch, 2 * patch));
|
|
|
|
|
|
|
|
|
|
// ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
std::vector<cv::Mat> planes;
|
|
|
|
|
cv::split(patchRegion, planes);
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ
|
|
|
|
|
double minB = 0, minG = 0, minR = 0;
|
|
|
|
|
cv::minMaxLoc(planes[0], &minB);
|
|
|
|
|
cv::minMaxLoc(planes[1], &minG);
|
|
|
|
|
cv::minMaxLoc(planes[2], &minR);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
double minVal = min(min(minB, minG), minR);
|
|
|
|
|
DarkChannel.at<unsigned char>(i,j) = static_cast<unsigned char>(minVal);
|
|
|
|
|
|
|
|
|
|
// <20>ڴ<EFBFBD><DAB4>ͷ<EFBFBD>
|
|
|
|
|
planes.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>㰵ͨ<E3B0B5><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
|
|
|
|
|
double minDarkChannel = 0.0;
|
|
|
|
|
double maxDarkChannel = 0.0;
|
|
|
|
|
cv::minMaxLoc(DarkChannel, &minDarkChannel, &maxDarkChannel);
|
|
|
|
|
|
|
|
|
|
// <20>ͷŰ<CDB7>ͨ<EFBFBD><CDA8>ͼ<EFBFBD><CDBC>
|
|
|
|
|
DarkChannel.release();
|
|
|
|
|
|
|
|
|
|
return maxDarkChannel;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ<D0A1><D6B5>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ<D0A1><D6B5><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Ҷ<EFBFBD>ͼ
|
|
|
|
|
bool GetMinChannel(const cv::Mat &img, cv::Mat& dark)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (img.empty() == true || img.type() != CV_8UC3)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<cv::Mat> planes;
|
|
|
|
|
cv::split(img, planes);
|
|
|
|
|
|
|
|
|
|
cv::min(planes[0], planes[1], dark);
|
|
|
|
|
cv::min(planes[2], dark, dark);
|
|
|
|
|
|
|
|
|
|
planes.clear();
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>V
|
|
|
|
|
bool GetImgV(const cv::Mat &MinChannel,const cv::Mat &Diff, const cv::Mat &Smooth, cv::Mat & DstV, double degree = 0.78)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
|
|
|
|
|
// 1<><31>ֵ<EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (MinChannel.empty() == true || Diff.empty() == true || Smooth.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 2ͼ<32><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (MinChannel.type() != CV_8UC1 || Diff.type() != CV_8UC1 || Smooth.type() != CV_8UC1)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 3ͼ<33><CDBC><EFBFBD>ߴ<EFBFBD><DFB4>ж<EFBFBD>
|
|
|
|
|
if (MinChannel.cols <= 0 || MinChannel.cols != Diff.cols || Diff.cols != Smooth.cols ||
|
|
|
|
|
MinChannel.rows <= 0 || MinChannel.rows != Diff.rows || Diff.rows != Smooth.rows)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (degree < 0)
|
|
|
|
|
{
|
|
|
|
|
degree = 0;
|
|
|
|
|
}
|
|
|
|
|
else if (degree > 1)
|
|
|
|
|
{
|
|
|
|
|
degree = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int ImgWidth = MinChannel.cols;
|
|
|
|
|
int ImgHeight = MinChannel.rows;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DstV
|
|
|
|
|
DstV.create(cv::Size(ImgWidth, ImgHeight), CV_8UC1);
|
|
|
|
|
|
|
|
|
|
// DstV <20><><EFBFBD><EFBFBD>
|
|
|
|
|
if (DstV.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٶ<EFBFBD>
|
|
|
|
|
if (DstV.isContinuous())
|
|
|
|
|
{
|
|
|
|
|
ImgWidth *= ImgHeight;
|
|
|
|
|
ImgHeight = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>DstVֵ
|
|
|
|
|
for(int i = 0; i < ImgHeight; ++i)
|
|
|
|
|
{
|
|
|
|
|
const uchar* pMinChannel = MinChannel.ptr<uchar>(i);
|
|
|
|
|
const uchar* pDiff = Diff.ptr<uchar>(i);
|
|
|
|
|
const uchar* pSmooth = Smooth.ptr<uchar>(i);
|
|
|
|
|
uchar* pDstV = DstV.ptr<uchar>(i);
|
|
|
|
|
|
|
|
|
|
for(int j = 0; j < ImgWidth; ++j)
|
|
|
|
|
{
|
|
|
|
|
double val = degree * max(uchar(min(uchar((*pMinChannel++) - (*pDiff++)), (*pSmooth++))), uchar(0));
|
|
|
|
|
(*pDstV++) = static_cast<uchar>(val);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
bool GetHazeFreeImg(const cv::Mat& img, const cv::Mat &ImgV, double A_MAX, cv::Mat &HazeFree)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7><EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (img.empty() == true || img.type() != CV_8UC3 || img.cols <= 0 || img.rows <= 0
|
|
|
|
|
|| ImgV.empty() == true || ImgV.type() != CV_8UC1 || ImgV.cols <= 0 || ImgV.rows <= 0
|
|
|
|
|
|| A_MAX < 0 || A_MAX > 255 || img.cols != ImgV.cols || img.rows != ImgV.rows)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD>ߴ<EFBFBD>
|
|
|
|
|
int imgWidth = img.cols;
|
|
|
|
|
int imgHeight = img.rows;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
HazeFree.create(imgHeight, imgWidth, CV_8UC3);
|
|
|
|
|
if (HazeFree.empty() == true)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma omp parallel for
|
|
|
|
|
for (int j = 0; j < imgWidth; ++j)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < imgHeight; i++)
|
|
|
|
|
{
|
|
|
|
|
double V = ImgV.at<unsigned char>(i, j);
|
|
|
|
|
cv::Vec3b vec = img.at<cv::Vec3b>(i, j);
|
|
|
|
|
|
|
|
|
|
for (int k = 0; k < 3; k++)
|
|
|
|
|
{
|
|
|
|
|
double VAB = 0;
|
|
|
|
|
if (V != A_MAX)
|
|
|
|
|
{
|
|
|
|
|
VAB = fabs(vec[k] - V)/(fabs(1 - V/A_MAX));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (VAB > 255)
|
|
|
|
|
{
|
|
|
|
|
vec[k] = 255;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
vec[k] = static_cast<unsigned char>(VAB);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HazeFree.at<cv::Vec3b>(i, j) = vec;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD>ͼ<EFBFBD><CDBC>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD>룺 1. img <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
// 2. A_MAX <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ч<EFBFBD><D0A7>, A_MAX < 0 ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>(<28>ر<EFBFBD><D8B1><EFBFBD>ʱ)<29><> <20><>Ч<EFBFBD><D0A7>Χ<EFBFBD><CEA7>0,255<35><35><EFBFBD><EFBFBD><EFBFBD>쳣ֵ<ECB3A3><D6B5><EFBFBD><EFBFBD>Ӧ
|
|
|
|
|
// 3. degree <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ч<EFBFBD><D0A7>, <20><>Ч<EFBFBD><D0A7>Χ<EFBFBD><CEA7>0,1<><31><EFBFBD><EFBFBD><EFBFBD>쳣ֵ<ECB3A3><D6B5><EFBFBD><EFBFBD>Ӧ
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. HazeFree <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
// 2. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
|
|
|
|
|
bool DeHazeImg(const cv::Mat &img, cv::Mat &HazeFree, double A_MAX, double degree)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><>ͨ<EFBFBD><CDA8> <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>ϸ<EFBFBD><CFB8><EFBFBD><EFBFBD>ǿ <20><><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (img.type() == CV_8UC1)
|
|
|
|
|
{
|
|
|
|
|
if (A_MAX != 0)
|
|
|
|
|
{
|
|
|
|
|
// <20><>˹<EFBFBD><CBB9>Լ<EFBFBD><D4BC>
|
|
|
|
|
return GNRHP(HazeFree,img, false);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20><>˹Լ<CBB9><D4BC>
|
|
|
|
|
return GRHP(HazeFree, img, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨
|
|
|
|
|
// <20><>ͨ<EFBFBD><CDA8>
|
|
|
|
|
if (A_MAX < 0)
|
|
|
|
|
{
|
|
|
|
|
A_MAX = GetDarkChannelMaxVal(img);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (A_MAX > 255)
|
|
|
|
|
{
|
|
|
|
|
A_MAX = 255;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cv::Mat Dark;
|
|
|
|
|
cv::Mat Smooth;
|
|
|
|
|
cv::Mat Diff;
|
|
|
|
|
cv::Mat V;
|
|
|
|
|
|
|
|
|
|
// <20><>ȡ<EFBFBD><C8A1>ͨ<EFBFBD><CDA8>
|
|
|
|
|
if (GetMinChannel(img, Dark) == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><>˹ģ<CBB9><C4A3>
|
|
|
|
|
cv::GaussianBlur(Dark, Smooth, cv::Size(5, 5), 1.667);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>Diff
|
|
|
|
|
cv::absdiff(Dark, Smooth, Diff);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>V
|
|
|
|
|
if (GetImgV(Dark, Diff, Smooth, V, degree) == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>HazeFree
|
|
|
|
|
if (GetHazeFreeImg(img, V, A_MAX, HazeFree) == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ImgStru<72>ṹ<EFBFBD>µ<EFBFBD>ͼ<EFBFBD><CDBC>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD>ͼ<EFBFBD><CDBC>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD>룺 1. src <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ṹ<EFBFBD><E1B9B9>
|
|
|
|
|
// 2. A_MAX <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ч<EFBFBD><D0A7>, A_MAX < 0 ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>(<28>ر<EFBFBD><D8B1><EFBFBD>ʱ)<29><> <20><>Ч<EFBFBD><D0A7>Χ<EFBFBD><CEA7>0,255<35><35><EFBFBD><EFBFBD><EFBFBD>쳣ֵ<ECB3A3><D6B5><EFBFBD><EFBFBD>Ӧ
|
|
|
|
|
// 3. degree <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ч<EFBFBD><D0A7>, <20><>Ч<EFBFBD><D0A7>Χ<EFBFBD><CEA7>0,1<><31><EFBFBD><EFBFBD><EFBFBD>쳣ֵ<ECB3A3><D6B5><EFBFBD><EFBFBD>Ӧ
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. dst <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ṹ<EFBFBD><E1B9B9>
|
|
|
|
|
// 2. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
|
|
|
|
|
bool ImgStruDeHazeControl(ImgStru* src, ImgStru* dst, int A_MAX, double degree)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// src dst <20><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
|
|
|
|
|
if (src == NULL || dst == NULL ||
|
|
|
|
|
src->ImgWidth <=0 ||
|
|
|
|
|
src->ImgHeight <= 0 ||
|
|
|
|
|
src->buff == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>Ը<EFBFBD><D4B8><EFBFBD>
|
|
|
|
|
dst->ImgWidth = src->ImgWidth;
|
|
|
|
|
dst->ImgHeight = src->ImgHeight;
|
|
|
|
|
dst->bitcount = src->bitcount;
|
|
|
|
|
dst->BoundingBox = src->BoundingBox;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>롢<EFBFBD><EBA1A2><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Mat src_Img; //
|
|
|
|
|
|
|
|
|
|
if (src->bitcount == 8)
|
|
|
|
|
{
|
|
|
|
|
src_Img = cv::Mat(src->ImgHeight, src->ImgWidth, CV_8UC1);
|
|
|
|
|
}
|
|
|
|
|
else if (src->bitcount == 24)
|
|
|
|
|
{
|
|
|
|
|
src_Img = cv::Mat(src->ImgHeight, src->ImgWidth, CV_8UC3);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ռ<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|
|
|
|
int lineByte = (src->ImgWidth * src->bitcount / 8);
|
|
|
|
|
|
|
|
|
|
// λͼ<CEBB><CDBC><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С<EFBFBD><D0A1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD>С
|
|
|
|
|
unsigned int imgBufSize = static_cast<unsigned int>(src->ImgHeight * lineByte);
|
|
|
|
|
|
|
|
|
|
if (!src_Img.empty())
|
|
|
|
|
{
|
|
|
|
|
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>
|
|
|
|
|
memcpy(src_Img.data, src->buff, imgBufSize);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
|
|
|
|
|
cv::Mat dst_Img;
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>DeHazeImg<6D>㷨<EFBFBD><E3B7A8>ʵ<EFBFBD><CAB5>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
if (DeHazeImg(src_Img, dst_Img, A_MAX, degree) == true)
|
|
|
|
|
{
|
|
|
|
|
if (src == dst)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dst->buff, dst_Img.data, imgBufSize);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SAFE_DELETE_ARRAY(dst->buff);
|
|
|
|
|
dst->buff = new unsigned char[imgBufSize];
|
|
|
|
|
memcpy(dst->buff, dst_Img.data, imgBufSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD>ܣ<EFBFBD>ͼ<EFBFBD><CDBC>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//<2F><><EFBFBD>룺 1. qbData ͨ<><CDA8><EFBFBD>鱨<EFBFBD><E9B1A8><EFBFBD>ݽṹ<DDBD><E1B9B9>
|
|
|
|
|
// 2. A_MAX <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ч<EFBFBD><D0A7>, A_MAX < 0 ʱ<><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>(<28>ر<EFBFBD><D8B1><EFBFBD>ʱ)<29><> <20><>Ч<EFBFBD><D0A7>Χ<EFBFBD><CEA7>0,255<35><35>
|
|
|
|
|
// 3. degree <20><><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>Ч<EFBFBD><D0A7>, <20><>Ч<EFBFBD><D0A7>Χ<EFBFBD><CEA7>0,1<><31>
|
|
|
|
|
// 3. bSrcFirst Ĭ<><C4AC>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>srcImg, srcImg-->dstImg
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>dstImg<6D><67>dstImg<6D><67><EFBFBD><EFBFBD>>dstImg
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1. qbData <20><>ͼ<EFBFBD><CDBC>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>鱨<EFBFBD><E9B1A8><EFBFBD>ݽṹ<DDBD><E1B9B9>
|
|
|
|
|
// 2. <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD>true<75><65>ʧ<EFBFBD>ܷ<EFBFBD><DCB7><EFBFBD>false
|
|
|
|
|
//˵<><CBB5>: <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD>Ա<EFBFBD>ʶλ<CAB6><CEBB><EFBFBD><EFBFBD>Чʱֱ<CAB1>ӷ<EFBFBD><D3B7>أ<EFBFBD><D8A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>κδ<CEBA><CEB4><EFBFBD>;
|
|
|
|
|
bool QBStruDeHazeControl(QBStru *qbData, int A_MAX, double degree, bool bSrcFirst)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
// <20><>ֵ<EFBFBD>ж<EFBFBD>
|
|
|
|
|
if (qbData == NULL)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>false
|
|
|
|
|
if (qbData->image.bValid == false)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ȴ<EFBFBD><C8B4><EFBFBD>srcImg
|
|
|
|
|
if (bSrcFirst == true)
|
|
|
|
|
{
|
|
|
|
|
if (qbData->image.srcImg.buff != NULL &&
|
|
|
|
|
qbData->image.srcImg.ImgWidth > 0 && // srcImg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
qbData->image.srcImg.ImgHeight > 0 ) // srcImg <20>߶<EFBFBD><DFB6><EFBFBD>֤
|
|
|
|
|
{
|
|
|
|
|
return ImgStruDeHazeControl(&qbData->image.srcImg, &qbData->image.dstImg, A_MAX, degree);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (qbData->image.dstImg.buff != NULL &&
|
|
|
|
|
qbData->image.dstImg.ImgWidth > 0 && // dstImg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
qbData->image.dstImg.ImgHeight > 0 ) // dstImg <20>߶<EFBFBD><DFB6><EFBFBD>֤
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
// <20><><EFBFBD><EFBFBD>dstImg<6D><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dstImg
|
|
|
|
|
return ImgStruDeHazeControl(&qbData->image.dstImg, &qbData->image.dstImg, A_MAX, degree);
|
|
|
|
|
}
|
|
|
|
|
else // srcImg dstImg<6D><67><EFBFBD><EFBFBD>Ч
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// <20>ȿ<EFBFBD>dstImg<6D>Ƿ<EFBFBD><C7B7><EFBFBD>Ч
|
|
|
|
|
if (qbData->image.dstImg.buff != NULL &&
|
|
|
|
|
qbData->image.dstImg.ImgWidth > 0 && // dstImg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
qbData->image.dstImg.ImgHeight > 0 ) // dstImg <20>߶<EFBFBD><DFB6><EFBFBD>֤
|
|
|
|
|
{
|
|
|
|
|
return ImgStruDeHazeControl(&qbData->image.dstImg, &qbData->image.dstImg, A_MAX, degree);
|
|
|
|
|
}else
|
|
|
|
|
if (qbData->image.srcImg.buff != NULL &&
|
|
|
|
|
qbData->image.srcImg.ImgWidth > 0 && // srcImg <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
|
|
|
|
|
qbData->image.srcImg.ImgHeight > 0 ) // srcImg <20>߶<EFBFBD><DFB6><EFBFBD>֤
|
|
|
|
|
{
|
|
|
|
|
return ImgStruDeHazeControl(&qbData->image.srcImg, &qbData->image.dstImg, A_MAX, degree);
|
|
|
|
|
}
|
|
|
|
|
else // <20>鱨<EFBFBD>ṹ<EFBFBD><E1B9B9>srcImg <20><> dstImg <20><><EFBFBD><EFBFBD>Ч
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch(cv::Exception &e)
|
|
|
|
|
{
|
|
|
|
|
e.msg;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
catch(...)
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|