#include "stdafx.h"
#include "DefinitionControl.h"

// 功能:对单通道灰度图像进行锐化和对比度拉伸
bool StretchBWImg(cv::Mat& src, cv::Mat& dst, int degree)
{
	try
	{
		// 数据判断
		if(src.empty() == true || src.type() != 0 || degree <= 10)
		{
			return false;
		}

		// 构建可变滤波器
		cv::Mat kernel(3,3,CV_32F, cv::Scalar(0));

		float center = 5.0F * degree - 50.0F; // [5 50]
		float others = (1.0F - center)/8.0F;

		// 对核元素进行赋值
		kernel.at<float>(0, 0) = others;
		kernel.at<float>(0, 1) = others;
		kernel.at<float>(0, 2) = others;
		kernel.at<float>(1, 0) = others;
		kernel.at<float>(1, 1) = center;
		kernel.at<float>(1, 2) = others;
		kernel.at<float>(2, 0) = others;
		kernel.at<float>(2, 1) = others;
		kernel.at<float>(2, 2) = others;

		// 转换为浮点数【0 1】
		cv::Mat src_float;
		src.convertTo(src_float, CV_32FC1);

		cv::Mat mid;
		cv::GaussianBlur(src_float, mid, cv::Size(5, 5), 1.667);
		cv::filter2D(mid, dst, mid.depth(), kernel);
		dst.convertTo(dst, CV_8UC1);

		return true;
	}
	catch(cv::Exception &e)
	{
		e.msg;
		return false;
	}
	catch(...)
	{
		return false;
	}
}



// 功能:对图像进行灰度或亮度增强
bool EnhanceImg(cv::Mat& src, cv::Mat& dst, int degree)
{
	try
	{
		// 如果输入图像为空,直接返回false
		if(src.empty() == true || degree <= 10)
		{
			return false;
		}

		if (src.type() != CV_8UC1 && src.type() != CV_8UC3)
		{
			return false;
		}

		// 单通道
		if (src.type() == CV_8UC1)
		{
			if (StretchBWImg(src, dst, degree) == false)
			{
				return false;
			}
		}
		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;
			if (EnhanceImg(planes[0], dstY, degree) == true)
			{
				// 通道合并
				planes[0] = dstY;
				cv::merge(planes, YCrCb);

				// 类型转换
				cv::cvtColor(YCrCb, dst,  cv::COLOR_YCrCb2BGR);
			}
			else
			{
				return false;
			}
		}

		return true;
	}
	catch(cv::Exception &e)
	{
		e.msg;
		return false;
	}
	catch(...)
	{
		return false;
	}
}

//功能:图像清晰度控制
bool QBStruDefinitionControl(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 ImgStruDefinitionControl(&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 ImgStruDefinitionControl(&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 ImgStruDefinitionControl(&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 ImgStruDefinitionControl(&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;
	}
}


// ImgStru结构下的图像清晰度控制
bool ImgStruDefinitionControl(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;

		// 调用cvMatDefinitionControl算法,实现清晰度控制
		if (cvMatDefinitionControl(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 cvMatDefinitionControl(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;
		}


		// 图像模糊
		if (degree < 10)
		{
			int r = 12 - degree;

			if (r % 2 == 0)
			{
				r = r + 1; 
			}

			double sigma = r / 3;

			cv::GaussianBlur(src, dst, cv::Size(r, r), sigma);
		}
		else // degree > 10
		{
			return EnhanceImg(src, dst, degree);
		}

		return true;
	}
	catch(cv::Exception &e)
	{
		e.msg;
		return false;
	}
	catch(...)
	{
		return false; 
	}
}