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.

366 lines
6.5 KiB
C++

2 years ago
#include "stdafx.h"
#include "DefinitionControl.h"
// <20><><EFBFBD><EFBFBD>:<3A>Ե<EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD>Ҷ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񻯺ͶԱȶ<D4B1><C8B6><EFBFBD><EFBFBD><EFBFBD>
bool StretchBWImg(cv::Mat& src, cv::Mat& dst, int degree)
{
try
{
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
if(src.empty() == true || src.type() != 0 || degree <= 10)
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD><C9B1>˲<EFBFBD><CBB2><EFBFBD>
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;
// <20>Ժ<EFBFBD>Ԫ<EFBFBD>ؽ<EFBFBD><D8BD>и<EFBFBD>ֵ
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;
// ת<><D7AA>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0 1<><31>
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;
}
}
// <20><><EFBFBD><EFBFBD>:<3A><>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>лҶȻ<D2B6><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǿ
bool EnhanceImg(cv::Mat& src, cv::Mat& dst, int degree)
{
try
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>Ϊ<EFBFBD>գ<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>false
if(src.empty() == true || degree <= 10)
{
return false;
}
if (src.type() != CV_8UC1 && src.type() != CV_8UC3)
{
return false;
}
// <20><>ͨ<EFBFBD><CDA8>
if (src.type() == CV_8UC1)
{
if (StretchBWImg(src, dst, degree) == false)
{
return false;
}
}
else
{
// YCrCb ģ<><C4A3>
cv::Mat YCrCb;
cv::cvtColor(src, YCrCb, cv::COLOR_BGR2YCrCb);
// ͼ<><CDBC><EFBFBD><EFBFBD>֤
if (YCrCb.empty() == true)
{
return false;
}
// ͨ<><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<cv::Mat> planes;
cv::split(YCrCb, planes);
// Y<><59><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cv::Mat dstY;
if (EnhanceImg(planes[0], dstY, degree) == true)
{
// ͨ<><CDA8><EFBFBD>ϲ<EFBFBD>
planes[0] = dstY;
cv::merge(planes, YCrCb);
// <20><><EFBFBD><EFBFBD>ת<EFBFBD><D7AA>
cv::cvtColor(YCrCb, dst, cv::COLOR_YCrCb2BGR);
}
else
{
return false;
}
}
return true;
}
catch(cv::Exception &e)
{
e.msg;
return false;
}
catch(...)
{
return false;
}
}
//<2F><><EFBFBD>ܣ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD>
bool QBStruDefinitionControl(QBStru *qbData, int 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>֤
(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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
qbData->image.dstImg.ImgHeight > 0 && // dstImg <20>߶<EFBFBD><DFB6><EFBFBD>֤
(qbData->image.dstImg.bitcount == 24 || qbData->image.dstImg.bitcount == 8))
{
// <20><><EFBFBD><EFBFBD>dstImg<6D><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dstImg
return ImgStruDefinitionControl(&qbData->image.dstImg, &qbData->image.dstImg, 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>֤
(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 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֤
qbData->image.srcImg.ImgHeight > 0 && // srcImg <20>߶<EFBFBD><DFB6><EFBFBD>֤
(qbData->image.srcImg.bitcount == 24 || qbData->image.srcImg.bitcount == 8))
{
return ImgStruDefinitionControl(&qbData->image.srcImg, &qbData->image.dstImg, 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;
}
}
// ImgStru<72><EFBFBD>µ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD>
bool ImgStruDefinitionControl(ImgStru* src, ImgStru* dst, int degree)
{
try
{
// src dst <20><>Ч<EFBFBD><D0A7><EFBFBD><EFBFBD>֤
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;
}
// <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
{
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);
}
// <20><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
cv::Mat dst_Img;
// <20><><EFBFBD><EFBFBD>cvMatDefinitionControl<6F><EFBFBD><E3B7A8>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD>
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<43><EFBFBD>µ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȿ<EFBFBD><C8BF><EFBFBD>
bool cvMatDefinitionControl(cv::Mat& src, cv::Mat& dst, int degree)
{
try
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>Ϊ<EFBFBD>գ<EFBFBD>ֱ<EFBFBD>ӷ<EFBFBD><D3B7><EFBFBD>false
if(src.empty() == true)
{
return false;
}
// ͼ<><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (src.type() != 0 && src.type() != 16)
{
return false;
}
// <20><><EFBFBD>ȿ<EFBFBD><C8BF>Ƴ̶<C6B3> <20>жϺͲö<CDB2>
if(degree < 0)
{
degree = 0;
}
if(degree > 20)
{
degree = 20;
}
// <20><><EFBFBD><EFBFBD>degree = 10<31><30><EFBFBD><EFBFBD><EFBFBD>ȱ<EFBFBD><C8B1>ֲ<EFBFBD><D6B2><EFBFBD>
if (degree == 10)
{
// <20><><EFBFBD>ݸ<EFBFBD><DDB8><EFBFBD>
dst = src.clone();
return true;
}
// ͼ<><CDBC>ģ<EFBFBD><C4A3>
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;
}
}