diff --git a/build/windows/HGImgProc/HGImgProc.def b/build/windows/HGImgProc/HGImgProc.def index 0663af36..ba664b06 100644 --- a/build/windows/HGImgProc/HGImgProc.def +++ b/build/windows/HGImgProc/HGImgProc.def @@ -16,6 +16,7 @@ HGImgProc_ImageFadeBkColor HGImgProc_ImageFilter HGImgProc_ImageOutHole HGImgProc_ImageHSVCorrect +HGImgProc_ImageDecontamination HGImgProc_CreateOCRMgr HGImgProc_DestroyOCRMgr diff --git a/build/windows/HGTest/HGTestDlg.cpp b/build/windows/HGTest/HGTestDlg.cpp index 9c674ccd..b7701ecc 100644 --- a/build/windows/HGTest/HGTestDlg.cpp +++ b/build/windows/HGTest/HGTestDlg.cpp @@ -105,10 +105,10 @@ BOOL CHGTestDlg::OnInitDialog() SetIcon(m_hIcon, FALSE); // 设置小图标 HGImage img = NULL; - HGImgFmt_LoadImage("D:\\1.jpg", 0, NULL, HGBASE_IMGTYPE_BINARY, HGBASE_IMGORIGIN_TOP, &img); + HGImgFmt_LoadImage("D:\\1.jpg", 0, NULL, HGBASE_IMGTYPE_BGRA, HGBASE_IMGORIGIN_BOTTOM, &img); if (NULL != img) { - HGImgProc_ImageHSVCorrect(img, img, HGIMGPROC_CORRECTOPTION_LOWSATURATION_REMOVAL, HGTRUE, HG_MAKECOLOR(255, 0, 0, 0)); + HGImgProc_ImageDecontamination(img, img, HGIMGPROC_DECOTYPE_INSIDE, 100, 200, 300, 500, HG_MAKECOLOR(255, 0, 0, 0)); HGImgFmt_SaveImage(img, 0, NULL, "D:\\222.bmp"); HGBase_DestroyImage(img); diff --git a/build/windows/HGWebService/HGWebService.vcxproj b/build/windows/HGWebService/HGWebService.vcxproj index c41b4677..b1baf59e 100644 --- a/build/windows/HGWebService/HGWebService.vcxproj +++ b/build/windows/HGWebService/HGWebService.vcxproj @@ -138,7 +138,7 @@ Windows true - ../Debug/HGBase.lib;../Debug/HGImgFmt.lib;../Debug/HGImgProc.lib;../../../../sdk/lib/win/x86/Debug/hgsane.lib;../../../third_party/zlib/windows/lib/x86/zlib.lib;../../../third_party/libzip/windows/lib/x86/zip.lib;../../../third_party/libcurl/windows/lib/x86/libcurld.lib;wldap32.lib;ws2_32.lib;%(AdditionalDependencies) + ../Debug/HGBase.lib;../Debug/HGImgFmt.lib;../Debug/HGImgProc.lib;../../../../sdk/lib/win/x86/Release/sane.lib;../../../third_party/zlib/windows/lib/x86/zlib.lib;../../../third_party/libzip/windows/lib/x86/zip.lib;../../../third_party/libcurl/windows/lib/x86/libcurld.lib;wldap32.lib;ws2_32.lib;%(AdditionalDependencies) /ignore:4098,4099,4075 /LTCG %(AdditionalOptions) @@ -158,7 +158,7 @@ true true true - ../Release/HGBase.lib;../Release/HGImgFmt.lib;../Release/HGImgProc.lib;../../../../sdk/lib/win/x86/Release/hgsane.lib;../../../third_party/zlib/windows/lib/x86/zlib.lib;../../../third_party/libzip/windows/lib/x86/zip.lib;../../../third_party/libcurl/windows/lib/x86/libcurl.lib;wldap32.lib;ws2_32.lib;%(AdditionalDependencies) + ../Release/HGBase.lib;../Release/HGImgFmt.lib;../Release/HGImgProc.lib;../../../../sdk/lib/win/x86/Release/sane.lib;../../../third_party/zlib/windows/lib/x86/zlib.lib;../../../third_party/libzip/windows/lib/x86/zip.lib;../../../third_party/libcurl/windows/lib/x86/libcurl.lib;wldap32.lib;ws2_32.lib;%(AdditionalDependencies) /ignore:4099 /LTCG %(AdditionalOptions) @@ -177,7 +177,7 @@ Windows true - ../x64/Debug/HGBase.lib;../x64/Debug/HGImgFmt.lib;../x64/Debug/HGImgProc.lib;../../../../sdk/lib/win/x64/Debug/hgsane.lib;../../../third_party/zlib/windows/lib/x64/zlib.lib;../../../third_party/libzip/windows/lib/x64/zip.lib;ws2_32.lib;%(AdditionalDependencies) + ../x64/Debug/HGBase.lib;../x64/Debug/HGImgFmt.lib;../x64/Debug/HGImgProc.lib;../../../../sdk/lib/win/x64/Release/sane.lib;../../../third_party/zlib/windows/lib/x64/zlib.lib;../../../third_party/libzip/windows/lib/x64/zip.lib;ws2_32.lib;%(AdditionalDependencies) /ignore:4098,4099,4075 /LTCG %(AdditionalOptions) @@ -197,7 +197,7 @@ true true true - ../x64/Release/HGBase.lib;../x64/Release/HGImgFmt.lib;../x64/Release/HGImgProc.lib;../../../../sdk/lib/win/x64/Release/hgsane.lib;../../../third_party/zlib/windows/lib/x64/zlib.lib;../../../third_party/libzip/windows/lib/x64/zip.lib;ws2_32.lib;%(AdditionalDependencies) + ../x64/Release/HGBase.lib;../x64/Release/HGImgFmt.lib;../x64/Release/HGImgProc.lib;../../../../sdk/lib/win/x64/Release/sane.lib;../../../third_party/zlib/windows/lib/x64/zlib.lib;../../../third_party/libzip/windows/lib/x64/zip.lib;ws2_32.lib;%(AdditionalDependencies) /LTCG %(AdditionalOptions) diff --git a/modules/imgproc/HGImgProc.cpp b/modules/imgproc/HGImgProc.cpp index f894d5ca..bd24e5a1 100644 --- a/modules/imgproc/HGImgProc.cpp +++ b/modules/imgproc/HGImgProc.cpp @@ -1353,3 +1353,330 @@ HGResult HGAPI HGImgProc_ImageHSVCorrect(HGImage image, HGImage destImage, HGUIn 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; +} diff --git a/modules/imgproc/HGImgProc.h b/modules/imgproc/HGImgProc.h index 3d53e40f..64cb241b 100644 --- a/modules/imgproc/HGImgProc.h +++ b/modules/imgproc/HGImgProc.h @@ -94,6 +94,11 @@ /* 除掉红色。红色定义H:[0, 85]∪[170, 255],S:[10, 255],V:[120,255] */ #define HGIMGPROC_CORRECTOPTION_RED_REMOVAL 3L +/* 内部去污 */ +#define HGIMGPROC_DECOTYPE_INSIDE 1L +/* 外部去污 */ +#define HGIMGPROC_DECOTYPE_OUTSIDE 2L + /* 自动裁剪参数 */ typedef struct { @@ -320,4 +325,21 @@ HGEXPORT HGResult HGAPI HGImgProc_ImageOutHole(HGImage image1, HGImage image2, H */ HGEXPORT HGResult HGAPI HGImgProc_ImageHSVCorrect(HGImage image, HGImage destImage, HGUInt correctOption, HGBool cvtGray, HGColor color); +/* 图像去污 +* 1) image: in, 源图像句柄 +* 2) destImage: in, 目标图像句柄 +* 3) decoType: in, 去污类型, 参见HGIMGPROC_DECOTYPE_* +* 4) x: in, 选择区域的x坐标 +* 5) y: in, 选择区域的y坐标 +* 6) width: in, 选择区域的宽 +* 7) height: in, 选择区域的高 +* 说明: +* 1) 操作的只是图像的ROI区域, ROI区域的大小必须一致 +* 2) 源图像和目标图像的type必须一样 +* 3) 自动处理origon不一致的情况 +* 4) image和destImage可以是同一个句柄 +*/ +HGEXPORT HGResult HGAPI HGImgProc_ImageDecontamination(HGImage image, HGImage destImage, HGUInt decoType, HGUInt x, HGUInt y, + HGUInt width, HGUInt height, HGColor color); + #endif /* __HGIMGPROC_H__ */ \ No newline at end of file