mirror of http://192.168.1.51:8099/lmh188/twain3.0
parent
40e5903aca
commit
a72e300eb1
|
@ -87,7 +87,7 @@ static std::vector<CString> reslutions{
|
|||
_T("240"),
|
||||
_T("300"),
|
||||
#ifndef LANXUM
|
||||
//_T("600")
|
||||
_T("600")
|
||||
#endif // LANXUM
|
||||
};
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ void ImageMatQueue::setparam(const GScanCap& param)
|
|||
#else // REAL300DPI
|
||||
fixedSize = papersize.GetPaperSize(param.papertype, 200.0f, param.paperAlign);
|
||||
#endif
|
||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex,param.AutoCrop_threshold,param.noise,param.indent)));
|
||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(islongcustomcrop ? islongcustomcrop : param.is_autocrop, param.autodescrew, param.fillbackground, cv::Size(fixedSize.cx, fixedSize.cy), param.is_convex,false,param.AutoCrop_threshold,param.noise,param.indent)));
|
||||
}
|
||||
if (param.is_autodiscradblank_normal || param.is_autodiscradblank_vince) {
|
||||
//m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank()));
|
||||
|
|
|
@ -22,44 +22,31 @@ CImageApplyAdjustColors::~CImageApplyAdjustColors(void)
|
|||
|
||||
void CImageApplyAdjustColors::apply(cv::Mat& pDib,int side)
|
||||
{
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "enter CImageApplyAdjustColors apply");
|
||||
#endif // LOG
|
||||
if (pDib.empty())
|
||||
{
|
||||
(void)side;
|
||||
if (pDib.empty()) return;
|
||||
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyAdjustColors apply");
|
||||
#endif // LOG
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_brightness != 0 || m_contrast != 0 || m_gamma != 1.0)
|
||||
cv::LUT(pDib, lut, pDib);
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyAdjustColors apply");
|
||||
#endif // LOG
|
||||
if (m_brightness != 0 || m_contrast != 0 || m_gamma < 0.999999f || m_gamma > 1.000001f)
|
||||
cv::LUT(pDib, lut, pDib);
|
||||
}
|
||||
|
||||
void CImageApplyAdjustColors::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
{
|
||||
if (mats.empty()) return;
|
||||
if (!mats[0].empty()) {
|
||||
apply(mats[0], 0);
|
||||
}
|
||||
|
||||
|
||||
if (isTwoSide && mats.size() > 1) {
|
||||
if(!mats[1].empty())
|
||||
apply(mats[1], 1);
|
||||
(void)isTwoSide;
|
||||
int i = 0;
|
||||
for (cv::Mat& var : mats) {
|
||||
if (i != 0 && isTwoSide == false)
|
||||
break;
|
||||
if(!var.empty())
|
||||
apply(var, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyAdjustColors::setAdjustColors(int brightness, int contrast, float gamma)
|
||||
{
|
||||
setBrightness(brightness);
|
||||
setContrast(contrast);
|
||||
setGamma(gamma);
|
||||
m_brightness = cv::max(-255, cv::min(brightness, 255));
|
||||
m_contrast = cv::max(-127, cv::min(contrast, 127));
|
||||
m_gamma = cv::max(0.1f, cv::min(gamma, 5.0f));
|
||||
update_lutData();
|
||||
}
|
||||
|
||||
|
@ -85,24 +72,19 @@ void CImageApplyAdjustColors::update_lutData()
|
|||
{
|
||||
unsigned char* ptr = lut.data;
|
||||
|
||||
if (m_gamma != 1.0f)
|
||||
uchar buffer[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
float g = 1.0f / m_gamma;
|
||||
for (int i = 0; i < 256; i++)
|
||||
ptr[i] = static_cast<unsigned char>(cv::min(255, static_cast<int>(cv::pow(i / 255.0f, g) * 255.0f + 0.5f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
//update contrast
|
||||
if (i < 128)
|
||||
ptr[i] = static_cast<unsigned char>(cv::max(0, cv::min(i - m_contrast, 127)));
|
||||
else
|
||||
ptr[i] = static_cast<unsigned char>(cv::max(127, cv::min(i + m_contrast, 255)));
|
||||
//update brightness
|
||||
ptr[i] = static_cast<unsigned char>(cv::max(0, cv::min(i + m_brightness, 255)));
|
||||
|
||||
//update brightness
|
||||
ptr[i] = static_cast<unsigned char>(cv::max(0, cv::min(ptr[i] + m_brightness, 255)));
|
||||
}
|
||||
//update contrast
|
||||
if (ptr[i] < 128)
|
||||
ptr[i] = static_cast<unsigned char>(cv::max(0, cv::min(ptr[i] - m_contrast, 127)));
|
||||
else
|
||||
ptr[i] = static_cast<unsigned char>(cv::max(127, cv::min(ptr[i] + m_contrast, 255)));
|
||||
}
|
||||
float g = 1.0f / m_gamma;
|
||||
for (int i = 0; i < 256; i++)
|
||||
ptr[i] = static_cast<unsigned char>(cv::min(255, static_cast<int>(cv::pow(static_cast<float>(ptr[i]) / 255.0f, g) * 255.0f + 0.5f)));
|
||||
}
|
||||
|
|
|
@ -9,6 +9,11 @@ public:
|
|||
|
||||
CImageApplyAdjustColors(void);
|
||||
|
||||
/*
|
||||
* brightness [in]: 亮度调节,取值范围[-255, 255]
|
||||
* constrast [in]: 对比度调节,取值范围[-128, 127]
|
||||
* gamma [in]: 伽马调节,取值范围[0.1, 5.0]
|
||||
*/
|
||||
CImageApplyAdjustColors(int brightness, int contrast, float gamma);
|
||||
|
||||
virtual ~CImageApplyAdjustColors(void);
|
||||
|
|
|
@ -6,17 +6,19 @@ CImageApplyAutoCrop::CImageApplyAutoCrop()
|
|||
, m_isDesaskew(false)
|
||||
, m_isFillBlank(false)
|
||||
, m_isConvexHull(true)
|
||||
, m_isFillColor(false)
|
||||
, m_threshold(40)
|
||||
, m_noise(2)
|
||||
, m_indent(5)
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, double threshold, int noise, int indent)
|
||||
CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor, double threshold, int noise, int indent)
|
||||
: m_isCrop(isCrop)
|
||||
, m_isDesaskew(isDesaskew)
|
||||
, m_isFillBlank(isFillBlank)
|
||||
, m_isConvexHull(isConvex)
|
||||
, m_isFillColor(isFillColor)
|
||||
, m_threshold(threshold)
|
||||
, m_noise(noise)
|
||||
, m_indent(indent)
|
||||
|
@ -101,7 +103,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
|||
cv::Point(thre_dst.cols - 1, thre_dst.rows - 1), cv::Point(0, thre_dst.rows - 1) };
|
||||
std::vector<std::vector<cv::Point>> rectEdges{ rectEdge };
|
||||
cv::drawContours(thre_dst, rectEdges, 0, cv::Scalar::all(0));
|
||||
cv::Mat element = cv::getStructuringElement(cv::MorphShapes::MORPH_RECT, cv::Size(m_indent * 2, m_indent * 2));
|
||||
cv::Mat element = cv::getStructuringElement(cv::MorphShapes::MORPH_RECT, cv::Size(m_indent, m_indent));
|
||||
cv::erode(thre_dst, thre_dst, element, cv::Point(-1, -1), 1);
|
||||
}
|
||||
hierarchy.clear();
|
||||
|
@ -123,7 +125,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
|||
contours[contours.size() - 1].push_back(cv::Point(dst.cols, -1));
|
||||
contours[contours.size() - 1].push_back(cv::Point(dst.cols, dst.rows));
|
||||
|
||||
hg::fillPolys(dst, contours, cv::Scalar(255, 255, 255));
|
||||
hg::fillPolys(dst, contours, m_isFillColor ? getBackGroudColor(pDib, rect.size.area()) : cv::Scalar(255, 255, 255));
|
||||
}
|
||||
|
||||
pDib.release();
|
||||
|
@ -131,17 +133,6 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
|||
pDib = dst.clone();
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
if (m_isCrop && side == 1 && !m_fixedSize.empty())
|
||||
if (std::abs(m_fixedSize.width - dst.cols) > 50 || std::abs(m_fixedSize.height - dst.rows) > 50)
|
||||
{
|
||||
pDib = dst.clone();
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply");
|
||||
#endif // LOG
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0));
|
||||
|
||||
cv::Rect roi;
|
||||
|
@ -153,18 +144,7 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
|||
|
||||
for (cv::Point& p : m_maxContour)
|
||||
p += roi.tl();
|
||||
#if 0
|
||||
std::string outrectinfo = "copy to rect x: " + std::to_string(rect.x) + "y: " + std::to_string(rect.y) + "width: " + std::to_string(rect.width) + "height: " + std::to_string(rect.height);
|
||||
std::string outroiinfo = "roi x: " + std::to_string(roi.x) + "y: " + std::to_string(roi.y) + "width: " + std::to_string(roi.width) + "height: " + std::to_string(roi.height);
|
||||
std::string dstsize = "dst size: width:" + std::to_string(dst.cols) + "height: " + std::to_string(dst.rows);
|
||||
std::string pDibszie = "pDib size: width: " + std::to_string(pDib.cols) + "height: " + std::to_string(pDib.rows);
|
||||
FileTools::write_log("imgprc.txt", dstsize);
|
||||
FileTools::write_log("imgprc.txt", pDibszie);
|
||||
FileTools::write_log("imgprc.txt", outrectinfo);
|
||||
FileTools::write_log("imgprc.txt", outroiinfo);
|
||||
#endif // LOG
|
||||
dst(roi).copyTo(pDib(rect));
|
||||
|
||||
}
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply8");
|
||||
|
@ -191,3 +171,58 @@ void CImageApplyAutoCrop::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
m_fixedSize = dSize;
|
||||
}
|
||||
}
|
||||
|
||||
cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int total)
|
||||
{
|
||||
if (image.channels() == 3)
|
||||
{
|
||||
cv::Mat image_bgr[3];
|
||||
cv::split(image, image_bgr);
|
||||
|
||||
uchar bgr[3];
|
||||
for (size_t i = 0; i < 3; i++)
|
||||
bgr[i] = getBackGroudChannelMean(image_bgr[i], total);
|
||||
return cv::Scalar(bgr[0], bgr[1], bgr[2]);
|
||||
}
|
||||
else
|
||||
return cv::Scalar::all(getBackGroudChannelMean(image, total));
|
||||
}
|
||||
|
||||
uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int total)
|
||||
{
|
||||
cv::Mat image_clone;
|
||||
cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25);
|
||||
|
||||
int threnshold = total / 32;
|
||||
int channels[] = { 0 };
|
||||
int nHistSize[] = { 256 };
|
||||
float range[] = { 0, 256 };
|
||||
const float* fHistRanges[] = { range };
|
||||
cv::Mat hist;
|
||||
cv::calcHist(&image_clone, 1, channels, cv::Mat(), hist, 1, nHistSize, fHistRanges, true, false);
|
||||
|
||||
int hist_array[256];
|
||||
for (int i = 0; i < 256; i++)
|
||||
hist_array[i] = hist.at<float>(i, 0);
|
||||
|
||||
int length = 1;
|
||||
const int length_max = 255 - m_threshold;
|
||||
while (length < length_max)
|
||||
{
|
||||
for (size_t i = m_threshold + 1; i < 256 - length; i++)
|
||||
{
|
||||
int count = 0;
|
||||
uint pixSum = 0;
|
||||
for (size_t j = 0; j < length; j++)
|
||||
{
|
||||
count += hist_array[j + i];
|
||||
pixSum += hist_array[j + i] * (i + j);
|
||||
}
|
||||
|
||||
if (count >= threnshold)
|
||||
return pixSum / count;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
return 255;
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/21 v1.0
|
||||
2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用)
|
||||
2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度。
|
||||
2020/10/28 v1.2.1 修复凹凸多边形填充背景的逻辑BUG。
|
||||
2020/10/28 v1.2.2 修复图像处理必定会缩小尺寸的BUG。
|
||||
2020/10/29 v1.2.3 避免无谓的纠偏(0°纠偏)。
|
||||
2020/11/09 v1.2.4 避免无谓的处理(裁剪、纠偏、除黑底均为false)
|
||||
* 版本号:v1.2.4
|
||||
2020/7/22 v1.1 增加获取图像有效区域轮廓的接口maxContour(用于配合一体机的“跳过空白页”算法,PC端暂时无需使用)
|
||||
2020/10/16 v1.2 修复自动裁剪尺寸精度丢失的BUG;提高除黑底缩进精度。
|
||||
2020/10/28 v1.2.1 修复凹凸多边形填充背景的逻辑BUG。
|
||||
2020/10/28 v1.2.2 修复图像处理必定会缩小尺寸的BUG。
|
||||
2020/10/29 v1.2.3 避免无谓的纠偏(0°纠偏)
|
||||
2020/11/30 v1.3.0 增加功能,可识别文稿颜色进行填充黑底。
|
||||
* 版本号:v1.3.0
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -32,11 +32,12 @@ public:
|
|||
* isFillBlank [in]:黑底填充使能,true为填充,false为不填充
|
||||
* fixedSize [in]:固定幅面尺寸,当isCrop为false时生效,结果尺寸按fixedSize大小输出,单位像素
|
||||
* isConvex [in]:黑底填充时的填充方式,true为凸多边形填充,false为凹多边形填充,默认true
|
||||
* isFillColor [in]:黑底填充时采用自适应色彩填充,false为白色填充,true为自适应文稿底色填充,默认false
|
||||
* threshold [in]:二值化阈值,取值范围(0, 255),默认40
|
||||
* noise [in]:除噪像素,能够消除noise宽度的背景竖条纹干扰,默认40
|
||||
* indent [in]:轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默认5
|
||||
*/
|
||||
CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, double threshold = 40, int noise = 40, int indent = 5);
|
||||
CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, bool isFillColor = false, double threshold = 40, int noise = 40, int indent = 5);
|
||||
|
||||
virtual ~CImageApplyAutoCrop();
|
||||
|
||||
|
@ -78,11 +79,17 @@ public:
|
|||
|
||||
void setFixedSize(cv::Size size) { m_fixedSize = size; }
|
||||
|
||||
private:
|
||||
cv::Scalar getBackGroudColor(const cv::Mat& image, int total);
|
||||
|
||||
uchar getBackGroudChannelMean(const cv::Mat& gray, int total);
|
||||
|
||||
private:
|
||||
bool m_isCrop;
|
||||
bool m_isDesaskew;
|
||||
bool m_isFillBlank;
|
||||
bool m_isConvexHull;
|
||||
bool m_isFillColor;
|
||||
|
||||
double m_threshold;
|
||||
int m_noise;
|
||||
|
|
|
@ -36,10 +36,10 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
|||
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||||
|
||||
cv::Mat integ;
|
||||
int blockSize = 13;//ÁÚÓò³ß´ç
|
||||
int blockSize = 25;//ÁÚÓò³ß´ç
|
||||
int threshold = 1;
|
||||
int low = 110;
|
||||
int up = 230;
|
||||
int low = 30;
|
||||
int up = 235;
|
||||
int halfSize = blockSize / 2;
|
||||
int square_blockSize = blockSize * blockSize;
|
||||
switch (m_type)
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
* 功能:二值化处理
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/5/28 v1.1 修改传统二值化算法,改用自定义局部自适应阈值算法
|
||||
2020/5/29 v1.2 在传统二值化之前添加增强锐化效果,二值化之后增加除噪效果
|
||||
2020/6/19 v1.3 编写自定义自适应阈值二值化;取消锐化处理;保留除噪效果
|
||||
* 版本号:v1.3
|
||||
* 最近修改时间:2020/5/28 v1.1 修改传统二值化算法,改用自定义局部自适应阈值算法
|
||||
2020/5/29 v1.2 在传统二值化之前添加增强锐化效果,二值化之后增加除噪效果
|
||||
2020/6/19 v1.3 编写自定义自适应阈值二值化;取消锐化处理;保留除噪效果
|
||||
2020/12/21 v1.3.1 调整自适应阈值上下限
|
||||
2020/12/21 v1.3.2 调整blockSize,从原来的51调整到25
|
||||
* 版本号:v1.3.2
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
|
|
@ -1,49 +1,43 @@
|
|||
#include "ImageApplyChannel.h"
|
||||
//#include "ImageApplyAdjustColors.h"
|
||||
#include "ImageApplyAdjustColors.h"
|
||||
|
||||
CImageApplyChannel::CImageApplyChannel()
|
||||
: m_channel(Invalid)
|
||||
//, colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||
, colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyChannel::CImageApplyChannel(Channel channel)
|
||||
: m_channel(channel)
|
||||
//,colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||
, colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyChannel::~CImageApplyChannel(void)
|
||||
CImageApplyChannel::~CImageApplyChannel()
|
||||
{
|
||||
//if (colors != NULL)
|
||||
//delete colors;
|
||||
if (colors != nullptr) delete colors;
|
||||
}
|
||||
|
||||
void CImageApplyChannel::apply(cv::Mat& pDib,int side)
|
||||
{
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "enter CImageApplyChannel apply");
|
||||
#endif // LOG
|
||||
|
||||
if (pDib.empty())
|
||||
{
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyChannel apply");
|
||||
#endif // LOG
|
||||
return;
|
||||
}
|
||||
(void)side;
|
||||
if (pDib.empty()) return;
|
||||
|
||||
cv::Mat dst(pDib.rows, pDib.cols, CV_8UC1);
|
||||
switch (m_channel)
|
||||
{
|
||||
case Red:
|
||||
cv::extractChannel(pDib, dst, 2);
|
||||
//colors->apply(pDib, side);
|
||||
colors->apply(pDib, side);
|
||||
break;
|
||||
case Green:
|
||||
cv::extractChannel(pDib, dst, 1);
|
||||
break;
|
||||
case Blue:
|
||||
cv::extractChannel(pDib, dst, 0);
|
||||
break;
|
||||
case All:
|
||||
colourless(pDib, dst, 80);
|
||||
break;
|
||||
case Except_Red:
|
||||
except_channel(pDib, dst, 2);
|
||||
|
@ -66,21 +60,20 @@ void CImageApplyChannel::apply(cv::Mat& pDib,int side)
|
|||
|
||||
void CImageApplyChannel::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
{
|
||||
if (mats.empty()) return;
|
||||
|
||||
if (!mats[0].empty()) {
|
||||
apply(mats[0], 0);
|
||||
}
|
||||
|
||||
if (isTwoSide && mats.size() > 1) {
|
||||
if (!mats[1].empty())
|
||||
apply(mats[1], 1);
|
||||
(void)isTwoSide;
|
||||
int i = 0;
|
||||
for (cv::Mat& var : mats) {
|
||||
if (i != 0 && isTwoSide == false)
|
||||
break;
|
||||
if (!var.empty())
|
||||
apply(var, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyChannel::except_channel(const cv::Mat & src, cv::Mat & dst, int channel)
|
||||
{
|
||||
int rows = src.total();
|
||||
int rows = static_cast<int>(src.total());
|
||||
cv::Mat src_temp(rows, 3, CV_8UC1, src.data);
|
||||
cv::Mat dst_temp(rows, 1, CV_8UC1, dst.data);
|
||||
|
||||
|
@ -90,19 +83,45 @@ void CImageApplyChannel::except_channel(const cv::Mat & src, cv::Mat & dst, int
|
|||
case 0:
|
||||
temp1 = src_temp(cv::Rect(1, 0, 1, rows));
|
||||
temp2 = src_temp(cv::Rect(2, 0, 1, rows));
|
||||
cv::addWeighted(temp1, 0.84, temp2, 0.16, 0, dst_temp);
|
||||
cv::addWeighted(temp1, 0.587, temp2, 0.299, 0, dst_temp);
|
||||
break;
|
||||
case 1:
|
||||
temp1 = src_temp(cv::Rect(0, 0, 1, rows));
|
||||
temp2 = src_temp(cv::Rect(2, 0, 1, rows));
|
||||
cv::addWeighted(temp1, 0.73, temp2, 0.27, 0, dst_temp);
|
||||
cv::addWeighted(temp1, 0.114, temp2, 0.299, 0, dst_temp);
|
||||
break;
|
||||
case 2:
|
||||
temp1 = src_temp(cv::Rect(0, 0, 1, rows));
|
||||
temp2 = src_temp(cv::Rect(1, 0, 1, rows));
|
||||
cv::addWeighted(temp1, 0.33, temp2, 0.67, 0, dst_temp);
|
||||
cv::addWeighted(temp1, 0.114, temp2, 0.587, 0, dst_temp);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CImageApplyChannel::colourless(const cv::Mat &src, cv::Mat &dst, uchar threshold)
|
||||
{
|
||||
if (src.channels() != 3)
|
||||
{
|
||||
dst = src;
|
||||
return;
|
||||
}
|
||||
|
||||
cv::Mat hsv;
|
||||
cv::cvtColor(src, hsv, cv::COLOR_BGR2HSV_FULL);
|
||||
cv::Mat mv_hsv[3];
|
||||
cv::split(hsv, mv_hsv);
|
||||
size_t total = mv_hsv[1].total();
|
||||
uchar* ptr_s = mv_hsv[1].data;
|
||||
uchar* ptr_v = mv_hsv[2].data;
|
||||
for (size_t i = 0; i < total; i++)
|
||||
if (ptr_s[i] > threshold)
|
||||
{
|
||||
ptr_s[i] = 0;
|
||||
ptr_v[i] = 255;
|
||||
}
|
||||
cv::merge(mv_hsv, 3, hsv);
|
||||
cv::cvtColor(hsv, hsv, cv::COLOR_HSV2BGR_FULL);
|
||||
cv::cvtColor(hsv, dst, cv::COLOR_BGR2GRAY);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
#ifndef IMAGE_APPLY_CHANNEL_H
|
||||
#define IMAGE_APPLY_CHANNEL_H
|
||||
|
||||
#include "imageapply.h"
|
||||
//class CImageApplyAdjustColors;
|
||||
class CImageApplyChannel : public CImageApply
|
||||
#include "ImageApply.h"
|
||||
|
||||
class CImageApplyAdjustColors;
|
||||
class CImageApplyChannel : public CImageApply
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum channel
|
||||
{
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
Invalid,
|
||||
Except_Red,
|
||||
Except_Green,
|
||||
Except_Blue
|
||||
Red, //红色通道
|
||||
Green, //绿色通道
|
||||
Blue, //蓝色通道
|
||||
All, //去除所有HSV色彩结构中,S大于80的色彩
|
||||
Invalid, //无效
|
||||
Except_Red, //绿蓝色通道混合
|
||||
Except_Green, //红蓝色通道混合
|
||||
Except_Blue //红绿色通道混合
|
||||
}Channel;
|
||||
|
||||
public:
|
||||
|
@ -34,10 +36,12 @@ private:
|
|||
|
||||
void except_channel(const cv::Mat& src, cv::Mat& dst, int channel);
|
||||
|
||||
void colourless(const cv::Mat& src, cv::Mat& dst, uchar threshold = 80);
|
||||
|
||||
private:
|
||||
|
||||
Channel m_channel;
|
||||
//CImageApplyAdjustColors* colors;
|
||||
CImageApplyAdjustColors* colors;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_CHANNEL_H
|
|
@ -28,7 +28,7 @@ bool isColor(const cv::Mat& image)
|
|||
cv::inRange(hsv_channels[2], 100, 255, range_v);
|
||||
|
||||
cv::Mat thre = (range_h1 | range_h2) & range_s & range_v;
|
||||
return cv::sum(thre)[0] > 4;
|
||||
return (cv::sum(thre)[0] / 255)> 4;
|
||||
}
|
||||
|
||||
bool isGray(const cv::Mat& image)
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
|
||||
CImageApplyConcatenation::CImageApplyConcatenation()
|
||||
: m_direction(autoDirection)
|
||||
, m_BG_color(0, 0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyConcatenation::CImageApplyConcatenation(ConcatMode dir)
|
||||
CImageApplyConcatenation::CImageApplyConcatenation(ConcatMode dir, const cv::Scalar& background)
|
||||
: m_direction(dir)
|
||||
, m_BG_color(background)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,6 +46,7 @@ cv::Mat CImageApplyConcatenation::concat(cv::Mat &front, cv::Mat &back, ConcatMo
|
|||
cv::Mat dst;
|
||||
if (direction == horizontal)
|
||||
{
|
||||
#if 0
|
||||
int top, bottom;
|
||||
if (front.rows > back.rows)
|
||||
{
|
||||
|
@ -58,9 +61,21 @@ cv::Mat CImageApplyConcatenation::concat(cv::Mat &front, cv::Mat &back, ConcatMo
|
|||
cv::copyMakeBorder(front, front, top, bottom, 0, 0, cv::BORDER_CONSTANT);
|
||||
}
|
||||
cv::hconcat(front, back, dst);
|
||||
#else
|
||||
int width = cv::max(front.cols, back.cols) * 2;
|
||||
int height = cv::max(front.rows, back.rows);
|
||||
|
||||
dst = cv::Mat(height, width, front.type(), m_BG_color);
|
||||
front.copyTo(dst(cv::Rect(0, 0, front.cols, front.rows)));
|
||||
int offset = front.cols;
|
||||
front.release();
|
||||
back.copyTo(dst(cv::Rect(offset, 0, back.cols, back.rows)));
|
||||
back.release();
|
||||
#endif
|
||||
}
|
||||
else if (direction == vertical)
|
||||
{
|
||||
#if 0
|
||||
int left, right;
|
||||
if (front.cols > back.cols)
|
||||
{
|
||||
|
@ -75,6 +90,17 @@ cv::Mat CImageApplyConcatenation::concat(cv::Mat &front, cv::Mat &back, ConcatMo
|
|||
cv::copyMakeBorder(front, front, 0, 0, left, right, cv::BORDER_CONSTANT);
|
||||
}
|
||||
cv::vconcat(front, back, dst);
|
||||
#else
|
||||
int width = cv::max(front.cols, back.cols);
|
||||
int height = cv::max(front.rows, back.rows) * 2;
|
||||
|
||||
dst = cv::Mat(height, width, front.type(), m_BG_color);
|
||||
front.copyTo(dst(cv::Rect(0, 0, front.cols, front.rows)));
|
||||
int offset = front.rows;
|
||||
front.release();
|
||||
back.copyTo(dst(cv::Rect(0, offset, back.cols, back.rows)));
|
||||
back.release();
|
||||
#endif
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:拼接,又名对折
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/29
|
||||
* 版本号:v1.0 2020/4/21
|
||||
* 版本号:v1.1 2020/4/29 : 1、添加m_BG_color接口,可设置图片背景;2、优化内存消耗
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_APPLY_CONCATENATION_H
|
||||
#define IMAGE_APPLY_CONCATENATION_H
|
||||
|
||||
|
@ -17,15 +29,23 @@ public:
|
|||
public:
|
||||
CImageApplyConcatenation(); //ĬÈÏm_direction = autoDirection;
|
||||
|
||||
CImageApplyConcatenation(ConcatMode dir);
|
||||
/*
|
||||
* dir [in]:拼接方向
|
||||
* backgroud [in]:背景颜色,默认为黑色
|
||||
* */
|
||||
CImageApplyConcatenation(ConcatMode dir, const cv::Scalar& backgroud = cv::Scalar(0, 0, 0));
|
||||
|
||||
virtual ~CImageApplyConcatenation(void);
|
||||
|
||||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
inline ConcatMode getConcatDirection() { return m_direction; }
|
||||
inline ConcatMode getConcatDirection() { return m_direction; }
|
||||
|
||||
inline void setFildDirection(ConcatMode dir) { m_direction = dir; }
|
||||
inline void setFildDirection(ConcatMode dir) { m_direction = dir; }
|
||||
|
||||
inline cv::Scalar getBackGroundColor() const { return m_BG_color; }
|
||||
|
||||
inline void setBackGroundColor(const cv::Scalar& color) { m_BG_color = color; }
|
||||
|
||||
private:
|
||||
|
||||
|
@ -35,6 +55,7 @@ private:
|
|||
|
||||
private:
|
||||
ConcatMode m_direction;
|
||||
cv::Scalar m_BG_color;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_CONCATENATION_H
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
#include "ImageApplyDiscardBlank.h"
|
||||
#include "ImageProcess_Public.h"
|
||||
#include "filetools.h"
|
||||
CImageApplyDiscardBlank::CImageApplyDiscardBlank(int blockSize, int devTh)
|
||||
: m_res(false)
|
||||
, m_dSize(blockSize)
|
||||
, m_devTh(devTh)
|
||||
{
|
||||
}
|
||||
CImageApplyDiscardBlank::CImageApplyDiscardBlank()
|
||||
: m_res(false)
|
||||
, dSize(200)
|
||||
, devTh(15, 15, 15, 15)
|
||||
, m_dSize(200)
|
||||
, m_devTh(15, 15, 15, 15)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -95,8 +101,8 @@ int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect&
|
|||
|
||||
void CImageApplyDiscardBlank::setIntensity(int val)
|
||||
{
|
||||
val = cv::max(cv::min(100, val), 1);
|
||||
devTh = cv::Scalar(val, val, val, val);
|
||||
val = cv::max(cv::min(100, val), 2);
|
||||
m_devTh = cv::Scalar::all(val);
|
||||
}
|
||||
|
||||
cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image)
|
||||
|
@ -107,12 +113,14 @@ cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image)
|
|||
double scale = 0.25;
|
||||
double thresh = 50;
|
||||
int blobSize = 200;
|
||||
int edgeWidth = 10;
|
||||
processRectR(image, rect, contour, scale, thresh, blobSize);
|
||||
cv::Rect rect2 = rect.boundingRect();
|
||||
cv::Rect inRect = rect2 & cv::Rect(0, 0, image.cols, image.rows);
|
||||
gap = cv::max(inRect.width - rect.size.width, inRect.height - rect.size.height) + 20;
|
||||
gap = cv::max(inRect.width - rect.size.width, inRect.height - rect.size.height) + 100;
|
||||
inRect = cv::Rect(inRect.x + gap, inRect.y + gap, inRect.width - gap * 2, inRect.height - gap * 2);
|
||||
|
||||
if (inRect.width <= 0 || inRect.height <= 0)
|
||||
return cv::Mat();
|
||||
return image(inRect);
|
||||
}
|
||||
|
||||
|
@ -135,18 +143,18 @@ void CImageApplyDiscardBlank::apply(cv::Mat& pDib, int side)
|
|||
cv::Mat image = getRoiMat(pDib);
|
||||
cv::Rect rect;
|
||||
cv::Rect imRect(0, 0, image.cols, image.rows);
|
||||
for(int i = 0; i < image.cols; i+= dSize)
|
||||
for(int j = 0; j < image.rows; j+= dSize)
|
||||
for(int i = 0; i < image.cols; i+= m_dSize)
|
||||
for(int j = 0; j < image.rows; j+= m_dSize)
|
||||
{
|
||||
rect = cv::Rect(i, j,dSize, dSize) & imRect;
|
||||
rect = cv::Rect(i, j, m_dSize, m_dSize) & imRect;
|
||||
if(rect != cv::Rect())
|
||||
{
|
||||
cv::meanStdDev (image(rect) , mean, dev);
|
||||
if(!scalar_LE(dev, devTh))
|
||||
if(!scalar_LE(dev, m_devTh))
|
||||
{
|
||||
m_res = false;
|
||||
#ifdef LOG
|
||||
FileTools::write_log("D:\\imgprc.txt", "CImageApplyDiscardBlank blank");
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply");
|
||||
#endif // LOG
|
||||
return;
|
||||
}
|
||||
|
@ -172,3 +180,30 @@ void CImageApplyDiscardBlank::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, int blockSize, int devTh)
|
||||
{
|
||||
if (pDib.empty())
|
||||
return true;
|
||||
|
||||
cv::Scalar mean;
|
||||
cv::Scalar dev;
|
||||
cv::Scalar s_devTh = cv::Scalar::all(devTh);
|
||||
cv::Mat image = getRoiMat(pDib);
|
||||
if (image.empty())
|
||||
return false;
|
||||
cv::Rect rect;
|
||||
cv::Rect imRect(0, 0, image.cols, image.rows);
|
||||
for (int i = 0; i < image.cols; i += blockSize)
|
||||
for (int j = 0; j < image.rows; j += blockSize)
|
||||
{
|
||||
rect = cv::Rect(i, j, blockSize, blockSize) & imRect;
|
||||
if (rect != cv::Rect())
|
||||
{
|
||||
cv::meanStdDev(image(rect), mean, dev);
|
||||
if (!scalar_LE(dev, s_devTh))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
class CImageApplyDiscardBlank : public CImageApply
|
||||
{
|
||||
public:
|
||||
CImageApplyDiscardBlank(int blockSize, int devTh);
|
||||
|
||||
/*
|
||||
* isnormal [in]:true标准模式,false为票据复写纸模式
|
||||
* */
|
||||
|
@ -32,21 +34,23 @@ public:
|
|||
|
||||
void setIntensity(int val);
|
||||
|
||||
void setMinArea(int val) { dSize = val; }
|
||||
void setMinArea(int val) { m_dSize = val; }
|
||||
|
||||
static bool apply(const cv::Mat& pDib, int blockSize = 200, int devTh = 15);
|
||||
|
||||
private:
|
||||
|
||||
int processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect, std::vector<cv::Point>& maxContour,
|
||||
static int processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect, std::vector<cv::Point>& maxContour,
|
||||
double scale, double thresh, int blobAreaSize);
|
||||
|
||||
bool scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2);
|
||||
static bool scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2);
|
||||
|
||||
cv::Mat getRoiMat(const cv::Mat& pDib);
|
||||
static cv::Mat getRoiMat(const cv::Mat& pDib);
|
||||
private:
|
||||
bool m_res;
|
||||
bool isNormalDiscard;
|
||||
int dSize;
|
||||
cv::Scalar devTh;
|
||||
bool m_isNormalDiscard;
|
||||
int m_dSize;
|
||||
cv::Scalar m_devTh;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_DISCARD_BLANK_H
|
|
@ -25,7 +25,11 @@ CImageOutHole::~CImageOutHole(void)
|
|||
{
|
||||
}
|
||||
|
||||
void CImageOutHole::apply(cv::Mat& pDib, int side) {}
|
||||
void CImageOutHole::apply(cv::Mat& pDib, int side)
|
||||
{
|
||||
(void)pDib;
|
||||
(void)side;
|
||||
}
|
||||
|
||||
void CImageOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
{
|
||||
|
@ -99,8 +103,8 @@ void CImageOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
|||
|
||||
//过滤非孔洞的联通区域
|
||||
std::vector<std::vector<cv::Point>> hole_contours = filterPoly(contours_mask, b1_mask, mask_rotatedRect, m_edgeScale, m_borderSize);
|
||||
for (int i = 0; i < hole_contours.size(); i++)
|
||||
cv::drawContours(mask, hole_contours, i, cv::Scalar(127), 2);
|
||||
for (size_t i = 0; i < hole_contours.size(); i++)
|
||||
cv::drawContours(mask, hole_contours, static_cast<int>(i), cv::Scalar(127), 2);
|
||||
|
||||
for (size_t i = 0; i < hole_contours.size(); i++)
|
||||
{
|
||||
|
@ -247,5 +251,7 @@ cv::Scalar CImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vec
|
|||
temp[j] += ptr[j];
|
||||
}
|
||||
|
||||
return cv::Scalar(temp[0] / pixelPoints.size(), temp[1] / pixelPoints.size(), temp[2] / pixelPoints.size());
|
||||
return cv::Scalar(temp[0] / static_cast<int>(pixelPoints.size()),
|
||||
temp[1] / static_cast<int>(pixelPoints.size()),
|
||||
temp[2] / static_cast<int>(pixelPoints.size()));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
|
||||
void setEdgeScale(float scale) { m_edgeScale = scale; }
|
||||
|
||||
void setThreshold(double threshold) { m_threshold = std::min(std::max(threshold, 1.0), 254.0); }
|
||||
void setThreshold(double threshold) { m_threshold = (std::min)((std::max)(threshold, 1.0), 254.0); }
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -23,37 +23,25 @@ CImageApplyResize::~CImageApplyResize(void)
|
|||
|
||||
void CImageApplyResize::apply(cv::Mat& pDib,int side)
|
||||
{
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "enter CImageApplyResize apply");
|
||||
#endif // LOG
|
||||
|
||||
if (pDib.empty())
|
||||
{
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyResize apply");
|
||||
#endif // LOG
|
||||
return;
|
||||
}
|
||||
(void)side;
|
||||
if (pDib.empty()) return;
|
||||
|
||||
if (m_type == ResizeType::RATIO)
|
||||
cv::resize(pDib, pDib, cv::Size(0, 0), m_fx, m_fy);
|
||||
else
|
||||
cv::resize(pDib, pDib, m_dSize);
|
||||
#ifdef LOG
|
||||
FileTools::write_log("imgprc.txt", "exit CImageApplyResize apply");
|
||||
#endif // LOG
|
||||
cv::resize(pDib, pDib, m_dSize);
|
||||
}
|
||||
|
||||
void CImageApplyResize::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||
{
|
||||
if (mats.empty()) return;
|
||||
(void)isTwoSide;
|
||||
|
||||
if (!mats[0].empty()) {
|
||||
apply(mats[0], 0);
|
||||
}
|
||||
|
||||
if (isTwoSide && mats.size() > 1) {
|
||||
if (!mats[1].empty())
|
||||
apply(mats[1], 1);
|
||||
int i = 0;
|
||||
for (cv::Mat& var : mats) {
|
||||
if (i != 0 && isTwoSide == false)
|
||||
break;
|
||||
if (!var.empty())
|
||||
apply(var, 0);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,12 @@ public:
|
|||
public:
|
||||
CImageApplyResize();
|
||||
|
||||
/*
|
||||
* type [in]:缩放类型
|
||||
* size [in]:目标尺寸,当type为DSIZE时生效
|
||||
* fx [in]:横向目标比例,当type为RATIO时生效
|
||||
* fy [in]:纵向目标比例,当type为RATIO时生效
|
||||
*/
|
||||
CImageApplyResize(ResizeType type, const cv::Size& size, double fx, double fy);
|
||||
|
||||
virtual ~CImageApplyResize(void);
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:旋转图像
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:v1.0 2020/4/21
|
||||
v1.1 2020/8/12 修复文稿方向自动识别导致崩溃的BUG
|
||||
* 版本号:v1.1
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_APPLY_ROTATION_H
|
||||
#define IMAGE_APPLY_ROTATION_H
|
||||
|
||||
|
@ -8,16 +21,22 @@ class CImageApplyRotation : public CImageApply
|
|||
public:
|
||||
enum class RotationType
|
||||
{
|
||||
Invalid,
|
||||
Rotate_90_clockwise,
|
||||
Rotate_180,
|
||||
Rotate_90_anti_clockwise,
|
||||
Invalid, //无效
|
||||
Rotate_90_clockwise, //顺时针90°
|
||||
Rotate_180, //180°
|
||||
Rotate_90_anti_clockwise, //逆时针90°,即270°
|
||||
|
||||
AutoTextOrientation
|
||||
AutoTextOrientation //自动文稿方向识别旋转
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* rotation [in]:旋转类型
|
||||
* isBackTransposed [in]:true为背面180°旋转,反之亦然
|
||||
* dpi [in]:当前图像的DPI,该参数在rotation为AutoTextOrientation时生效。在识别文稿方向时,会默认将图像变换为200DPI进行识别
|
||||
* tessadataPath [in]:训练库文件路径,该参数在rotation为AutoTextOrientation时生效
|
||||
*/
|
||||
CImageApplyRotation(RotationType rotation, bool isBackTransposed = false, int dpi = 200, const char* tessdataPath = nullptr);
|
||||
|
||||
virtual ~CImageApplyRotation();
|
||||
|
|
|
@ -21,8 +21,7 @@ namespace hg
|
|||
|
||||
//dst
|
||||
dst.clear();
|
||||
int hullCount = hull->total;
|
||||
for (int i = 0; i < hullCount; i++)
|
||||
for (int i = 0, hullCount = hull->total; i < hullCount; i++)
|
||||
dst.push_back(**CV_GET_SEQ_ELEM(CvPoint*, hull, i));
|
||||
|
||||
//storage
|
||||
|
@ -297,7 +296,7 @@ namespace hg
|
|||
cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY);
|
||||
}
|
||||
|
||||
cv::Point warpPoint(cv::Point p, const cv::Mat& warp_mat)
|
||||
cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat)
|
||||
{
|
||||
double src_data[3] = { static_cast<double>(p.x), static_cast<double>(p.y), 1 };
|
||||
cv::Mat src(3, 1, warp_mat.type(), src_data); //warp_mat.type() == CV_64FC1
|
||||
|
@ -306,4 +305,20 @@ namespace hg
|
|||
double* ptr = reinterpret_cast<double*>(dst.data);
|
||||
return cv::Point(static_cast<int>(ptr[0]), static_cast<int>(ptr[1]));
|
||||
}
|
||||
|
||||
int distanceP2P(const cv::Point& p1, const cv::Point& p2)
|
||||
{
|
||||
return cv::sqrt(cv::pow(p1.x - p2.x, 2) + cv::pow(p1.y - p2.y, 2));
|
||||
}
|
||||
|
||||
float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2)
|
||||
{
|
||||
//求直线方程
|
||||
int A = 0, B = 0, C = 0;
|
||||
A = l1.y - l2.y;
|
||||
B = l2.x - l1.x;
|
||||
C = l1.x * l2.y - l1.y * l2.x;
|
||||
//代入点到直线距离公式
|
||||
return ((float)abs(A * p.x + B * p.y + C)) / ((float)sqrtf(A * A + B * B));
|
||||
}
|
||||
}
|
|
@ -1,3 +1,15 @@
|
|||
/*
|
||||
* ====================================================
|
||||
|
||||
* 功能:公共图像处理算法。部分功能可能会在ImageProcess里面多个类反复使用
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:2020/4/21
|
||||
* 版本号:v1.0
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#ifndef IMAGE_PROCESS_PUBLIC_H
|
||||
#define IMAGE_PROCESS_PUBLIC_H
|
||||
|
||||
|
@ -6,28 +18,106 @@
|
|||
|
||||
namespace hg
|
||||
{
|
||||
/*
|
||||
* 功能:计算源点集的凸多边形轮廓,输出轮廓点集
|
||||
* src: 源点集
|
||||
* dst: 目标点集
|
||||
* clockwise: true为顺时针排序,false为逆时针排序
|
||||
*/
|
||||
void convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise = false);
|
||||
|
||||
/*
|
||||
* 功能:填充凸多边形,默认颜色为白色
|
||||
* image: 填充图像
|
||||
* points: 凸多边形轮廓点集(逆时针排序)
|
||||
*/
|
||||
void fillConvexHull(cv::Mat& image, const std::vector<cv::Point>& points);
|
||||
|
||||
/*
|
||||
* 功能:填充凹多边形
|
||||
* image: 填充图像
|
||||
* contours: 凹多边形轮廓点集(逆时针排序)
|
||||
* color: 填充颜色
|
||||
*/
|
||||
void fillPolys(cv::Mat& image, const std::vector<std::vector<cv::Point>>& contours, const cv::Scalar& color);
|
||||
|
||||
/*
|
||||
* 功能:获取连通区域轮廓
|
||||
* src: 源图像
|
||||
* contours: 结果轮廓集
|
||||
* hierarchy: 轮廓集的排序关系。与contours的数量对应,受retr选项不同,排序会有变化
|
||||
* retr: 轮廓集排序方式,默认为链式排序
|
||||
* method: 查找算法选择,默认为普通查找
|
||||
* offset: 查找起始点,默认为(0,0)点
|
||||
*/
|
||||
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
|
||||
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
|
||||
|
||||
cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour);
|
||||
|
||||
/*
|
||||
* 功能: 获取覆盖轮廓集的最小外接凸多边形轮廓
|
||||
* contours: 轮廓集(每个轮廓由点集组成)
|
||||
* hierarchy: 轮廓集中,轮廓之间的关系。数量与contours对应
|
||||
* 返回值: 凸多边形轮廓点集
|
||||
*/
|
||||
std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy);
|
||||
|
||||
/*
|
||||
* 功能: 获取覆盖轮廓集的最小外接凸多边形轮廓
|
||||
* contours: 轮廓集(每个轮廓由点集组成)
|
||||
* hierarchy: 轮廓集中,轮廓之间的关系。数量与contours对应
|
||||
* 返回值: 凸多边形轮廓点集
|
||||
*/
|
||||
std::vector<cv::Point> getVertices(const cv::RotatedRect& rect);
|
||||
|
||||
/*
|
||||
* 功能: 轮廓缩进
|
||||
* points: 轮廓点集
|
||||
* center: 围绕center点缩进
|
||||
* indent: 缩进像素
|
||||
*/
|
||||
void polyIndent(std::vector<cv::Point>& points, const cv::Point& center, int indent);
|
||||
|
||||
/*
|
||||
* 功能: 二值化,能够处理彩色和灰度图像。src为彩色图像时,灰度图取三个通道的最大值
|
||||
* src: 源图
|
||||
* dst: 目标图
|
||||
* thre: 阈值
|
||||
*/
|
||||
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre);
|
||||
|
||||
/*
|
||||
* 功能: 彩色转灰度,灰度图取三个通道的最大值
|
||||
* src: 源图
|
||||
* 返回值: 灰度图
|
||||
*/
|
||||
cv::Mat transforColor(const cv::Mat& src);
|
||||
|
||||
cv::Point warpPoint(cv::Point p, const cv::Mat& warp_mat);
|
||||
/*
|
||||
* 功能: 获取点的仿射变换
|
||||
* p: 原点
|
||||
* warp_mat: 仿射变换系数矩阵
|
||||
* 返回值: 变换后的点
|
||||
*/
|
||||
cv::Point warpPoint(const cv::Point& p, const cv::Mat& warp_mat);
|
||||
|
||||
/*
|
||||
* 功能: 点到点距离
|
||||
* p1: 点1
|
||||
* p2: 点2
|
||||
* 返回值: 点到点距离
|
||||
*/
|
||||
int distanceP2P(const cv::Point& p1, const cv::Point& p2);
|
||||
|
||||
/*
|
||||
* 功能: 点到直线距离
|
||||
* p: 点
|
||||
* l1: 直线端点1
|
||||
* l2: 直线端点2
|
||||
* 返回值: 点到直线距离
|
||||
*/
|
||||
float distanceP2L(const cv::Point& p, const cv::Point& l1, const cv::Point& l2);
|
||||
}
|
||||
|
||||
#endif // !IMAGE_PROCESS_C_H
|
||||
|
|
|
@ -70,7 +70,7 @@ using namespace std::placeholders;
|
|||
TWPP_ENTRY_MFC(HuagaoDs)
|
||||
|
||||
static constexpr const Identity srcIdent(
|
||||
Version(3, 3, Language::English, Country::China, "v3.3.2.4"),
|
||||
Version(3, 3, Language::English, Country::China, "v3.3.4.1"),
|
||||
DataGroup::Image,
|
||||
#ifdef MAKEHUAGAO
|
||||
"HUAGO",
|
||||
|
@ -2919,6 +2919,8 @@ Twpp::Result HuagaoDs::startScan()
|
|||
|
||||
scanner->ResetScanner();
|
||||
std::string info = "\n m_scanparam->is_autocrop :" + to_string(m_scanparam->is_autocrop);
|
||||
info += "\n m_scanparam->colorenable :" + to_string(m_scanparam->automaticcolor);
|
||||
info += "\n m_scanparam->colorenabletype :" + to_string(m_scanparam->automaticcolortype);
|
||||
info += "\n m_scanparam->papertype :" + to_string(m_scanparam->papertype);
|
||||
info += "\n m_scanparam->fillbackground :" + to_string(m_scanparam->fillbackground);
|
||||
info += "\n m_scanparam->autodescrew :" + to_string(m_scanparam->autodescrew);
|
||||
|
|
BIN
huagao/stdafx.h
BIN
huagao/stdafx.h
Binary file not shown.
Loading…
Reference in New Issue