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