You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

285 lines
5.1 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "stdafx.h"
#include "IntensityControl.h"
// 通用情报结构体亮度控制
bool QBStruIntensityControl(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 &&
qbData->image.srcImg.ImgHeight > 0 &&
(qbData->image.srcImg.bitcount == 24 || qbData->image.srcImg.bitcount == 8))
{
return ImgStruIntensityControl(&qbData->image.srcImg, &qbData->image.dstImg, degree);
}
else
if (qbData->image.dstImg.buff != NULL &&
qbData->image.dstImg.ImgWidth > 0 &&
qbData->image.dstImg.ImgHeight > 0 &&
(qbData->image.dstImg.bitcount == 24 || qbData->image.dstImg.bitcount == 8))
{
return ImgStruIntensityControl(&qbData->image.dstImg, &qbData->image.dstImg, degree);
}
else
{
return false;
}
}
else
{
// 先看dstImg是否有效
if (qbData->image.dstImg.buff != NULL &&
qbData->image.dstImg.ImgWidth > 0 &&
qbData->image.dstImg.ImgHeight > 0 &&
(qbData->image.dstImg.bitcount == 24 || qbData->image.dstImg.bitcount == 8))
{
return ImgStruIntensityControl(&qbData->image.dstImg, &qbData->image.dstImg, degree);
}
else
if (qbData->image.srcImg.buff != NULL &&
qbData->image.srcImg.ImgWidth > 0 &&
qbData->image.srcImg.ImgHeight > 0 &&
(qbData->image.srcImg.bitcount == 24 || qbData->image.srcImg.bitcount == 8))
{
return ImgStruIntensityControl(&qbData->image.srcImg, &qbData->image.dstImg, degree);
}
else
{
return false;
}
}
return true;
}
catch(cv::Exception &e)
{
e.msg;
return false;
}
catch(...)
{
return false;
}
}
// ImgStru结构下的图像亮度控制
//功能:图像亮度控制
bool ImgStruIntensityControl(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;
// 调用cvMatIntensityControl算法实现亮度控制
if (cvMatIntensityControl(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;
}
}
// OpenCV结构下的图像亮度控制
bool cvMatIntensityControl(cv::Mat& src, cv::Mat& dst, int degree)
{
try
{
// 如果输入图像为空直接返回false
if(src.empty() == true)
{
return false;
}
// 图像类型
if (src.type() != CV_8UC1 && src.type() != CV_8UC3)
{
return false;
}
// 亮度控制程度 判断和裁断
if(degree < 0)
{
degree = 0;
}
if(degree > 20)
{
degree = 20;
}
// 如果degree = 10亮度保持不变
if (degree == 10)
{
// 数据复制
dst = src.clone();
return true;
}
// 方案一:自创算法
// 伽马系数
double gama = 1.0;
if (degree < 10) // gama 为分母 【1 5】
{
gama = -0.4 * degree + 5;
}
else
{
gama = 1.9 - 0.09 * degree; // gama为 幂次【0.1 1】
}
// 针对单通道
if (src.type() == CV_8UC1)
{
if (degree < 10)
{
if (abs(gama) > 0)
{
// dst = src * 1 / gama
src.convertTo(dst, CV_8UC1, 1.0 / gama);
}
}
else
{
// 转换为浮点数【0 1】
cv::Mat gray32;
src.convertTo(gray32, CV_32FC1, 1.0 / 255);
// gray32 = gray32 ^ gama
cv::pow(gray32, gama, gray32);
// dst = gray32 * 255
gray32.convertTo(dst, CV_8UC1, 255.0);
}
}
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;
cvMatIntensityControl(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;
}
}