#include "HGImgProc.h" #include "./ImageProcess/ImageApplyAdjustColors.h" #include "./ImageProcess/ImageApplyAutoCrop.h" #include "./ImageProcess/ImageApplyDiscardBlank.h" #include "./ImageProcess/ImageApplyBWBinaray.h" #include "./ImageProcess/ImageApplyChannel.h" #include "./ImageProcess/ImageApplyColorRecognition.h" #include "./ImageProcess/ImageApplyDispersion.h" #include "./ImageProcess/ImageApplyFadeBackGroundColor.h" #include "./ImageProcess/ImageApplyFilter.h" #include "./ImageProcess/ImageApplyOutHole.h" #include "./ImageProcess/ImageApplyHSVCorrect.h" #include "CvxText.hpp" #include "../base/HGInc.h" #include "../base/HGUtility.h" 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); } 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; } 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; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * channels; uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * 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; 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) { 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; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * 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); assert(img.data == p); } 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; } 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); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * 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); assert(destImg.data == pDest); } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageAutoCrop(HGImage image, HGBool autoCrop, HGBool deskew, HGBool fillBlank, const HGImgAutoCropParam* param, 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); if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 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; } bool convex = true; bool fillColor = false; double threshold = 40.0; int noise = 8; int indent = 5; bool normalCrop = false; bool dispersion = true; 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; } 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) channels = 3; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * 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); 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; 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) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageBlankCheck(imageTmp, param, blank); HGBase_DestroyImage(imageTmp); } return ret; } 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) channels = 3; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * 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; } HGResult HGAPI HGImgProc_ImageDrawLine(HGImage image, HGInt x1, HGInt y1, HGInt x2, HGInt y2, HGColor color, HGUInt width, HGUInt type) { if (NULL == image || 0 == width || type < HGIMGPROC_LINETYPE_SOLID || type > HGIMGPROC_LINETYPE_DASH) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_GRAY == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageDrawLine(imageTmp, x1, y1, x2, y2, color, width, type); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } 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 = 3; if (HGBASE_IMGTYPE_BGRA == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type) channels = 4; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * channels; IplImage* pImg = cvCreateImageHeader(cvSize(roiWidth, roiHeight), IPL_DEPTH_8U, channels); cvSetData(pImg, p, imgInfo.widthStep); if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) { y1 = roiHeight - y1 - 1; y2 = roiHeight - y2 - 1; } HGUInt r = HG_GETCOLOR_R(color); HGUInt g = HG_GETCOLOR_G(color); HGUInt b = HG_GETCOLOR_B(color); if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type) { r = HG_GETCOLOR_B(color); g = HG_GETCOLOR_G(color); b = HG_GETCOLOR_R(color); } cvLine(pImg, cvPoint(x1, y1), cvPoint(x2, y2), cvScalar(b, g, r), width); cvReleaseImageHeader(&pImg); return HGBASE_ERR_OK; } 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; } std::string fontName = "宋体"; HGUInt fontSize = 20; HGBool bold = HGFALSE; HGBool underline = HGFALSE; HGBool italic = HGFALSE; HGBool strikeout = HGFALSE; if (NULL != fontParam) { if (0 == fontParam->fontSize) { return HGBASE_ERR_INVALIDARG; } fontName = fontParam->foneName; fontSize = fontParam->fontSize; bold = fontParam->bold; underline = fontParam->underline; italic = fontParam->italic; strikeout = fontParam->strikeout; } HGChar moduleName[256]; HGBase_GetModuleName((void *)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; HGResult ret = cvxText.Create(fontPath); if (HGBASE_ERR_OK != ret) { return ret; } ret = cvxText.DrawString(image, text, color, posType, locationX, locationY, fontSize, bold, underline, italic, strikeout); return ret; } #if 0 HGResult HGAPI HGImgProc_ImageBinarization(HGImage image, HGImage destImage, HGUInt thresholdType, HGInt threshold, HGInt blockSize, HGInt constant) { if (NULL == image || thresholdType < HGIMGPROC_THRESHTYPE_BINARY || thresholdType > HGIMGPROC_THRESHTYPE_ERROR_DIFFUSION) { return HGBASE_ERR_INVALIDARG; } CImageApplyBWBinaray::ThresholdType thresholdType2 = CImageApplyBWBinaray::ThresholdType::THRESH_BINARY; if (HGIMGPROC_THRESHTYPE_OTSU == thresholdType) thresholdType2 = CImageApplyBWBinaray::ThresholdType::THRESH_OTSU; else if (HGIMGPROC_THRESHTYPE_ADAPTIVE_GAUSSIAN == thresholdType) thresholdType2 = CImageApplyBWBinaray::ThresholdType::ADAPTIVE_GAUSSIAN; else if (HGIMGPROC_THRESHTYPE_ADAPTIVE_MEAN == thresholdType) thresholdType2 = CImageApplyBWBinaray::ThresholdType::ADAPTIVE_MEAN; else if (HGIMGPROC_THRESHTYPE_ERROR_DIFFUSION == thresholdType) thresholdType2 = CImageApplyBWBinaray::ThresholdType::ERROR_DIFFUSION; HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); 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; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BINARY == imgInfo.type) { return HGBASE_ERR_OK; } else if (HGBASE_IMGTYPE_GRAY != imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageBinarization(imageTmp, imageTmp, thresholdType, threshold, blockSize, constant); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left; cv::Mat img(roiHeight, roiWidth, CV_8UC(1), p, imgInfo.widthStep); CImageApplyBWBinaray imgApply(thresholdType2, threshold, blockSize, constant); imgApply.apply(img, 0); if (img.data != p) { for (HGUInt i = 0; i < roiHeight; ++i) { memcpy(p + i * imgInfo.widthStep, img.data + i * img.step, roiWidth); } } } else { HGImageInfo destImgInfo; HGBase_GetImageInfo(destImage, &destImgInfo); if (imgInfo.type != destImgInfo.type) { 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; } if (HGBASE_IMGTYPE_BINARY == imgInfo.type) { return HGBase_CopyImage(image, destImage); } else if (HGBASE_IMGTYPE_GRAY != imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageBinarization(imageTmp, imageTmp, thresholdType, threshold, blockSize, constant); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGBase_CopyImage(image, destImage); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * destImgInfo.widthStep + destRoi.left; cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(1), pDest, destImgInfo.widthStep); CImageApplyBWBinaray imgApply(thresholdType2, threshold, blockSize, constant); imgApply.apply(destImg, 0); if (destImg.data != pDest) { for (HGUInt i = 0; i < destRoiHeight; ++i) { memcpy(pDest + i * destImgInfo.widthStep, destImg.data + i * destImg.step, destRoiWidth); } } } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageExtractChannel(HGImage image, HGImage destImage, HGUInt channelType) { if (NULL == image || channelType < HGIMGPROC_CHANNELTYPE_RED || channelType > HGIMGPROC_CHANNELTYPE_EXCEPT_BLUE) { return HGBASE_ERR_INVALIDARG; } CImageApplyChannel::Channel channelType2 = CImageApplyChannel::Red; if (HGIMGPROC_CHANNELTYPE_GREEN == channelType) channelType2 = CImageApplyChannel::Green; else if (HGIMGPROC_CHANNELTYPE_BLUE == channelType) channelType2 = CImageApplyChannel::Blue; else if (HGIMGPROC_CHANNELTYPE_ALL == channelType) channelType2 = CImageApplyChannel::All; else if (HGIMGPROC_CHANNELTYPE_INVALID == channelType) channelType2 = CImageApplyChannel::Invalid; else if (HGIMGPROC_CHANNELTYPE_EXCEPT_RED == channelType) channelType2 = CImageApplyChannel::Except_Red; else if (HGIMGPROC_CHANNELTYPE_EXCEPT_GREEN == channelType) channelType2 = CImageApplyChannel::Except_Green; else if (HGIMGPROC_CHANNELTYPE_EXCEPT_BLUE == channelType) channelType2 = CImageApplyChannel::Except_Blue; HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); 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; if (NULL == destImage) { destImage = image; } else { 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; } } if (HGBASE_IMGTYPE_BGR != imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageExtractChannel(imageTmp, destImage, channelType); HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * 3; cv::Mat img(roiHeight, roiWidth, CV_8UC(3), p, imgInfo.widthStep); CImageApplyChannel imgApply(channelType2); imgApply.apply(img, 0); assert(img.data != p); HGImageInfo newImgInfo; newImgInfo.width = (HGUInt)img.cols; newImgInfo.height = (HGUInt)img.rows; newImgInfo.type = HGBASE_IMGTYPE_GRAY; newImgInfo.widthStep = (HGUInt)img.step; newImgInfo.origin = imgInfo.origin; HGImage newImg = NULL; HGResult ret = HGBase_CreateImageWithData(img.data, &newImgInfo, &newImg); if (NULL != newImg) { ret = HGBase_CopyImage(newImg, destImage); HGBase_DestroyImage(newImg); } return ret; } HGResult HGAPI HGImgProc_ImageColorRecognition(HGImage image, HGUInt* colorType) { if (NULL == image || NULL == colorType) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); if (HGBASE_IMGTYPE_BINARY == imgInfo.type) { *colorType = HGIMGPROC_COLORTYPE_BINARY; return HGBASE_ERR_OK; } 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; else if (HGBASE_IMGTYPE_BGRA == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type) channels = 4; uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGTYPE_GRAY == imgInfo.type) { *colorType = HGIMGPROC_COLORTYPE_BINARY; for (HGUInt h = 0; h < roiHeight; ++h) { for (HGUInt w = 0; w < roiWidth; ++w) { uint8_t *pData = p + imgInfo.widthStep * h + w * channels; if (0 != *pData && 255 != *pData) { *colorType = HGIMGPROC_COLORTYPE_GRAY; break; } } } } else { if (HGBASE_IMGTYPE_BGR != imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageColorRecognition(imageTmp, colorType); HGBase_DestroyImage(imageTmp); } return ret; } cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep); CImageApplyColorRecognition imgApply(CImageApplyColorRecognition::AllColor); imgApply.apply(img, 0); *colorType = HGIMGPROC_COLORTYPE_COLOR; CImageApplyColorRecognition::ColorType colorType2 = imgApply.getResult(); if (CImageApplyColorRecognition::Gray == colorType2) *colorType = HGIMGPROC_COLORTYPE_GRAY; else if (CImageApplyColorRecognition::Mono == colorType2) *colorType = HGIMGPROC_COLORTYPE_BINARY; } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageDispersion(HGImage image, HGImage destImage) { if (NULL == image) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); HGUInt type = imgInfo.type; 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; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BGR != type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageDispersion(imageTmp, imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * 3; cv::Mat img(roiHeight, roiWidth, CV_8UC(3), p, imgInfo.widthStep); CImageApplyDispersion imgApply; imgApply.apply(img, 0); assert(img.data == p); } 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; } if (HGBASE_IMGTYPE_BGR != type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageDispersion(imageTmp, imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGBase_CopyImage(image, destImage); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * destImgInfo.widthStep + destRoi.left * 3; cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(3), pDest, destImgInfo.widthStep); CImageApplyDispersion imgApply; imgApply.apply(destImg, 0); assert(destImg.data == pDest); } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageFilter(HGImage image, HGImage destImage, HGUInt filterType, HGInt kSize) { if (NULL == image || filterType < HGIMGPROC_FILTERTYPE_SHARPEN || filterType > HGIMGPROC_FILTERTYPE_BRIGHTSHARP) { return HGBASE_ERR_INVALIDARG; } CImageApplyFilter::FilterMode filterType2 = CImageApplyFilter::Sharpen; if (HGIMGPROC_FILTERTYPE_SHARPEN_MORE == filterType) filterType2 = CImageApplyFilter::Sharpen_More; else if (HGIMGPROC_FILTERTYPE_AVERBLUR == filterType) filterType2 = CImageApplyFilter::AverBlur; else if (HGIMGPROC_FILTERTYPE_AVERBLUR_MORE == filterType) filterType2 = CImageApplyFilter::AverBlur_More; else if (HGIMGPROC_FILTERTYPE_BILATERALFILTER == filterType) filterType2 = CImageApplyFilter::BilateralFilter; else if (HGIMGPROC_FILTERTYPE_GAUSSIANBLUR == filterType) filterType2 = CImageApplyFilter::GaussianBlur; else if (HGIMGPROC_FILTERTYPE_BRIGHTSHARP == filterType) filterType2 = CImageApplyFilter::BrightSharp; HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); 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; else if (HGBASE_IMGTYPE_BGRA == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type) channels = 4; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageFilter(imageTmp, imageTmp, filterType, kSize); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * channels; cv::Mat img(roiHeight, roiWidth, CV_8UC(channels), p, imgInfo.widthStep); CImageApplyFilter imgApply(filterType2, kSize); imgApply.apply(img, 0); if (img.data != p) { for (HGUInt i = 0; i < roiHeight; ++i) { memcpy(p + i * imgInfo.widthStep, img.data + i * img.step, roiWidth * channels); } } } else { HGImageInfo destImgInfo; HGBase_GetImageInfo(destImage, &destImgInfo); if (imgInfo.type != destImgInfo.type) { 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; } if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageFilter(imageTmp, imageTmp, filterType, kSize); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGBase_CopyImage(image, destImage); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * destImgInfo.widthStep + destRoi.left * channels; cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(channels), pDest, destImgInfo.widthStep); CImageApplyFilter imgApply(filterType2, kSize); imgApply.apply(destImg, 0); if (destImg.data != pDest) { for (HGUInt i = 0; i < destRoiHeight; ++i) { memcpy(pDest + i * destImgInfo.widthStep, destImg.data + i * destImg.step, destRoiWidth * channels); } } } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageOutHole(HGImage image1, HGImage image2, HGFloat borderSize, HGFloat edgeScale, HGDouble threshold) { if (NULL == image1 || NULL == image2 || image1 == image2) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo1; HGBase_GetImageInfo(image1, &imgInfo1); HGImageInfo imgInfo2; HGBase_GetImageInfo(image2, &imgInfo2); if (imgInfo1.type != imgInfo2.type || imgInfo1.origin != imgInfo2.origin) { return HGBASE_ERR_INVALIDDATA; } HGByte* data1 = NULL; HGBase_GetImageData(image1, &data1); HGByte* data2 = NULL; HGBase_GetImageData(image2, &data2); HGImageRoi roi1; HGBase_GetImageROI(image1, &roi1); HGUInt roiWidth1 = roi1.right - roi1.left; HGUInt roiHeight1 = roi1.bottom - roi1.top; HGImageRoi roi2; HGBase_GetImageROI(image2, &roi2); HGUInt roiWidth2 = roi2.right - roi2.left; HGUInt roiHeight2 = roi2.bottom - roi2.top; if (roiWidth1 != roiWidth2 || roiHeight1 != roiHeight2) { return HGBASE_ERR_INVALIDDATA; } if (HGBASE_IMGTYPE_BINARY == imgInfo1.type || HGBASE_IMGTYPE_RGBA == imgInfo1.type || HGBASE_IMGTYPE_BGRA == imgInfo1.type || HGBASE_IMGTYPE_RGB == imgInfo1.type) { HGImage imageTmp1 = NULL; HGResult ret = HGBase_CloneImage(image1, HGBASE_IMGTYPE_BGR, 0, &imageTmp1); if (HGBASE_ERR_OK == ret) { HGImage imageTmp2 = NULL; ret = HGBase_CloneImage(image2, HGBASE_IMGTYPE_BGR, 0, &imageTmp2); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageOutHole(imageTmp1, imageTmp2, borderSize, edgeScale, threshold); if (HGBASE_ERR_OK == ret) { HGBase_CopyImage(imageTmp1, image1); HGBase_CopyImage(imageTmp2, image2); } HGBase_DestroyImage(imageTmp2); } HGBase_DestroyImage(imageTmp1); } return ret; } uint32_t channels = 1; if (HGBASE_IMGTYPE_BGR == imgInfo1.type || HGBASE_IMGTYPE_RGB == imgInfo1.type) channels = 3; else if (HGBASE_IMGTYPE_BGRA == imgInfo1.type || HGBASE_IMGTYPE_RGBA == imgInfo1.type) channels = 4; uint8_t* p1 = data1 + roi1.top * imgInfo1.widthStep + roi1.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo1.origin) p1 = data1 + (imgInfo1.height - roi1.bottom) * imgInfo1.widthStep + roi1.left * channels; cv::Mat img1(roiHeight1, roiWidth1, CV_8UC(channels), p1, imgInfo1.widthStep); uint8_t* p2 = data2 + roi2.top * imgInfo2.widthStep + roi2.left * channels; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo2.origin) p2 = data2 + (imgInfo2.height - roi2.bottom) * imgInfo2.widthStep + roi2.left * channels; cv::Mat img2(roiHeight2, roiWidth2, CV_8UC(channels), p2, imgInfo2.widthStep); std::vector mats; mats.push_back(img1); mats.push_back(img2); CImageApplyOutHole imgApply(borderSize, edgeScale, threshold); imgApply.apply(mats, true); assert(mats[0].data == p1); assert(mats[1].data == p2); return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageHSVCorrect(HGImage image, HGImage destImage, HGUInt correctOption, HGBool cvtGray, HGColor color) { if (NULL == image || correctOption < HGIMGPROC_CORRECTOPTION_DEFAULT || correctOption > HGIMGPROC_CORRECTOPTION_RED_REMOVAL) { return HGBASE_ERR_INVALIDARG; } CImageApplyHSVCorrect::CorrectOption correctOption2 = CImageApplyHSVCorrect::Deafault; if (HGIMGPROC_CORRECTOPTION_LOWSATURATION_REMOVAL == correctOption) correctOption2 = CImageApplyHSVCorrect::LowSaturation_Removal; else if (HGIMGPROC_CORRECTOPTION_RED_REMOVAL == correctOption) correctOption2 = CImageApplyHSVCorrect::Red_Removal; bool cvtGray2 = cvtGray ? true : false; HGUInt r = HG_GETCOLOR_R(color); HGUInt g = HG_GETCOLOR_G(color); HGUInt b = HG_GETCOLOR_B(color); uint color2 = (uint)(((HGUInt)r << 16) | ((HGUInt)g << 8) | (HGUInt)b); HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); HGUInt type = imgInfo.type; 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; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BGR != type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageHSVCorrect(imageTmp, imageTmp, correctOption, cvtGray, color); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * 3; cv::Mat img(roiHeight, roiWidth, CV_8UC(3), p, imgInfo.widthStep); CImageApplyHSVCorrect imgApply(correctOption2, cvtGray2, color2); imgApply.apply(img, 0); assert(img.data == p); } 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; } if (HGBASE_IMGTYPE_BGR != type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageHSVCorrect(imageTmp, imageTmp, correctOption, cvtGray, color); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGBase_CopyImage(image, destImage); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * destImgInfo.widthStep + destRoi.left * 3; cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(3), pDest, destImgInfo.widthStep); CImageApplyHSVCorrect imgApply(correctOption2, cvtGray2, color2); imgApply.apply(destImg, 0); assert(destImg.data == pDest); } return HGBASE_ERR_OK; } #endif HGResult HGAPI HGImgProc_ImageFadeBkColor(HGImage image, HGImage destImage, const HGImgFaceBkColorParam* param) { if (NULL == image) { return HGBASE_ERR_INVALIDARG; } int threshold = 100; int offset = 0; int range = 40; if (NULL != param) { threshold = param->threshold; offset = param->offset; range = param->range; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); HGUInt type = imgInfo.type; 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; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BGR != type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageFadeBkColor(imageTmp, imageTmp, param); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) p = data + (imgInfo.height - roi.bottom) * imgInfo.widthStep + roi.left * 3; cv::Mat img(roiHeight, roiWidth, CV_8UC(3), p, imgInfo.widthStep); CImageApplyFadeBackGroudColor imgApply(threshold, offset, range); imgApply.apply(img, 0); assert(img.data == p); } 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; } if (HGBASE_IMGTYPE_BGR != type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageFadeBkColor(imageTmp, imageTmp, param); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGBase_CopyImage(image, destImage); uint8_t* pDest = destData + destRoi.top * destImgInfo.widthStep + destRoi.left * 3; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) pDest = destData + (destImgInfo.height - destRoi.bottom) * destImgInfo.widthStep + destRoi.left * 3; cv::Mat destImg(destRoiHeight, destRoiWidth, CV_8UC(3), pDest, destImgInfo.widthStep); CImageApplyFadeBackGroudColor imgApply(threshold, offset, range); imgApply.apply(destImg, 0); assert(destImg.data == pDest); } return HGBASE_ERR_OK; } HGResult HGAPI HGImgProc_ImageDecontamination(HGImage image, HGImage destImage, HGUInt decoType, HGUInt x, HGUInt y, HGUInt width, HGUInt height, HGColor color) { if (NULL == image || decoType < HGIMGPROC_DECOTYPE_INSIDE || decoType > HGIMGPROC_DECOTYPE_OUTSIDE || 0 == width || 0 == height) { return HGBASE_ERR_INVALIDARG; } HGImageInfo imgInfo; HGBase_GetImageInfo(image, &imgInfo); 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; if (x + width > roiWidth || y + height > roiHeight) { return HGBASE_ERR_INVALIDARG; } uint32_t channels = 1; if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_RGB == imgInfo.type) channels = 3; else if (HGBASE_IMGTYPE_BGRA == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type) channels = 4; uint32_t dataSize = roiWidth * channels; HGUInt r = HG_GETCOLOR_R(color); HGUInt g = HG_GETCOLOR_G(color); HGUInt b = HG_GETCOLOR_B(color); HGUInt v = (r * 76 + g * 150 + b * 30) >> 8; if (NULL == destImage || image == destImage) { if (HGBASE_IMGTYPE_BINARY == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageDecontamination(imageTmp, imageTmp, decoType, x, y, width, height, color); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, image); } HGBase_DestroyImage(imageTmp); } return ret; } HGByte* p = data + (HGUSize)roi.top * (HGUSize)imgInfo.widthStep + roi.left * channels; HGInt step = (HGInt)imgInfo.widthStep; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) { p = data + (HGUSize)(imgInfo.height - roi.top - 1) * (HGUSize)imgInfo.widthStep + roi.left * channels; step = -(HGInt)imgInfo.widthStep; } if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { r = HG_GETCOLOR_B(color); g = HG_GETCOLOR_G(color); b = HG_GETCOLOR_R(color); } if (HGIMGPROC_DECOTYPE_INSIDE == decoType) { //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pEx = p + (HGSize)i * (HGSize)step; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pEx2 = pEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) { pEx2[0] = r; pEx2[1] = g; pEx2[2] = b; } } } } else { assert(HGIMGPROC_DECOTYPE_OUTSIDE == decoType); //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pEx = p + (HGSize)i * (HGSize)step; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pEx2 = pEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) { } else { pEx2[0] = r; pEx2[1] = g; pEx2[2] = b; } } } } } else { assert(HGBASE_IMGTYPE_GRAY == imgInfo.type); if (HGIMGPROC_DECOTYPE_INSIDE == decoType) { //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pEx = p + (HGSize)i * (HGSize)step; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pEx2 = pEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) *pEx2 = v; } } } else { assert(HGIMGPROC_DECOTYPE_OUTSIDE == decoType); //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pEx = p + (HGSize)i * (HGSize)step; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pEx2 = pEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) { } else *pEx2 = v; } } } } } else { HGImageInfo destImgInfo; HGBase_GetImageInfo(destImage, &destImgInfo); if (imgInfo.type != destImgInfo.type) { 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; } if (HGBASE_IMGTYPE_BINARY == imgInfo.type) { HGImage imageTmp = NULL; HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, 0, &imageTmp); if (HGBASE_ERR_OK == ret) { ret = HGImgProc_ImageDecontamination(imageTmp, imageTmp, decoType, x, y, width, height, color); if (HGBASE_ERR_OK == ret) { ret = HGBase_CopyImage(imageTmp, destImage); } HGBase_DestroyImage(imageTmp); } return ret; } HGByte* src = data + (HGUSize)roi.top * (HGUSize)imgInfo.widthStep + roi.left * channels; HGInt srcStep = (HGInt)imgInfo.widthStep; if (HGBASE_IMGORIGIN_BOTTOM == imgInfo.origin) { src = data + (HGUSize)(imgInfo.height - roi.top - 1) * (HGUSize)imgInfo.widthStep + roi.left * channels; srcStep = -(HGInt)imgInfo.widthStep; } HGByte* dest = destData + (HGUSize)destRoi.top * (HGUSize)destImgInfo.widthStep + destRoi.left * channels; HGInt destStep = (HGInt)destImgInfo.widthStep; if (HGBASE_IMGORIGIN_BOTTOM == destImgInfo.origin) { dest = destData + (HGUSize)(destImgInfo.height - destRoi.top - 1) * (HGUSize)destImgInfo.widthStep + destRoi.left * channels; destStep = -(HGInt)destImgInfo.widthStep; } if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type || HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type) { r = HG_GETCOLOR_B(color); g = HG_GETCOLOR_G(color); b = HG_GETCOLOR_R(color); } if (HGIMGPROC_DECOTYPE_INSIDE == decoType) { //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pSrcEx = src + (HGSize)i * (HGSize)srcStep; HGByte* pDestEx = dest + (HGSize)i * (HGSize)destStep; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pSrcEx2 = pSrcEx + j * channels; HGByte* pDestEx2 = pDestEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) { pDestEx2[0] = r; pDestEx2[1] = g; pDestEx2[2] = b; } else { pDestEx2[0] = pSrcEx2[0]; pDestEx2[1] = pSrcEx2[1]; pDestEx2[2] = pSrcEx2[2]; } } } } else { assert(HGIMGPROC_DECOTYPE_OUTSIDE == decoType); //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pSrcEx = src + (HGSize)i * (HGSize)srcStep; HGByte* pDestEx = dest + (HGSize)i * (HGSize)destStep; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pSrcEx2 = pSrcEx + j * channels; HGByte* pDestEx2 = pDestEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) { pDestEx2[0] = pSrcEx2[0]; pDestEx2[1] = pSrcEx2[1]; pDestEx2[2] = pSrcEx2[2]; } else { pDestEx2[0] = r; pDestEx2[1] = g; pDestEx2[2] = b; } } } } } else { assert(HGBASE_IMGTYPE_GRAY == imgInfo.type); if (HGIMGPROC_DECOTYPE_INSIDE == decoType) { //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pSrcEx = src + (HGSize)i * (HGSize)srcStep; HGByte* pDestEx = dest + (HGSize)i * (HGSize)destStep; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pSrcEx2 = pSrcEx + j * channels; HGByte* pDestEx2 = pDestEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) *pDestEx2 = v; else *pDestEx2 = *pSrcEx2; } } } else { assert(HGIMGPROC_DECOTYPE_OUTSIDE == decoType); //#pragma omp parallel for for (int32_t i = 0; i < (int32_t)roiHeight; ++i) { HGByte* pSrcEx = src + (HGSize)i * (HGSize)srcStep; HGByte* pDestEx = dest + (HGSize)i * (HGSize)destStep; for (int32_t j = 0; j < (int32_t)roiWidth; ++j) { HGByte* pSrcEx2 = pSrcEx + j * channels; HGByte* pDestEx2 = pDestEx + j * channels; if ((j >= (int32_t)x && j < (int32_t)(x + width)) && (i >= (int32_t)y && i < (int32_t)(y + height))) *pDestEx2 = *pSrcEx2; else *pDestEx2 = v; } } } } } return HGBASE_ERR_OK; }