imgproc增加二值化算法

This commit is contained in:
luoliangyi 2022-06-18 10:32:32 +08:00
parent 4536c698e6
commit 36dfa08c0a
4 changed files with 172 additions and 11 deletions

View File

@ -8,6 +8,7 @@ HGImgProc_ImageAutoCrop
HGImgProc_ImageBlankCheck
HGImgProc_ImageDrawLine
HGImgProc_AddImageWatermark
HGImgProc_ImageBinarization
HGImgProc_CreateOCRMgr
HGImgProc_DestroyOCRMgr

View File

@ -104,6 +104,16 @@ BOOL CHGTestDlg::OnInitDialog()
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
HGImage img = NULL;
HGImgFmt_LoadImage("D:\\1.jpg", 0, NULL, HGBASE_IMGTYPE_BGRA, HGBASE_IMGORIGIN_BOTTOM, &img);
if (NULL != img)
{
HGImgProc_ImageBinarization(img, img, HGIMGPROC_THRESHTYPE_OTSU, 120, 51, 41);
HGImgFmt_SaveImage(img, 0, NULL, "D:\\2222.bmp");
HGBase_DestroyImage(img);
}
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}

View File

@ -2,6 +2,7 @@
#include "./ImageProcess/ImageApplyAdjustColors.h"
#include "./ImageProcess/ImageApplyAutoCrop.h"
#include "./ImageProcess/ImageApplyDiscardBlank.h"
#include "./ImageProcess/ImageApplyBWBinaray.h"
#include "CvxText.hpp"
#include "../base/HGInc.h"
#include "../base/HGUtility.h"
@ -159,6 +160,7 @@ HGResult HGAPI HGImgProc_ImageAdjustColors(HGImage image, HGImage destImage,
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
{
@ -210,6 +212,7 @@ HGResult HGAPI HGImgProc_ImageAdjustColors(HGImage image, HGImage destImage,
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;
@ -225,11 +228,11 @@ HGResult HGAPI HGImgProc_ImageAutoCrop(HGImage image, HGBool autoCrop, HGBool de
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type
|| HGBASE_IMGTYPE_BGRA == imgInfo.type)
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_RGB, 0, &imageTmp);
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp);
if (HGBASE_ERR_OK == ret)
{
if (0 == destType)
@ -273,7 +276,7 @@ HGResult HGAPI HGImgProc_ImageAutoCrop(HGImage image, HGBool autoCrop, HGBool de
HGUInt roiHeight = roi.bottom - roi.top;
uint32_t channels = 1;
if (HGBASE_IMGTYPE_RGB == imgInfo.type || HGBASE_IMGTYPE_BGR == imgInfo.type)
if (HGBASE_IMGTYPE_BGR == imgInfo.type)
channels = 3;
uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels;
@ -314,11 +317,11 @@ HGResult HGAPI HGImgProc_ImageBlankCheck(HGImage image, const HGImgBlankCheckPar
HGImageInfo imgInfo;
HGBase_GetImageInfo(image, &imgInfo);
if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_RGBA == imgInfo.type
|| HGBASE_IMGTYPE_BGRA == imgInfo.type)
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_RGB, 0, &imageTmp);
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_BGR, 0, &imageTmp);
if (HGBASE_ERR_OK == ret)
{
ret = HGImgProc_ImageBlankCheck(imageTmp, param, blank);
@ -352,7 +355,7 @@ HGResult HGAPI HGImgProc_ImageBlankCheck(HGImage image, const HGImgBlankCheckPar
HGUInt roiHeight = roi.bottom - roi.top;
uint32_t channels = 1;
if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_RGB == imgInfo.type)
if (HGBASE_IMGTYPE_BGR == imgInfo.type)
channels = 3;
uint8_t* p = data + roi.top * imgInfo.widthStep + roi.left * channels;
@ -379,7 +382,7 @@ HGResult HGAPI HGImgProc_ImageDrawLine(HGImage image, HGInt x1, HGInt y1, HGInt
if (HGBASE_IMGTYPE_BINARY == imgInfo.type || HGBASE_IMGTYPE_GRAY == imgInfo.type)
{
HGImage imageTmp = NULL;
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, 0, &imageTmp);
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);
@ -422,14 +425,14 @@ HGResult HGAPI HGImgProc_ImageDrawLine(HGImage image, HGInt x1, HGInt y1, HGInt
HGUInt r = HG_GETCOLOR_R(color);
HGUInt g = HG_GETCOLOR_G(color);
HGUInt b = HG_GETCOLOR_B(color);
if (HGBASE_IMGTYPE_BGR == imgInfo.type || HGBASE_IMGTYPE_BGRA == imgInfo.type)
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(r, g, b), width);
cvLine(pImg, cvPoint(x1, y1), cvPoint(x2, y2), cvScalar(b, g, r), width);
cvReleaseImageHeader(&pImg);
return HGBASE_ERR_OK;
}
@ -482,3 +485,128 @@ HGResult HGAPI HGImgProc_AddImageWatermark(HGImage image, const HGChar* text, HG
ret = cvxText.DrawString(image, text, color, posType, locationX, locationY, fontSize, bold, underline, italic, strikeout);
return ret;
}
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_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_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;
}

View File

@ -37,6 +37,17 @@
/* 水印位置-自定义 */
#define HGIMGPROC_WMPOSTYPE_LOCATION 10L
/* 传统二值化 */
#define HGIMGPROC_THRESHTYPE_BINARY 1L
/* 大津法 */
#define HGIMGPROC_THRESHTYPE_OTSU 2L
/* 高斯局部自适应阈值 */
#define HGIMGPROC_THRESHTYPE_ADAPTIVE_GAUSSIAN 3L
/* 均值局部自适应阈值 */
#define HGIMGPROC_THRESHTYPE_ADAPTIVE_MEAN 4L
/* 错误扩散 */
#define HGIMGPROC_THRESHTYPE_ERROR_DIFFUSION 5L
/* 自动裁剪参数 */
typedef struct
{
@ -155,4 +166,15 @@ HGEXPORT HGResult HGAPI HGImgProc_ImageDrawLine(HGImage image, HGInt x1, HGInt y
HGEXPORT HGResult HGAPI HGImgProc_AddImageWatermark(HGImage image, const HGChar *text, HGColor color, HGUInt posType,
HGInt locationX, HGInt locationY, const HGImgWatermarkFontParam *fontParam);
/* 图像二值化
* 1) image: in,
* 2) destImage: in,
* 3) thresholdType: in, HGIMGPROC_THRESHTYPE_*
* 4) threshold: in, , HGIMGPROC_THRESHTYPE_OTSU时无效
* 5) blockSize: in, HGIMGPROC_THRESHTYPE_ADAPTIVE_GAUSSIAN和HGIMGPROC_THRESHTYPE_ADAPTIVE_MEAN模式有效
* 6) constant: in, HGIMGPROC_THRESHTYPE_ADAPTIVE_GAUSSIAN和HGIMGPROC_THRESHTYPE_ADAPTIVE_MEAN模式有效blockSize形成比例关系
*/
HGEXPORT HGResult HGAPI HGImgProc_ImageBinarization(HGImage image, HGImage destImage, HGUInt thresholdType,
HGInt threshold, HGInt blockSize, HGInt constant);
#endif /* __HGIMGPROC_H__ */