code_app/modules/imgproc/HGImgProc.cpp

501 lines
13 KiB
C++
Raw Normal View History

2022-05-03 10:25:52 +00:00
#include "HGImgProc.h"
#include "./ImageProcess/ImageApplyAdjustColors.h"
#include "./ImageProcess/ImageApplyAutoCrop.h"
#include "./ImageProcess/ImageApplyDiscardBlank.h"
2022-06-13 11:56:43 +00:00
#include "CvxText.hpp"
2022-05-03 10:25:52 +00:00
#include "../base/HGInc.h"
2022-06-13 11:56:43 +00:00
#include "../base/HGUtility.h"
2022-05-03 10:25:52 +00:00
HGResult HGAPI HGImgProc_ResizeImage(HGImage image, HGImage destImage, HGUInt interp)
{
if (NULL == image || NULL == destImage || image == destImage)
{
return HGBASE_ERR_INVALIDARG;
}
if (HGIMGPROC_INTERPOTYPE_NN != interp && HGIMGPROC_INTERPOTYPE_LINEAR != interp)
{
return HGBASE_ERR_INVALIDARG;
}
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
HGImageInfo destImgInfo;
HGBase_GetImageInfo(destImage, &destImgInfo);
uint32_t type = imgInfo.type;
uint32_t destType = destImgInfo.type;
if (type != destType)
{
return HGBASE_ERR_INVALIDDATA;
}
HGByte* data = NULL;
HGBase_GetImageData(image, &data);
HGByte* destData = NULL;
HGBase_GetImageData(destImage, &destData);
HGImageRoi roi;
HGBase_GetImageROI(image, &roi);
HGImageRoi destRoi;
HGBase_GetImageROI(destImage, &destRoi);
HGUInt roiWidth = roi.right - roi.left;
HGUInt roiHeight = roi.bottom - roi.top;
HGUInt destRoiWidth = destRoi.right - destRoi.left;
HGUInt destRoiHeight = destRoi.bottom - destRoi.top;
if (roiWidth == destRoiWidth && roiHeight == destRoiHeight)
{
return HGBase_CopyImage(image, destImage);
}
2022-05-26 11:01:38 +00:00
if (HGBASE_IMGTYPE_BINARY == type)
{
HGImage imageTmp1 = NULL;
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp1);
if (HGBASE_ERR_OK == ret)
{
HGImage imageTmp2 = NULL;
ret = HGBase_CreateImage(destRoiWidth, destRoiHeight, HGBASE_IMGTYPE_GRAY, imgInfo.origin, &imageTmp2);
if (HGBASE_ERR_OK == ret)
{
ret = HGImgProc_ResizeImage(imageTmp1, imageTmp2, interp);
if (HGBASE_ERR_OK == ret)
{
ret = HGBase_CopyImage(imageTmp2, destImage);
}
HGBase_DestroyImage(imageTmp2);
}
HGBase_DestroyImage(imageTmp1);
}
return ret;
}
2022-05-03 10:25:52 +00:00
uint32_t channels = 1;
if (HGBASE_IMGTYPE_BGR == type || HGBASE_IMGTYPE_RGB == type)
channels = 3;
else if (HGBASE_IMGTYPE_BGRA == type || HGBASE_IMGTYPE_RGBA == type)
channels = 4;
uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels;
uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels;
IplImage* pImg = cvCreateImageHeader(cvSize(roiWidth, roiHeight), IPL_DEPTH_8U, channels);
IplImage* pImgDest = cvCreateImageHeader(cvSize(destRoiWidth, destRoiHeight), IPL_DEPTH_8U, channels);
cvSetData(pImg, p, imgInfo.widthStep);
cvSetData(pImgDest, pDest, destImgInfo.widthStep);
int interpolation = (HGIMGPROC_INTERPOTYPE_NN == interp) ? CV_INTER_NN : CV_INTER_LINEAR;
cvResize(pImg, pImgDest, interpolation);
cvReleaseImageHeader(&pImgDest);
cvReleaseImageHeader(&pImg);
if (imgInfo.origin != destImgInfo.origin)
{
HGBase_ImageFlip(destImage, destImage);
}
return HGBASE_ERR_OK;
}
HGResult HGAPI HGImgProc_ImageAdjustColors(HGImage image, HGImage destImage,
HGInt brightness, HGInt contrast, HGFloat gamma)
{
if (NULL == image)
{
return HGBASE_ERR_INVALIDARG;
}
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
HGUInt type = imgInfo.type;
2022-05-26 11:01:38 +00:00
2022-05-03 10:25:52 +00:00
HGByte* data = NULL;
HGBase_GetImageData(image, &data);
HGImageRoi roi;
HGBase_GetImageROI(image, &roi);
HGUInt roiWidth = roi.right - roi.left;
HGUInt roiHeight = roi.bottom - roi.top;
uint32_t channels = 1;
if (HGBASE_IMGTYPE_BGR == type || HGBASE_IMGTYPE_RGB == type)
channels = 3;
else if (HGBASE_IMGTYPE_BGRA == type || HGBASE_IMGTYPE_RGBA == type)
channels = 4;
if (NULL == destImage || image == destImage)
{
2022-05-26 11:01:38 +00:00
if (HGBASE_IMGTYPE_BINARY == type)
{
HGImage imageTmp = NULL;
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp);
if (HGBASE_ERR_OK == ret)
{
ret = HGImgProc_ImageAdjustColors(imageTmp, imageTmp, brightness, contrast, gamma);
if (HGBASE_ERR_OK == ret)
{
ret = HGBase_CopyImage(imageTmp, image);
}
HGBase_DestroyImage(imageTmp);
}
return ret;
}
2022-05-27 01:40:25 +00:00
uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels;
cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep);
CImageApplyAdjustColors imgApply(brightness, contrast, gamma);
imgApply.apply(img, 0);
2022-05-03 10:25:52 +00:00
}
else
{
HGImageInfo destImgInfo;
HGBase_GetImageInfo(destImage, &destImgInfo);
HGUInt destType = destImgInfo.type;
if (type != destType)
{
return HGBASE_ERR_INVALIDDATA;
}
HGByte* destData = NULL;
HGBase_GetImageData(destImage, &destData);
HGImageRoi destRoi;
HGBase_GetImageROI(destImage, &destRoi);
HGUInt destRoiWidth = destRoi.right - destRoi.left;
HGUInt destRoiHeight = destRoi.bottom - destRoi.top;
if (roiWidth != destRoiWidth || roiHeight != destRoiHeight)
{
return HGBASE_ERR_INVALIDDATA;
}
2022-05-26 11:01:38 +00:00
if (HGBASE_IMGTYPE_BINARY == type)
{
HGImage imageTmp = NULL;
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp);
if (HGBASE_ERR_OK == ret)
{
ret = HGImgProc_ImageAdjustColors(imageTmp, imageTmp, brightness, contrast, gamma);
if (HGBASE_ERR_OK == ret)
{
ret = HGBase_CopyImage(imageTmp, destImage);
}
HGBase_DestroyImage(imageTmp);
}
return ret;
}
HGBase_CopyImage(image, destImage);
2022-05-03 10:25:52 +00:00
uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels;
cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(channels), pDest, destImgInfo.widthStep);
CImageApplyAdjustColors imgApply(brightness, contrast, gamma);
imgApply.apply(destImg, 0);
2022-05-03 10:25:52 +00:00
}
return HGBASE_ERR_OK;
}
HGResult HGAPI HGImgProc_ImageAutoCrop(HGImage image, HGBool autoCrop, HGBool deskew, HGBool fillBlank, const HGImgAutoCropParam* param,
2022-05-03 10:25:52 +00:00
HGUInt destWidth, HGUInt destHeight, HGUInt destType, HGUInt destOrigin, HGImage* destImage)
{
if (NULL == image || NULL == destImage)
{
return HGBASE_ERR_INVALIDARG;
}
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
2022-05-26 11:01:38 +00:00
if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type
|| HGBASE_IMGTYPE_BGRA == imgInfo.type)
2022-05-03 10:25:52 +00:00
{
2022-05-26 11:01:38 +00:00
HGImage imageTmp = NULL;
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, 0, &imageTmp);
if (HGBASE_ERR_OK == ret)
{
if (0 == destType)
destType = imgInfo.type;
if (0 == destOrigin)
destOrigin = imgInfo.origin;
ret = HGImgProc_ImageAutoCrop(imageTmp, autoCrop, deskew, fillBlank, param,
destWidth, destHeight, destType, destOrigin, destImage);
HGBase_DestroyImage(imageTmp);
}
return ret;
2022-05-03 10:25:52 +00:00
}
bool convex = true;
bool fillColor = false;
2022-05-03 10:25:52 +00:00
double threshold = 40.0;
int noise = 8;
int indent = 5;
bool normalCrop = false;
bool dispersion = true;
2022-05-03 10:25:52 +00:00
if (NULL != param)
{
convex = (bool)param->convex;
fillColor = (bool)param->fillColor;
threshold = param->threshold;
noise = param->noise;
indent = param->indent;
normalCrop = (bool)param->normalCrop;
dispersion = (bool)param->dispersion;
2022-05-03 10:25:52 +00:00
}
HGByte* data = NULL;
HGBase_GetImageData(image, &data);
HGImageRoi roi;
HGBase_GetImageROI(image, &roi);
HGUInt roiWidth = roi.right - roi.left;
HGUInt roiHeight = roi.bottom - roi.top;
uint32_t channels = 1;
if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_BGR == imgInfo.type)
2022-05-03 10:25:52 +00:00
channels = 3;
uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels;
cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep);
cv::Mat destImg;
autoCrop_desaskew_fillBlank(img, destImg, autoCrop, deskew, fillBlank, destWidth, destHeight,
convex, fillColor, threshold, noise, indent, normalCrop, dispersion);
2022-05-03 10:25:52 +00:00
if (destImg.empty())
{
return HGIMGPROC_ERR_FAIL;
}
HGImageInfo newImgInfo;
newImgInfo.width = (HGUInt)destImg.cols;
newImgInfo.height = (HGUInt)destImg.rows;
newImgInfo.type = imgInfo.type;
newImgInfo.widthStep = (HGUInt)destImg.step;
newImgInfo.origin = imgInfo.origin;
2022-05-26 11:01:38 +00:00
if (0 == destType)
destType = imgInfo.type;
if (0 == destOrigin)
destOrigin = imgInfo.origin;
return HGBase_CreateImageFromData(destImg.data, &newImgInfo, NULL, destType, destOrigin, destImage);
}
HGResult HGAPI HGImgProc_ImageBlankCheck(HGImage image, const HGImgBlankCheckParam* param, HGBool* blank)
{
if (NULL == image || NULL == blank)
2022-05-03 10:25:52 +00:00
{
return HGBASE_ERR_INVALIDARG;
2022-05-03 10:25:52 +00:00
}
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
2022-05-26 11:01:38 +00:00
if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type
|| HGBASE_IMGTYPE_BGRA == imgInfo.type)
2022-05-03 10:25:52 +00:00
{
2022-05-26 11:01:38 +00:00
HGImage imageTmp = NULL;
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, 0, &imageTmp);
if (HGBASE_ERR_OK == ret)
{
ret = HGImgProc_ImageBlankCheck(imageTmp, param, blank);
HGBase_DestroyImage(imageTmp);
}
return ret;
2022-05-03 10:25:52 +00:00
}
HGDouble threshold = 40.0;
HGInt edge = 150;
HGInt blockSize = 10;
HGDouble devTh = 50.0;
HGDouble meanTh = 200.0;
if (NULL != param)
{
threshold = param->threshold;
edge = param->edge;
blockSize = param->blockSize;
devTh = param->devTh;
meanTh = param->meanTh;
}
HGByte* data = NULL;
HGBase_GetImageData(image, &data);
HGImageRoi roi;
HGBase_GetImageROI(image, &roi);
HGUInt roiWidth = roi.right - roi.left;
HGUInt roiHeight = roi.bottom - roi.top;
uint32_t channels = 1;
if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_RGB == imgInfo.type)
channels = 3;
uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels;
cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep);
bool ret = CImageApplyDiscardBlank::apply(img, threshold, edge, blockSize, devTh, meanTh);
*blank = ret ? HGTRUE : HGFALSE;
return HGBASE_ERR_OK;
2022-06-13 11:56:43 +00:00
}
static HGResult MeasureString(const HGChar* text, HGInt x, HGInt y, const HGImgWatermarkFontParam* fontParam, HGRect* pos)
{
assert(NULL != text && '\0' != *text);
assert(NULL != pos);
std::string fontName = "宋体";
HGUInt fontSize = 10;
HGBool bold = HGFALSE;
HGBool underline = HGFALSE;
HGBool italic = HGFALSE;
HGBool strikeout = HGFALSE;
if (NULL != fontParam)
{
fontName = fontParam->foneName;
fontSize = fontParam->fontSize;
bold = fontParam->bold;
underline = fontParam->underline;
italic = fontParam->italic;
strikeout = fontParam->strikeout;
}
HGChar moduleName[256];
HGBase_GetModuleName(HGImgProc_AddImageWatermark, moduleName, 256);
HGChar modulePath[256];
HGBase_GetFilePath(moduleName, modulePath, 256);
HGChar fontPath[256];
sprintf(fontPath, "%s%s.ttf", modulePath, fontName.c_str());
CvxText cvxText;
bool ret = cvxText.Create(fontPath);
if (ret)
{
ret = cvxText.MeasureString(text, x, y, fontSize, bold, underline, italic, strikeout, pos);
cvxText.Destroy();
}
return ret ? HGBASE_ERR_OK : HGBASE_ERR_FAIL;
}
HGResult HGAPI HGImgProc_AddImageWatermark(HGImage image, const HGChar* text, HGColor color, HGUInt posType,
HGInt locationX, HGInt locationY, const HGImgWatermarkFontParam *fontParam)
{
if (NULL == image || NULL == text || '\0' == *text || posType < HGIMGPROC_WMPOSTYPE_LEFT
|| posType > HGIMGPROC_WMPOSTYPE_LOCATION)
{
return HGBASE_ERR_INVALIDARG;
}
HGImageRoi imgRoi;
HGBase_GetImageROI(image, &imgRoi);
HGInt roiWidth = imgRoi.right - imgRoi.left;
HGInt roiHeight = imgRoi.bottom - imgRoi.top;
if (HGIMGPROC_WMPOSTYPE_LOCATION == posType)
{
std::string fontName = "宋体";
HGUInt fontSize = 10;
HGBool bold = HGFALSE;
HGBool underline = HGFALSE;
HGBool italic = HGFALSE;
HGBool strikeout = HGFALSE;
if (NULL != fontParam)
{
fontName = fontParam->foneName;
fontSize = fontParam->fontSize;
bold = fontParam->bold;
underline = fontParam->underline;
italic = fontParam->italic;
strikeout = fontParam->strikeout;
}
HGChar moduleName[256];
HGBase_GetModuleName(HGImgProc_AddImageWatermark, moduleName, 256);
HGChar modulePath[256];
HGBase_GetFilePath(moduleName, modulePath, 256);
HGChar fontPath[256];
sprintf(fontPath, "%s%s.ttf", modulePath, fontName.c_str());
CvxText cvxText;
bool ret = cvxText.Create(fontPath);
if (ret)
{
ret = cvxText.DrawString(image, text, locationX, locationY, color, fontSize, bold, underline, italic, strikeout);
cvxText.Destroy();
}
return ret ? HGBASE_ERR_OK : HGBASE_ERR_FAIL;
}
HGRect pos;
HGResult ret = MeasureString(text, 0, 0, fontParam, &pos);
if (HGBASE_ERR_OK != ret)
return ret;
HGInt stringWidth = pos.right - pos.left;
HGInt stringHeight = pos.bottom - pos.top;
HGInt x, y;
if (HGIMGPROC_WMPOSTYPE_LEFT == posType)
{
x = 0;
y = (roiHeight - stringHeight) / 2;
}
else if (HGIMGPROC_WMPOSTYPE_TOP == posType)
{
x = (roiWidth - stringWidth) / 2;
y = 0;
}
else if (HGIMGPROC_WMPOSTYPE_RIGHT == posType)
{
x = roiWidth - stringWidth;
y = (roiHeight - stringHeight) / 2;
}
else if (HGIMGPROC_WMPOSTYPE_BOTTOM == posType)
{
x = (roiWidth - stringWidth) / 2;
y = roiHeight - stringHeight;
}
else if (HGIMGPROC_WMPOSTYPE_LEFTTOP == posType)
{
x = 0;
y = 0;
}
else if (HGIMGPROC_WMPOSTYPE_RIGHTTOP == posType)
{
x = roiWidth - stringWidth;
y = 0;
}
else if (HGIMGPROC_WMPOSTYPE_LEFTBOTTOM == posType)
{
x = 0;
y = roiHeight - stringHeight;
}
else if (HGIMGPROC_WMPOSTYPE_RIGHTBOTTOM == posType)
{
x = roiWidth - stringWidth;
y = roiHeight - stringHeight;
}
else
{
x = (roiWidth - stringWidth) / 2;
y = (roiHeight - stringHeight) / 2;
}
return HGImgProc_AddImageWatermark(image, text, color, HGIMGPROC_WMPOSTYPE_LOCATION, x, y, fontParam);
2022-05-03 10:25:52 +00:00
}