mirror of http://192.168.1.51:8099/lmh188/twain3.0
修改UVTwain 背景黑色情况下裁切异常问题
This commit is contained in:
parent
90f0c0935c
commit
4b729a4585
|
@ -1,13 +1,12 @@
|
||||||
#include "ImageApplyAutoCrop.h"
|
#include "ImageApplyAutoCrop.h"
|
||||||
#include "ImageProcess_Public.h"
|
#include "ImageProcess_Public.h"
|
||||||
|
|
||||||
#define RE 2
|
|
||||||
|
|
||||||
CImageApplyAutoCrop::CImageApplyAutoCrop()
|
CImageApplyAutoCrop::CImageApplyAutoCrop()
|
||||||
: m_isCrop(false)
|
: m_isCrop(false)
|
||||||
, m_isDesaskew(false)
|
, m_isDesaskew(false)
|
||||||
, m_isFillBlank(false)
|
, m_isFillBlank(false)
|
||||||
, m_isConvexHull(true)
|
, m_isConvexHull(true)
|
||||||
|
, m_isFillColor(false)
|
||||||
, m_threshold(40)
|
, m_threshold(40)
|
||||||
, m_noise(2)
|
, m_noise(2)
|
||||||
, m_indent(5)
|
, m_indent(5)
|
||||||
|
@ -19,6 +18,7 @@ CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFi
|
||||||
, m_isDesaskew(isDesaskew)
|
, m_isDesaskew(isDesaskew)
|
||||||
, m_isFillBlank(isFillBlank)
|
, m_isFillBlank(isFillBlank)
|
||||||
, m_isConvexHull(isConvex)
|
, m_isConvexHull(isConvex)
|
||||||
|
, m_isFillColor(false)
|
||||||
, m_threshold(threshold)
|
, m_threshold(threshold)
|
||||||
, m_noise(noise)
|
, m_noise(noise)
|
||||||
, m_indent(indent)
|
, m_indent(indent)
|
||||||
|
@ -32,45 +32,27 @@ CImageApplyAutoCrop::~CImageApplyAutoCrop()
|
||||||
|
|
||||||
void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
||||||
{
|
{
|
||||||
#ifdef LOG
|
(void)side;
|
||||||
FileTools::write_log("imgprc.txt", "enter CImageApplyAutoCrop apply");
|
if (pDib.empty()) return;
|
||||||
#endif // LOG
|
if (!m_isCrop && !m_isDesaskew && !m_isFillBlank && m_fixedSize.empty()) return;
|
||||||
if (pDib.empty())
|
|
||||||
{
|
|
||||||
#ifdef LOG
|
|
||||||
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply");
|
|
||||||
#endif // LOG
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat src = pDib;
|
cv::Mat src = pDib;
|
||||||
|
cv::Mat thre;
|
||||||
cv::Mat dst;
|
cv::Mat dst;
|
||||||
cv::Mat src_resize;
|
hg::threshold_Mat(src, thre, m_threshold);
|
||||||
cv::resize(src, src_resize, cv::Size(src.cols / RE, src.rows / RE));
|
|
||||||
cv::Mat scale_mat;
|
|
||||||
cv::Mat thre(src_resize.size(), CV_8UC1);
|
|
||||||
hg::threshold_Mat(src_resize, thre, m_threshold);
|
|
||||||
src_resize.release();
|
|
||||||
|
|
||||||
if (m_noise > RE)
|
if (m_noise > 0)
|
||||||
{
|
{
|
||||||
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise / RE, m_noise / RE));
|
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise, m_noise));
|
||||||
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element);
|
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element);
|
||||||
element.release();
|
|
||||||
}
|
}
|
||||||
std::vector<cv::Vec4i> hierarchy;
|
std::vector<cv::Vec4i> hierarchy;
|
||||||
std::vector<std::vector<cv::Point>> contours;
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
|
||||||
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
|
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
|
||||||
std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
|
m_maxContour = hg::getMaxContour(contours, hierarchy);
|
||||||
|
|
||||||
for (cv::Point& item : maxContour)
|
if (m_maxContour.size() == 0)
|
||||||
{
|
|
||||||
item.x = item.x * RE - RE / 2;
|
|
||||||
item.y = item.y * RE - RE / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxContour.size() == 0)
|
|
||||||
{
|
{
|
||||||
thre.release();
|
thre.release();
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
|
@ -81,68 +63,83 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
||||||
thre.release();
|
thre.release();
|
||||||
dst.release();
|
dst.release();
|
||||||
|
|
||||||
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
|
cv::RotatedRect rect = hg::getBoundingRect(m_maxContour);
|
||||||
|
m_rect = rect;
|
||||||
|
|
||||||
if (m_isDesaskew)
|
cv::Rect boudingRect = cv::boundingRect(m_maxContour);
|
||||||
|
boudingRect.x -= 1;
|
||||||
|
boudingRect.y -= 1;
|
||||||
|
boudingRect.width += 2;
|
||||||
|
boudingRect.height += 2;
|
||||||
|
|
||||||
|
if (m_isDesaskew && rect.angle != 0)
|
||||||
{
|
{
|
||||||
cv::Point2f srcTri[4];
|
cv::Point2f srcTri[4];
|
||||||
cv::Point2f dstTri[3];
|
cv::Point2f dstTri[3];
|
||||||
rect.points(srcTri);
|
rect.points(srcTri);
|
||||||
|
for (cv::Point2f& p : srcTri)
|
||||||
|
{
|
||||||
|
p.x -= 0.5;
|
||||||
|
p.y -= 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
dstTri[0] = cv::Point2f(0, rect.size.height - 1);
|
dstTri[0] = cv::Point2f(0, rect.size.height - 1);
|
||||||
dstTri[1] = cv::Point2f(0, 0);
|
dstTri[1] = cv::Point2f(0, 0);
|
||||||
dstTri[2] = cv::Point2f(rect.size.width - 1, 0);
|
dstTri[2] = cv::Point2f(rect.size.width - 1, 0);
|
||||||
|
|
||||||
cv::Mat warp_mat;
|
cv::Mat warp_mat;
|
||||||
warp_mat = cv::getAffineTransform(srcTri, dstTri);
|
warp_mat = cv::getAffineTransform(srcTri, dstTri);
|
||||||
cv::warpAffine(src, dst, warp_mat, rect.size);
|
cv::warpAffine(src, dst, warp_mat, rect.size, cv::INTER_NEAREST);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dst = src(rect.boundingRect() & cv::Rect(0, 0, src.cols, src.rows));
|
dst = src(boudingRect & cv::Rect(0, 0, src.cols, src.rows));
|
||||||
|
|
||||||
|
m_maxContour.clear();
|
||||||
|
m_maxContour.push_back(cv::Point(-1, dst.rows));
|
||||||
|
m_maxContour.push_back(cv::Point(-1, -1));
|
||||||
|
m_maxContour.push_back(cv::Point(dst.cols, -1));
|
||||||
|
m_maxContour.push_back(cv::Point(dst.cols, dst.rows));
|
||||||
|
|
||||||
if (m_isFillBlank)
|
if (m_isFillBlank)
|
||||||
{
|
{
|
||||||
cv::Mat thre_dst;
|
cv::Mat thre_dst;
|
||||||
hg::threshold_Mat(dst, thre_dst, m_threshold);
|
hg::threshold_Mat(dst, thre_dst, m_threshold);
|
||||||
cv::erode(thre_dst, thre_dst, cv::Mat(), cv::Point(-1, -1), m_indent);
|
|
||||||
|
if (m_indent > 0)
|
||||||
|
{
|
||||||
|
std::vector<cv::Point> rectEdge{ cv::Point(0, 0) ,cv::Point(thre_dst.cols - 1, 0),
|
||||||
|
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, m_indent));
|
||||||
|
cv::erode(thre_dst, thre_dst, element, cv::Point(-1, -1), 1);
|
||||||
|
}
|
||||||
hierarchy.clear();
|
hierarchy.clear();
|
||||||
contours.clear();
|
contours.clear();
|
||||||
maxContour.clear();
|
m_maxContour.clear();
|
||||||
|
|
||||||
hg::findContours(thre_dst, contours, hierarchy, cv::RETR_EXTERNAL);
|
hg::findContours(thre_dst, contours, hierarchy, cv::RETR_EXTERNAL);
|
||||||
thre_dst.release();
|
|
||||||
|
|
||||||
maxContour = hg::getMaxContour(contours, hierarchy);
|
|
||||||
if (m_isConvexHull)
|
if (m_isConvexHull)
|
||||||
hg::convexHull(maxContour, maxContour);
|
{
|
||||||
|
m_maxContour = hg::getMaxContour(contours, hierarchy);
|
||||||
|
hg::convexHull(m_maxContour, m_maxContour);
|
||||||
|
contours.clear();
|
||||||
|
contours.push_back(m_maxContour);
|
||||||
|
}
|
||||||
|
|
||||||
contours.clear();
|
contours.push_back(std::vector<cv::Point>());
|
||||||
contours.resize(2);
|
contours[contours.size() - 1].push_back(cv::Point(-1, dst.rows - 1));
|
||||||
contours[0] = maxContour;
|
contours[contours.size() - 1].push_back(cv::Point(-1, -1));
|
||||||
contours[1].push_back(cv::Point(0, dst.rows - 1));
|
contours[contours.size() - 1].push_back(cv::Point(dst.cols, -1));
|
||||||
contours[1].push_back(cv::Point(0, 0));
|
contours[contours.size() - 1].push_back(cv::Point(dst.cols, dst.rows));
|
||||||
contours[1].push_back(cv::Point(dst.cols - 1, 0));
|
|
||||||
contours[1].push_back(cv::Point(dst.cols - 1, dst.rows - 1));
|
|
||||||
|
|
||||||
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();
|
pDib.release();
|
||||||
if ((m_isCrop && side == 0) || (side == 1 && m_fixedSize.width * m_fixedSize.height == 0))
|
if (/*(m_isCrop && side == 0) || (side == 1 && m_fixedSize.width * m_fixedSize.height == 0)*/ m_isCrop)
|
||||||
{
|
|
||||||
pDib = dst.clone();
|
pDib = dst.clone();
|
||||||
dst.release();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
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;
|
|
||||||
}
|
|
||||||
pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0));
|
pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? cv::Scalar(255, 255, 255) : cv::Scalar(0, 0, 0));
|
||||||
|
|
||||||
cv::Rect roi;
|
cv::Rect roi;
|
||||||
|
@ -151,19 +148,10 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
||||||
roi.y = dst.rows > pDib.rows ? (dst.rows - pDib.rows) / 2 : 0;
|
roi.y = dst.rows > pDib.rows ? (dst.rows - pDib.rows) / 2 : 0;
|
||||||
roi.height = cv::min(pDib.rows, dst.rows);
|
roi.height = cv::min(pDib.rows, dst.rows);
|
||||||
cv::Rect rect((pDib.cols - roi.width) / 2, (pDib.rows - roi.height) / 2, roi.width, roi.height);
|
cv::Rect rect((pDib.cols - roi.width) / 2, (pDib.rows - roi.height) / 2, roi.width, roi.height);
|
||||||
#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));
|
|
||||||
dst.release();
|
|
||||||
|
|
||||||
|
for (cv::Point& p : m_maxContour)
|
||||||
|
p += roi.tl();
|
||||||
|
dst(roi).copyTo(pDib(rect));
|
||||||
}
|
}
|
||||||
#ifdef LOG
|
#ifdef LOG
|
||||||
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply8");
|
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply8");
|
||||||
|
@ -172,13 +160,14 @@ void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
|
||||||
|
|
||||||
void CImageApplyAutoCrop::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
void CImageApplyAutoCrop::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||||
{
|
{
|
||||||
|
m_rects.clear();
|
||||||
if (mats.empty()) return;
|
if (mats.empty()) return;
|
||||||
if (!mats[0].empty()) {
|
if (!mats[0].empty()) {
|
||||||
apply(mats[0], 0);
|
apply(mats[0], 0);
|
||||||
|
m_rects.push_back(m_rect);
|
||||||
//cv::imwrite("1.bmp", mats[0]);
|
//cv::imwrite("1.bmp", mats[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isTwoSide && mats.size() > 1)
|
if (isTwoSide && mats.size() > 1)
|
||||||
{
|
{
|
||||||
cv::Size dSize = m_fixedSize;
|
cv::Size dSize = m_fixedSize;
|
||||||
|
@ -187,11 +176,66 @@ void CImageApplyAutoCrop::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||||
|
|
||||||
if (!mats[1].empty()) {
|
if (!mats[1].empty()) {
|
||||||
apply(mats[1], 1);
|
apply(mats[1], 1);
|
||||||
|
m_rects.push_back(m_rect);
|
||||||
//cv::imwrite("1.bmp", mats[0]);
|
//cv::imwrite("1.bmp", mats[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!mats[0].empty())
|
if (!mats[0].empty())
|
||||||
m_fixedSize = dSize;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
|
||||||
|
* 功能:自动裁剪、纠偏、除黑底
|
||||||
|
* 作者:刘丁维
|
||||||
|
* 生成时间: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/30 v1.3.0 增加功能,可识别文稿颜色进行填充黑底。
|
||||||
|
* 版本号:v1.3.0
|
||||||
|
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef IMAGE_APPLY_AUTO_CROP_H
|
#ifndef IMAGE_APPLY_AUTO_CROP_H
|
||||||
#define IMAGE_APPLY_AUTO_CROP_H
|
#define IMAGE_APPLY_AUTO_CROP_H
|
||||||
|
|
||||||
|
@ -8,7 +26,18 @@ class CImageApplyAutoCrop : public CImageApply
|
||||||
public:
|
public:
|
||||||
CImageApplyAutoCrop();
|
CImageApplyAutoCrop();
|
||||||
|
|
||||||
CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true, double threshold = 40, int noise = 40, int indent = 5);
|
/*
|
||||||
|
* isCrop [in]:自动幅面裁剪使能,true自动裁剪,false为固定裁剪
|
||||||
|
* isDesaskew [in]:自动纠偏使能,true自动纠偏,false为不纠偏
|
||||||
|
* 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 = 2, int indent = 5);
|
||||||
|
|
||||||
virtual ~CImageApplyAutoCrop();
|
virtual ~CImageApplyAutoCrop();
|
||||||
|
|
||||||
|
@ -26,6 +55,10 @@ public:
|
||||||
|
|
||||||
double threshold() { return m_threshold; }
|
double threshold() { return m_threshold; }
|
||||||
|
|
||||||
|
const cv::RotatedRect& rotatedROI() { return m_rect; }
|
||||||
|
|
||||||
|
const std::vector<cv::RotatedRect>& rotatedROIs() { return m_rects; }
|
||||||
|
|
||||||
int noise() { return m_noise; }
|
int noise() { return m_noise; }
|
||||||
|
|
||||||
int indent() { return m_indent; }
|
int indent() { return m_indent; }
|
||||||
|
@ -50,19 +83,25 @@ public:
|
||||||
|
|
||||||
void setFixedSize(cv::Size size) { m_fixedSize = size; }
|
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:
|
private:
|
||||||
bool m_isCrop;
|
bool m_isCrop;
|
||||||
bool m_isDesaskew;
|
bool m_isDesaskew;
|
||||||
bool m_isFillBlank;
|
bool m_isFillBlank;
|
||||||
bool m_isConvexHull;
|
bool m_isConvexHull;
|
||||||
|
bool m_isFillColor;
|
||||||
|
|
||||||
double m_threshold;
|
double m_threshold;
|
||||||
int m_noise;
|
int m_noise;
|
||||||
int m_indent;
|
int m_indent;
|
||||||
cv::Size m_fixedSize;
|
cv::Size m_fixedSize;
|
||||||
|
cv::RotatedRect m_rect;
|
||||||
std::vector<cv::Point> m_maxContour;
|
std::vector<cv::Point> m_maxContour;
|
||||||
|
std::vector<cv::RotatedRect> m_rects;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !IMAGE_APPLY_AUTO_CROP_H
|
#endif // !IMAGE_APPLY_AUTO_CROP_H
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue