|
|
#include "stdafx.h"
|
|
|
#include "ContrastControl.h"
|
|
|
|
|
|
|
|
|
// 图像对比度调整
|
|
|
bool cvMatContrastControl(cv::Mat& src, cv::Mat& dst, int degree)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果输入图像为空,直接返回false
|
|
|
if(src.empty() == true)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 图像类型
|
|
|
if (src.type() != 0 && src.type() != 16)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 对比度控制程度 判断和裁断
|
|
|
if(degree < 0)
|
|
|
{
|
|
|
degree = 0;
|
|
|
}
|
|
|
|
|
|
if(degree > 20)
|
|
|
{
|
|
|
degree = 20;
|
|
|
}
|
|
|
|
|
|
// 如果degree = 10,亮度保持不变
|
|
|
if (degree == 10)
|
|
|
{
|
|
|
// 数据复制
|
|
|
dst = src.clone();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
double c = (degree - 10.0) / 10.0;
|
|
|
double k = tan((45.0F + 44.0F * c) / 180.0 * CV_PI);
|
|
|
|
|
|
// 单通道
|
|
|
if (src.type() == 0)
|
|
|
{
|
|
|
if (degree > 10)
|
|
|
{
|
|
|
// 重新计算对比度调节系数 10 - 20 对应 1 - 2
|
|
|
degree = degree - 10;
|
|
|
c = (degree - 10.0) / 10.0;
|
|
|
k = 1 + tan((45.0F + 44.0F * c) / 180.0 * CV_PI);
|
|
|
}
|
|
|
|
|
|
// dst = (src - 127.5) * k + 127.5
|
|
|
cv::addWeighted(src, k, src, 0, 127.5 - 127.5 * k, dst, CV_8UC1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// YCrCb 模型
|
|
|
cv::Mat YCrCb;
|
|
|
cv::cvtColor(src, YCrCb, cv::COLOR_BGR2YCrCb);
|
|
|
|
|
|
// 图像验证
|
|
|
if (YCrCb.empty() == true)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 通道分离
|
|
|
std::vector<cv::Mat> planes;
|
|
|
cv::split(YCrCb, planes);
|
|
|
|
|
|
// Y分量调整
|
|
|
cv::Mat dstY;
|
|
|
cvMatContrastControl(planes[0], dstY, degree);
|
|
|
|
|
|
// 通道合并
|
|
|
planes[0] = dstY;
|
|
|
cv::merge(planes, YCrCb);
|
|
|
|
|
|
// 类型转换
|
|
|
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return false;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// ImgStru 图像结构体 图像对比度增强
|
|
|
bool ImgStruContrastControl(ImgStru* src, ImgStru* dst, int degree)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// src dst 有效性验证
|
|
|
if (src == NULL || dst ==NULL ||
|
|
|
src->ImgWidth <=0 ||
|
|
|
src->ImgHeight <= 0 ||
|
|
|
src->bitcount <= 0 ||
|
|
|
src->buff == NULL)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if(src->bitcount != 8 && src->bitcount != 24)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 属性复制
|
|
|
dst->ImgWidth = src->ImgWidth;
|
|
|
dst->ImgHeight = src->ImgHeight;
|
|
|
dst->bitcount = src->bitcount;
|
|
|
dst->BoundingBox = src->BoundingBox;
|
|
|
|
|
|
// 构建输入、输出图像
|
|
|
cv::Mat src_Img;
|
|
|
|
|
|
if (src->bitcount == 8)
|
|
|
{
|
|
|
src_Img = cv::Mat(src->ImgHeight, src->ImgWidth, CV_8UC1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
src_Img = cv::Mat(src->ImgHeight, src->ImgWidth, CV_8UC3);
|
|
|
}
|
|
|
|
|
|
int lineByte = src->ImgWidth * src->bitcount / 8;
|
|
|
unsigned int imgBufSize = static_cast<unsigned int>(src->ImgHeight * lineByte);
|
|
|
|
|
|
if (src_Img.empty() == true)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
memcpy(src_Img.data, src->buff, imgBufSize);
|
|
|
}
|
|
|
|
|
|
// 输出图像
|
|
|
cv::Mat dst_Img;
|
|
|
|
|
|
// 调用cvMatContrastControl算法
|
|
|
if (cvMatContrastControl(src_Img, dst_Img, 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;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 情报结构 图像对比度增强
|
|
|
bool QBStruContrastControl(QBStru *qbData, int degree, bool bSrcFirst)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 空值判断
|
|
|
if (qbData == NULL)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 图像数据无效,直接返回false
|
|
|
if (qbData->image.bValid == false)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 优先处理srcImg
|
|
|
if (bSrcFirst == true)
|
|
|
{
|
|
|
if (qbData->image.srcImg.buff != NULL &&
|
|
|
qbData->image.srcImg.ImgWidth > 0 && // srcImg 宽度验证
|
|
|
qbData->image.srcImg.ImgHeight > 0 && // srcImg 高度验证
|
|
|
(qbData->image.srcImg.bitcount == 24 || qbData->image.srcImg.bitcount == 8))
|
|
|
{
|
|
|
return ImgStruContrastControl(&qbData->image.srcImg, &qbData->image.dstImg, degree);
|
|
|
}
|
|
|
else
|
|
|
if (qbData->image.dstImg.buff != NULL &&
|
|
|
qbData->image.dstImg.ImgWidth > 0 && // dstImg 宽度验证
|
|
|
qbData->image.dstImg.ImgHeight > 0 && // dstImg 高度验证
|
|
|
(qbData->image.dstImg.bitcount == 24 || qbData->image.dstImg.bitcount == 8))
|
|
|
{
|
|
|
// 输入dstImg,输出dstImg
|
|
|
return ImgStruContrastControl(&qbData->image.dstImg, &qbData->image.dstImg, degree);
|
|
|
}
|
|
|
else // srcImg dstImg均无效
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 先看dstImg是否有效
|
|
|
if (qbData->image.dstImg.buff != NULL &&
|
|
|
qbData->image.dstImg.ImgWidth > 0 && // dstImg 宽度验证
|
|
|
qbData->image.dstImg.ImgHeight > 0 && // dstImg 高度验证
|
|
|
(qbData->image.dstImg.bitcount == 24 || qbData->image.dstImg.bitcount == 8))
|
|
|
{
|
|
|
return ImgStruContrastControl(&qbData->image.dstImg, &qbData->image.dstImg, degree);
|
|
|
}
|
|
|
else
|
|
|
if (qbData->image.srcImg.buff != NULL &&
|
|
|
qbData->image.srcImg.ImgWidth > 0 && // srcImg 宽度验证
|
|
|
qbData->image.srcImg.ImgHeight > 0 && // srcImg 高度验证
|
|
|
(qbData->image.srcImg.bitcount == 24 || qbData->image.srcImg.bitcount == 8))
|
|
|
{
|
|
|
return ImgStruContrastControl(&qbData->image.srcImg, &qbData->image.dstImg, degree);
|
|
|
}
|
|
|
else // 情报结构体srcImg 和 dstImg 均无效
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return false;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|