#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(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 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; } }