更新丁维优化重构图像处理算法代码
This commit is contained in:
parent
1c0d0c33b2
commit
72cba36185
510
AutoCrop.cpp
510
AutoCrop.cpp
|
@ -1,510 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "AutoCrop.h"
|
|
||||||
#ifndef _USE_MATH_DEFINES
|
|
||||||
#define _USE_MATH_DEFINES
|
|
||||||
#endif // !_USE_MATH_DEFINES
|
|
||||||
#include <math.h>
|
|
||||||
#include "PublicFunc.h"
|
|
||||||
#include "filetools.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace cv;
|
|
||||||
|
|
||||||
CAutoCrop::CAutoCrop( bool bFill,bool bautoDeScrew, bool bCrop,SIZE dstsize,SIZE originSize,int tw_pixType)
|
|
||||||
:m_bAutoDescrew(bautoDeScrew), m_bCrop(bCrop), m_bFill(bFill),m_dstSize(dstsize),m_originSize(originSize),tw_pixType(tw_pixType)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CAutoCrop::~CAutoCrop()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::apply(cv::Mat & dib,int side)
|
|
||||||
{
|
|
||||||
//XdPrint("CAutoCrop");
|
|
||||||
//RotatedRect rect;
|
|
||||||
//vector<Point> contour;
|
|
||||||
//double scale = 0.25;
|
|
||||||
//double thresh = 70;
|
|
||||||
//int blobSize = 200;
|
|
||||||
//int edgeWidth =5;
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Enter autocrop apply");
|
|
||||||
int flags=RC_INVALID;
|
|
||||||
if (m_bCrop)
|
|
||||||
{
|
|
||||||
flags|=RC_CUT;
|
|
||||||
}
|
|
||||||
if (m_bAutoDescrew)
|
|
||||||
{
|
|
||||||
flags|=RC_ROTATED;
|
|
||||||
}
|
|
||||||
if (m_bFill)
|
|
||||||
{
|
|
||||||
flags|=RC_BLACK_BACKGROUD;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_bCrop||m_bAutoDescrew)
|
|
||||||
{
|
|
||||||
if (tw_pixType!=0)//TWPT_BW)
|
|
||||||
{
|
|
||||||
flags|=RC_SHARPING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Mat mat;
|
|
||||||
rotated_and_cut(dib,mat,flags,32.0,7,5);
|
|
||||||
dib=mat;
|
|
||||||
|
|
||||||
if (!m_bCrop)
|
|
||||||
{
|
|
||||||
Size szActual,szOrg;
|
|
||||||
Rect rectCrop;
|
|
||||||
if (!m_bAutoDescrew)
|
|
||||||
{
|
|
||||||
int offsetF=72;
|
|
||||||
int offsetB=143;
|
|
||||||
rectCrop.x=(dib.cols-m_originSize.cx)/2;
|
|
||||||
rectCrop.y=side==0?offsetF:offsetB;
|
|
||||||
rectCrop.width=m_originSize.cx;
|
|
||||||
rectCrop.height=m_originSize.cy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
rectCrop.x=(dib.cols-m_originSize.cx)/2;
|
|
||||||
rectCrop.y=(dib.rows-m_originSize.cy)/2;
|
|
||||||
rectCrop.width=m_originSize.cx;
|
|
||||||
rectCrop.height=m_originSize.cy;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect rectImage(0, 0, dib.cols, dib.rows);
|
|
||||||
dib = dib(rectCrop);
|
|
||||||
}
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit autocrop apply");
|
|
||||||
}
|
|
||||||
static int i=0;
|
|
||||||
void CAutoCrop::setFill(bool val)
|
|
||||||
{
|
|
||||||
m_bFill = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAutoCrop::getFill()
|
|
||||||
{
|
|
||||||
return m_bFill;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::setCrop(bool val)
|
|
||||||
{
|
|
||||||
m_bCrop = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CAutoCrop::getCrop()
|
|
||||||
{
|
|
||||||
return m_bCrop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::sharpen(Mat& mat)
|
|
||||||
{
|
|
||||||
float kernel_data[] = { -0.1f, 0, 0, 0, -0.1f, 0, 0, 0, 0, 0, 0, 0, 1.5f, 0, 0, 0, 0, 0, 0, 0, -0.1f, 0, 0, 0, -0.1f };
|
|
||||||
Mat kernel(5, 5, CV_32FC1, kernel_data);
|
|
||||||
filter2D(mat, mat, mat.depth(), kernel);
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Point2f CAutoCrop::warpPoint(Point p, const Mat& warp_mat)
|
|
||||||
{
|
|
||||||
double src_data[3] = {p.x, p.y, 1};
|
|
||||||
Mat src(3, 1, warp_mat.type(), src_data); //warp_mat.type() == CV_64FC1
|
|
||||||
|
|
||||||
int type = warp_mat.type();
|
|
||||||
Mat dst = warp_mat * src;
|
|
||||||
double* ptr = (double*)dst.data;
|
|
||||||
|
|
||||||
return Point(ptr[0], ptr[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::rotated_and_cut(Mat &src,Mat& dst,int flags,double threshold,int noise,int indent)
|
|
||||||
{
|
|
||||||
if (flags == RC_INVALID)
|
|
||||||
{
|
|
||||||
dst = src.clone();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mat scale_mat;
|
|
||||||
Mat thre;
|
|
||||||
threshold_Mat(src, thre, threshold, noise);
|
|
||||||
|
|
||||||
vector<Vec4i> hierarchy;
|
|
||||||
vector<vector<Point>> contours;
|
|
||||||
findContours(thre, contours, hierarchy, RETR_EXTERNAL);
|
|
||||||
if (contours.size()<=0)
|
|
||||||
{
|
|
||||||
dst = src.clone();
|
|
||||||
flags=0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Point> maxContour = getMaxContour(contours, hierarchy);
|
|
||||||
MyConvexHull(maxContour,maxContour);
|
|
||||||
//convexHull(maxContour, maxContour); //用于排序,确保轮廓随逆时针排序
|
|
||||||
thre.release();
|
|
||||||
dst.release();
|
|
||||||
|
|
||||||
RotatedRect rect = getBoundingRect(maxContour);
|
|
||||||
Rect bounding_rect = boundingRect(maxContour);
|
|
||||||
if (flags & RC_CUT)
|
|
||||||
{
|
|
||||||
if (flags & RC_ROTATED)
|
|
||||||
{
|
|
||||||
dst = Mat::zeros(rect.size, src.type());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dst = src(bounding_rect).clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flags & RC_BLACK_BACKGROUD)
|
|
||||||
{
|
|
||||||
dst = src.clone();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dst = Mat::zeros(src.size(), src.type());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Mat warp_mat;
|
|
||||||
if (flags & RC_ROTATED)
|
|
||||||
{
|
|
||||||
Point2f dstTri[3];
|
|
||||||
Point2f srcTri[4];
|
|
||||||
rect.points(srcTri);
|
|
||||||
if (flags & RC_CUT)
|
|
||||||
{
|
|
||||||
dstTri[0] = Point2f(0, rect.size.height);
|
|
||||||
dstTri[1] = Point2f(0, 0);
|
|
||||||
dstTri[2] = Point2f(rect.size.width, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float left = (src.cols - rect.size.width) / 2;
|
|
||||||
float right = left + rect.size.width - 1;
|
|
||||||
float top = (src.rows - rect.size.height) / 2;
|
|
||||||
float bottom = top + rect.size.height - 1;
|
|
||||||
dstTri[0] = Point2f(left, bottom);
|
|
||||||
dstTri[1] = Point2f(left, top);
|
|
||||||
dstTri[2] = Point2f(right, top);
|
|
||||||
}
|
|
||||||
|
|
||||||
warp_mat = getAffineTransform(srcTri, dstTri);
|
|
||||||
|
|
||||||
Size dSize = (flags & RC_CUT) ? Size(rect.size) : dst.size();
|
|
||||||
|
|
||||||
warpAffine(src, dst, warp_mat, dSize, INTER_AREA);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags & RC_BLACK_BACKGROUD)
|
|
||||||
{
|
|
||||||
if (flags & RC_ROTATED)
|
|
||||||
{
|
|
||||||
for (int i=0;i<maxContour.size();i++)//for (Point& item : maxContour)
|
|
||||||
{
|
|
||||||
maxContour[i] = warpPoint(maxContour[i], warp_mat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (flags & RC_CUT)
|
|
||||||
{
|
|
||||||
Point offset = bounding_rect.tl();
|
|
||||||
for (int i=0;i<maxContour.size();i++)//for (Point& item : maxContour)
|
|
||||||
{
|
|
||||||
maxContour[i] -= offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fillBlackBackGround(dst, maxContour, indent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flags&RC_SHARPING)
|
|
||||||
{
|
|
||||||
sharpen(dst);
|
|
||||||
}
|
|
||||||
warp_mat.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::fillBlackBackGround(Mat& src, vector<Point> points, float indent)
|
|
||||||
{
|
|
||||||
polyIndent(points, indent);
|
|
||||||
Mat mask = Mat::zeros(src.size(), CV_8UC(src.channels()));
|
|
||||||
|
|
||||||
fillConvexPoly(mask, points, Scalar(255, 255, 255, 255));
|
|
||||||
|
|
||||||
bitwise_not(mask, mask);
|
|
||||||
//imwrite("mask1.bmp", mask);
|
|
||||||
//imwrite("mask2.bmp", src);
|
|
||||||
bitwise_or(src, mask, src);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::polyIndent(vector<Point>& points, float indent)
|
|
||||||
{
|
|
||||||
static Point zero(0, 0);
|
|
||||||
Point center = getBoundingRect(points).center;
|
|
||||||
for (int i=0;i<points.size();i++)// for (Point& item : points)
|
|
||||||
{
|
|
||||||
Point vec = points[i] - center;
|
|
||||||
if (vec != zero)
|
|
||||||
{
|
|
||||||
float length = vec.x * vec.x + vec.y * vec.y;
|
|
||||||
float x = sqrt((float)(vec.x * vec.x) / length) * indent;
|
|
||||||
float y = sqrt((float)(vec.y * vec.y) / length) * indent;
|
|
||||||
|
|
||||||
if (vec.x < 0)
|
|
||||||
{
|
|
||||||
x *= -1.0f;
|
|
||||||
}
|
|
||||||
if (vec.y < 0)
|
|
||||||
{
|
|
||||||
y *= -1.0f;
|
|
||||||
}
|
|
||||||
points[i].x -= x;
|
|
||||||
points[i].y -= y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//convexHull(points, points); //用于排序,确保轮廓随逆时针排序
|
|
||||||
MyConvexHull(points,points);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::fill_poly(Mat& src, const vector<vector<Point>>& contours, const Scalar& color, int lineType /*= 8*/, int shift /*= 0*/, Point offset /*= Point()*/)
|
|
||||||
{
|
|
||||||
int ncontours = contours.size();
|
|
||||||
Point** ptsptr = new Point*[ncontours];
|
|
||||||
int* npts = new int[ncontours];
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ncontours; i++)
|
|
||||||
{
|
|
||||||
ptsptr[i] = new Point[contours[i].size()];
|
|
||||||
npts[i] = contours[i].size();
|
|
||||||
for (size_t j = 0; j < npts[i]; j++)
|
|
||||||
{
|
|
||||||
ptsptr[i][j] = contours[i][j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fillPoly(src, (const Point**)ptsptr, (const int*)npts, ncontours, color, lineType, shift, offset);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < ncontours; i++)
|
|
||||||
{
|
|
||||||
delete[] ptsptr[i];
|
|
||||||
}
|
|
||||||
delete[] ptsptr;
|
|
||||||
delete[] npts;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::RotatedRect CAutoCrop::getBoundingRect(const vector<Point>& contour)
|
|
||||||
{
|
|
||||||
if (contour.empty())
|
|
||||||
{
|
|
||||||
return RotatedRect();//return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
RotatedRect rect = minAreaRect(contour);
|
|
||||||
if (rect.angle < -45)
|
|
||||||
{
|
|
||||||
rect.angle += 90;
|
|
||||||
double temp = rect.size.width;
|
|
||||||
rect.size.width = rect.size.height;
|
|
||||||
rect.size.height = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Point> CAutoCrop::getMaxContour(const vector<vector<Point>>& contours, const vector<Vec4i>& hierarchy)
|
|
||||||
{
|
|
||||||
vector<Point> maxContour;
|
|
||||||
if (contours.empty())
|
|
||||||
{
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contours.size() == 1)
|
|
||||||
{
|
|
||||||
maxContour = contours[0];
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, length = hierarchy.size(); i < length; i++)
|
|
||||||
{
|
|
||||||
if (hierarchy[i][3] == -1)
|
|
||||||
{
|
|
||||||
for(int j=0;j<contours[i].size();j++)//for (const auto &item : contours[i])
|
|
||||||
{
|
|
||||||
maxContour.push_back(contours[i][j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::findContours(const Mat& src, vector<vector<Point>>& contours, vector<Vec4i>& hierarchy, int retr /*= RETR_LIST*/, int method /*= CHAIN_APPROX_SIMPLE*/, Point offset /*= Point(0, 0)*/)
|
|
||||||
{
|
|
||||||
CvMat c_image = src;
|
|
||||||
MemStorage storage(cvCreateMemStorage());
|
|
||||||
CvSeq* _ccontours = nullptr;
|
|
||||||
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
|
|
||||||
|
|
||||||
if (!_ccontours)
|
|
||||||
{
|
|
||||||
contours.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
|
|
||||||
int total = (int)all_contours.size();
|
|
||||||
contours.resize(total);
|
|
||||||
|
|
||||||
SeqIterator<CvSeq*> it = all_contours.begin();
|
|
||||||
for (int i = 0; i < total; i++, ++it)
|
|
||||||
{
|
|
||||||
CvSeq* c = *it;
|
|
||||||
((CvContour*)c)->color = (int)i;
|
|
||||||
int count = (int)c->total;
|
|
||||||
int* data = new int[count * 2];
|
|
||||||
cvCvtSeqToArray(c, data);
|
|
||||||
for (int j = 0; j < count; j++)
|
|
||||||
{
|
|
||||||
contours[i].push_back(Point(data[j * 2], data[j * 2 + 1]));
|
|
||||||
}
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
hierarchy.resize(total);
|
|
||||||
it = all_contours.begin();
|
|
||||||
for (int i = 0; i < total; i++, ++it)
|
|
||||||
{
|
|
||||||
CvSeq* c = *it;
|
|
||||||
int h_next = c->h_next ? ((CvContour*)c->h_next)->color : -1;
|
|
||||||
int h_prev = c->h_prev ? ((CvContour*)c->h_prev)->color : -1;
|
|
||||||
int v_next = c->v_next ? ((CvContour*)c->v_next)->color : -1;
|
|
||||||
int v_prev = c->v_prev ? ((CvContour*)c->v_prev)->color : -1;
|
|
||||||
hierarchy[i] = Vec4i(h_next, h_prev, v_next, v_prev);
|
|
||||||
}
|
|
||||||
cvClearMemStorage(storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::threshold_Mat(const Mat& src, Mat& dst, double thre, int noise)
|
|
||||||
{
|
|
||||||
if (src.channels() == 3)
|
|
||||||
{
|
|
||||||
Mat gray = transforColor(src);
|
|
||||||
threshold(gray, dst, thre, 255, THRESH_BINARY);
|
|
||||||
Mat element = getStructuringElement(MORPH_RECT, Size(noise, noise));
|
|
||||||
morphologyEx(dst, dst, MORPH_ERODE, element);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
imwrite("gray.bmp", gray);
|
|
||||||
imwrite("thre.bmp", dst);
|
|
||||||
#endif
|
|
||||||
gray.release();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
threshold(src, dst, thre, 255, THRESH_BINARY);
|
|
||||||
Mat element=getStructuringElement(MORPH_RECT,Size(noise,noise));
|
|
||||||
morphologyEx(dst,dst,MORPH_ERODE,element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat CAutoCrop::transforColor(const Mat& src)
|
|
||||||
{
|
|
||||||
if (src.channels() == 1)
|
|
||||||
{
|
|
||||||
return src.clone();
|
|
||||||
}
|
|
||||||
Mat channels[3];
|
|
||||||
split(src, channels);
|
|
||||||
|
|
||||||
Mat temp, dst;
|
|
||||||
bitwise_or(channels[0], channels[1], temp);
|
|
||||||
bitwise_or(channels[2], temp, dst);
|
|
||||||
|
|
||||||
temp.release();
|
|
||||||
//for(Mat& index : channels)
|
|
||||||
//{
|
|
||||||
// index.release();
|
|
||||||
//}
|
|
||||||
for (int i=0;i < 3;i++)
|
|
||||||
{
|
|
||||||
channels[i].release();
|
|
||||||
}
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CAutoCrop::MyConvexHull(const vector<Point>& src, vector<Point>& dst, bool clockwise /*= false*/)
|
|
||||||
{
|
|
||||||
CvMemStorage* storage = cvCreateMemStorage(0); //申请内存空间,用于存放源数据和结果数据
|
|
||||||
CvSeq* ptseq = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage); //ptseq作为storage的迭代器
|
|
||||||
|
|
||||||
//填充源数据
|
|
||||||
for (size_t i=0;i<src.size();i++)
|
|
||||||
{
|
|
||||||
CvPoint p;
|
|
||||||
p.x = src[i].x;
|
|
||||||
p.y = src[i].y;
|
|
||||||
cvSeqPush(ptseq, &p);
|
|
||||||
}
|
|
||||||
//for (const Point& item : src)
|
|
||||||
//{
|
|
||||||
// CvPoint p;
|
|
||||||
// p.x = item.x;
|
|
||||||
// p.y = item.y;
|
|
||||||
// cvSeqPush(ptseq, &p);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//凸多边形计算,得到结果数据的迭代器hull,结果数据依然保存在storage分配的内存空间中
|
|
||||||
CvSeq* hull = cvConvexHull2(ptseq, 0, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 0);
|
|
||||||
|
|
||||||
//填充结果数据到dst中
|
|
||||||
dst.clear();
|
|
||||||
int hullCount = hull->total;
|
|
||||||
for (size_t i = 0; i < hullCount; i++)
|
|
||||||
{
|
|
||||||
dst.push_back(Point(**CV_GET_SEQ_ELEM(CvPoint*, hull, i)));
|
|
||||||
}
|
|
||||||
|
|
||||||
//释放storage
|
|
||||||
//cvClearMemStorage(storage);
|
|
||||||
cvReleaseMemStorage(&storage);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Point> getMaxContour(const vector<vector<Point>>& contours, const vector<Vec4i>& hierarchy)
|
|
||||||
{
|
|
||||||
vector<Point> maxContour;
|
|
||||||
if (contours.empty())
|
|
||||||
{
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contours.size() == 1)
|
|
||||||
{
|
|
||||||
maxContour = contours[0];
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0, length = hierarchy.size(); i < length; i++)
|
|
||||||
{
|
|
||||||
if (hierarchy[i][3] == -1)
|
|
||||||
{
|
|
||||||
for(int j=0;j<contours[i].size();j++)//for (const auto &item : contours[i])
|
|
||||||
{
|
|
||||||
maxContour.push_back(contours[i][j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
48
AutoCrop.h
48
AutoCrop.h
|
@ -1,48 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "ImageApply.h"
|
|
||||||
|
|
||||||
class CAutoCrop : public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CAutoCrop( bool bFill = true,bool bautoDeScrew = true,bool bCrop = true,SIZE dstsize = CSize(0, 0),SIZE originsize=CSize(0,0),int tw_pixType=2);
|
|
||||||
virtual ~CAutoCrop();
|
|
||||||
|
|
||||||
void apply(cv::Mat& dib,int side);
|
|
||||||
|
|
||||||
void setFill(bool val);
|
|
||||||
bool getFill();
|
|
||||||
|
|
||||||
void setCrop(bool val);
|
|
||||||
bool getCrop();
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum RC_TYPE {
|
|
||||||
RC_INVALID = 0x0,
|
|
||||||
RC_ROTATED = 0x1,
|
|
||||||
RC_CUT = 0x2,
|
|
||||||
RC_BLACK_BACKGROUD = 0x4,
|
|
||||||
RC_SHARPING = 0x8
|
|
||||||
};
|
|
||||||
|
|
||||||
void sharpen(cv::Mat& Mat);
|
|
||||||
cv::Point2f warpPoint(cv::Point p, const cv::Mat& warp_Mat);
|
|
||||||
void rotated_and_cut(cv::Mat &src, cv::Mat& dst,int flags,double threshold,int noise,int indent);
|
|
||||||
void fillBlackBackGround(cv::Mat& src, std::vector<cv::Point> points, float indent);
|
|
||||||
void polyIndent(std::vector<cv::Point>& points, float indent);
|
|
||||||
void fill_poly(cv::Mat& src, const std::vector<std::vector<cv::Point>>& contours, const cv::Scalar& color, int lineType = 8, int shift = 0, cv::Point offset = cv::Point());
|
|
||||||
cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour);
|
|
||||||
std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy);
|
|
||||||
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));
|
|
||||||
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre, int noise);
|
|
||||||
cv::Mat transforColor(const cv::Mat& src);
|
|
||||||
void MyConvexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise = false);
|
|
||||||
|
|
||||||
bool m_bCrop;
|
|
||||||
bool m_bFill;
|
|
||||||
bool m_bAutoDescrew;
|
|
||||||
SIZE m_dstSize;
|
|
||||||
SIZE m_originSize;
|
|
||||||
int tw_pixType;
|
|
||||||
};
|
|
||||||
|
|
|
@ -48,12 +48,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include "scn_config.h"
|
#include "scn_config.h"
|
||||||
#include "PublicFunc.h"
|
#include "PublicFunc.h"
|
||||||
#include "AutoCrop.h"
|
#include "ImageProcess/ImageApplyHeaders.h"
|
||||||
#include "ImageAdjustColors.h"
|
|
||||||
#include "ImageChannel.h"
|
|
||||||
#include "ImageApplyResize.h"
|
|
||||||
#include "ImageRotation.h"
|
|
||||||
#include "ImageProcDiscardBlank.h"
|
|
||||||
#include "filetools.h"
|
#include "filetools.h"
|
||||||
#include "hugaotwainds.h"
|
#include "hugaotwainds.h"
|
||||||
#include "GScanO200.h"
|
#include "GScanO200.h"
|
||||||
|
|
|
@ -1,213 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "ImageAdjustColors.h"
|
|
||||||
|
|
||||||
|
|
||||||
CImageAdjustColors::CImageAdjustColors(void)
|
|
||||||
{
|
|
||||||
lut.create(1, 256, CV_8UC1);
|
|
||||||
setAdjustColors(0, 0, 1.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CImageAdjustColors::CImageAdjustColors(float fBrightness, float fContrast, float fGamma)
|
|
||||||
{
|
|
||||||
lut.create(1, 256, CV_8UC1);
|
|
||||||
setAdjustColors(fBrightness, fContrast, fGamma);
|
|
||||||
}
|
|
||||||
|
|
||||||
CImageAdjustColors::~CImageAdjustColors(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageAdjustColors::apply(cv::Mat& pDib,int side)
|
|
||||||
{
|
|
||||||
if (m_fBrightness != 0|| m_fContrast != 0|| m_fGamma != 1.0)
|
|
||||||
{
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Enter CImageAdjustColors apply");
|
|
||||||
cv::LUT(pDib, lut, pDib);
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit CImageAdjustColors apply");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageAdjustColors::setAdjustColors(float fBrightness, float fContrast, float fGamma)
|
|
||||||
{
|
|
||||||
m_fBrightness = fBrightness;
|
|
||||||
m_fContrast = getRealContrast(fContrast);
|
|
||||||
m_fGamma = fGamma;
|
|
||||||
updata();
|
|
||||||
}
|
|
||||||
int CImageAdjustColors::getContrast()
|
|
||||||
{
|
|
||||||
return m_fContrast;
|
|
||||||
}
|
|
||||||
int CImageAdjustColors::getBrightness()
|
|
||||||
{
|
|
||||||
return m_fBrightness;
|
|
||||||
}
|
|
||||||
double CImageAdjustColors::getGamma()
|
|
||||||
{
|
|
||||||
return m_fGamma;
|
|
||||||
}
|
|
||||||
void CImageAdjustColors::setContrast(int contrast)
|
|
||||||
{
|
|
||||||
m_fContrast = cv::max(-127, cv::min(contrast, 127));
|
|
||||||
updata();
|
|
||||||
}
|
|
||||||
void CImageAdjustColors::setBrightness(int brightness)
|
|
||||||
{
|
|
||||||
m_fBrightness = cv::max(-255, cv::min(brightness, 255));
|
|
||||||
updata();
|
|
||||||
}
|
|
||||||
void CImageAdjustColors::setGamma(double gamma)
|
|
||||||
{
|
|
||||||
m_fGamma = cv::max(0.1, cv::min(gamma, 5.0));
|
|
||||||
updata();
|
|
||||||
}
|
|
||||||
void CImageAdjustColors::MapToMap(byte* mapsIn, byte* mapsOut)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
mapsOut[i] = mapsIn[mapsOut[i]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float CImageAdjustColors::getRealContrast(float twContrast)
|
|
||||||
{
|
|
||||||
float ret=0.0;
|
|
||||||
if (twContrast<=-1000.0)
|
|
||||||
{
|
|
||||||
ret=-36.0;
|
|
||||||
}
|
|
||||||
else if(twContrast>-1000.0&&twContrast<=-666.0)
|
|
||||||
{
|
|
||||||
ret=-24.0;
|
|
||||||
}
|
|
||||||
else if(twContrast>-666.0&&twContrast<=-333.0)
|
|
||||||
{
|
|
||||||
ret=-12.0;
|
|
||||||
}
|
|
||||||
else if (twContrast>= 333 && twContrast < 666)
|
|
||||||
{
|
|
||||||
ret=12.0;
|
|
||||||
}
|
|
||||||
else if (twContrast >= 666 && twContrast < 1000)
|
|
||||||
{
|
|
||||||
ret=24.0;
|
|
||||||
}
|
|
||||||
else if (twContrast >= 1000)
|
|
||||||
{
|
|
||||||
ret=36.0;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageAdjustColors::CalculateMap(Range in, Range out, unsigned char* map)
|
|
||||||
{
|
|
||||||
double k = 0, b = 0;
|
|
||||||
|
|
||||||
if (in.getMax() != in.getMin())
|
|
||||||
{
|
|
||||||
k = (double)(out.getMax() - out.getMin()) / (double)(in.getMax() - in.getMin());
|
|
||||||
b = (double)(out.getMin()) - k * in.getMin();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
byte v = (byte)i;
|
|
||||||
|
|
||||||
if (v >= in.getMax())
|
|
||||||
v = (byte)out.getMax();
|
|
||||||
else if (v <= in.getMin())
|
|
||||||
v = (byte)out.getMin();
|
|
||||||
else
|
|
||||||
v = (byte)(k * v + b);
|
|
||||||
|
|
||||||
map[i] = v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageAdjustColors::updata()
|
|
||||||
{
|
|
||||||
Range inIR;
|
|
||||||
Range OutIR;
|
|
||||||
byte maps[256];
|
|
||||||
byte _maps[256];
|
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
_maps[i] = maps[i] = (byte)i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (m_fBrightness > 0)
|
|
||||||
//{
|
|
||||||
// inIR = Range(0, (int)(255 - m_fBrightness));
|
|
||||||
// OutIR = Range((int)m_fBrightness, 255);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// inIR = Range((int)-m_fBrightness, 255);
|
|
||||||
// OutIR = Range(0, (int)(255 + m_fBrightness));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//CalculateMap(inIR, OutIR, maps);
|
|
||||||
//MapToMap(maps, _maps);
|
|
||||||
|
|
||||||
//if (m_fContrast > 0)
|
|
||||||
//{
|
|
||||||
// inIR = Range(0, (int)(255 - m_fContrast));
|
|
||||||
// OutIR = Range((int)m_fContrast, 255);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// inIR = Range((int)-m_fContrast, 255);
|
|
||||||
// OutIR = Range(0, (int)(255 + m_fContrast));
|
|
||||||
//}
|
|
||||||
//CalculateMap(inIR, OutIR, maps);
|
|
||||||
//MapToMap(maps, _maps);
|
|
||||||
|
|
||||||
double g = 1 / m_fGamma;
|
|
||||||
if (g != 1.0)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 256; i++)
|
|
||||||
{
|
|
||||||
maps[i] = (byte)MIN(255, (int)(pow(i / 255.0, g) * 255 + 0.5));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 128; i++)
|
|
||||||
{
|
|
||||||
int color = GetRangeValue(0, 127, i - (int)m_fContrast);
|
|
||||||
color = GetRangeValue(0, 255, color + (int)m_fBrightness);
|
|
||||||
maps[i] = (byte)color;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 128; i < 256; i++)
|
|
||||||
{
|
|
||||||
int color = GetRangeValue(128, 255, i + (int)m_fContrast);
|
|
||||||
color = GetRangeValue(0, 255, color + (int)m_fBrightness);
|
|
||||||
maps[i] = (byte)color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
MapToMap(maps, _maps);
|
|
||||||
|
|
||||||
memcpy(lut.data, _maps, sizeof(_maps));
|
|
||||||
}
|
|
||||||
|
|
||||||
int CImageAdjustColors::GetRangeValue(int low, int up, int value)
|
|
||||||
{
|
|
||||||
if (low > up)
|
|
||||||
{
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value<low)
|
|
||||||
{
|
|
||||||
return low;
|
|
||||||
}
|
|
||||||
if (value>up)
|
|
||||||
{
|
|
||||||
return up;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "ImageApply.h"
|
|
||||||
|
|
||||||
class CImageAdjustColors : public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CImageAdjustColors(void);
|
|
||||||
CImageAdjustColors(float fBrightness, float fContrast, float fGamma);
|
|
||||||
virtual ~CImageAdjustColors(void);
|
|
||||||
|
|
||||||
virtual void apply(cv::Mat& pDib,int side);
|
|
||||||
|
|
||||||
void setAdjustColors(float fBrightness, float fContrast, float fGamma);
|
|
||||||
|
|
||||||
int getContrast();
|
|
||||||
|
|
||||||
int getBrightness();
|
|
||||||
|
|
||||||
double getGamma();
|
|
||||||
|
|
||||||
void setContrast(int contrast);
|
|
||||||
|
|
||||||
void setBrightness(int brightness);
|
|
||||||
|
|
||||||
void setGamma(double gamma);
|
|
||||||
|
|
||||||
private:
|
|
||||||
class Range
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Range()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Range(int nMin, int nMax)
|
|
||||||
{
|
|
||||||
m_min = MIN(nMin, nMax);
|
|
||||||
m_max = MAX(nMin, nMax);
|
|
||||||
}
|
|
||||||
|
|
||||||
int getMin()
|
|
||||||
{
|
|
||||||
return m_min;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getMax()
|
|
||||||
{
|
|
||||||
return m_max;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_min;
|
|
||||||
int m_max;
|
|
||||||
};
|
|
||||||
void updata();
|
|
||||||
int GetRangeValue(int low, int up, int value);
|
|
||||||
void CalculateMap(Range in, Range out, unsigned char* map);
|
|
||||||
void MapToMap(byte* mapsIn, byte* mapsOut);
|
|
||||||
float m_fBrightness;
|
|
||||||
float m_fContrast;
|
|
||||||
float m_fGamma;
|
|
||||||
float getRealContrast(float twContrast);
|
|
||||||
cv::Mat lut;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "ImageApplyCrop.h"
|
|
||||||
|
|
||||||
CImageApplyCrop::CImageApplyCrop(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CImageApplyCrop::~CImageApplyCrop(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageApplyCrop::apply(cv::Mat& pDib,int side)
|
|
||||||
{
|
|
||||||
pDib = pDib(cv::Rect(m_org, m_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
cv::Size CImageApplyCrop::getSize()
|
|
||||||
{
|
|
||||||
return m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Point CImageApplyCrop::getOrg()
|
|
||||||
{
|
|
||||||
return m_org;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageApplyCrop::setSize(cv::Size size)
|
|
||||||
{
|
|
||||||
m_size=size;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageApplyCrop::setOrg(cv::Point point)
|
|
||||||
{
|
|
||||||
m_org=point;
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "imageapply.h"
|
|
||||||
|
|
||||||
class CImageApplyCrop :
|
|
||||||
public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CImageApplyCrop(void);
|
|
||||||
virtual ~CImageApplyCrop(void);
|
|
||||||
|
|
||||||
void apply(cv::Mat& pDib,int side);
|
|
||||||
cv::Size getSize();
|
|
||||||
cv::Point getOrg();
|
|
||||||
void setSize(cv::Size size);
|
|
||||||
void setOrg(cv::Point point);
|
|
||||||
private:
|
|
||||||
cv::Size m_size;
|
|
||||||
cv::Point m_org;
|
|
||||||
};
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef IMAGE_APPLY_HEADER_H
|
||||||
|
#define IMAGE_APPLY_HEADER_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
#include "ImageApplyAdjustColors.h"
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,54 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "ImageApplyResize.h"
|
|
||||||
#include "PublicFunc.h"
|
|
||||||
CImageApplyResize::CImageApplyResize(float orgResulution,float setResulution,bool autocut,SIZE dstsize)
|
|
||||||
:m_orgDpi(orgResulution),m_dpi(setResulution),autoCut(autocut),dstSize(dstsize)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CImageApplyResize::~CImageApplyResize(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CImageApplyResize::apply(cv::Mat& pDib,int side)
|
|
||||||
{
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Enter CImageApplyResize apply");
|
|
||||||
if(autoCut)
|
|
||||||
{
|
|
||||||
if (m_dpi != m_orgDpi)
|
|
||||||
{
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit CImageApplyResize autoCut m_dpi != m_orgDpi apply");
|
|
||||||
float ratio = m_dpi / m_orgDpi;
|
|
||||||
cv::resize(pDib, pDib, cv::Size(0, 0), ratio, ratio);
|
|
||||||
//XdPrint("1");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cv::Size dst(dstSize.cx,dstSize.cy);
|
|
||||||
cv::resize(pDib,pDib,dst,0,0);
|
|
||||||
}
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit CImageApplyResize apply");
|
|
||||||
}
|
|
||||||
|
|
||||||
float CImageApplyResize::getDpi()
|
|
||||||
{
|
|
||||||
return m_dpi;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageApplyResize::setDpi(float dpi)
|
|
||||||
{
|
|
||||||
m_dpi = dpi;
|
|
||||||
}
|
|
||||||
|
|
||||||
float CImageApplyResize::getOrgDpi()
|
|
||||||
{
|
|
||||||
return m_orgDpi;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageApplyResize::setOrgDpi(float dpi)
|
|
||||||
{
|
|
||||||
m_orgDpi = dpi;
|
|
||||||
}
|
|
|
@ -1,24 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "imageapply.h"
|
|
||||||
class CImageApplyResize :
|
|
||||||
public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CImageApplyResize(float orgResulution=0.0,float setResulution=0.0,bool autocut=false,SIZE dstsize=CSize(0,0));
|
|
||||||
virtual ~CImageApplyResize(void);
|
|
||||||
|
|
||||||
virtual void apply(cv::Mat& pDib,int side);
|
|
||||||
|
|
||||||
float getDpi();
|
|
||||||
void setDpi(float dpi);
|
|
||||||
|
|
||||||
float getOrgDpi();
|
|
||||||
void setOrgDpi(float dpi);
|
|
||||||
|
|
||||||
private:
|
|
||||||
float m_dpi;
|
|
||||||
float m_orgDpi;
|
|
||||||
SIZE dstSize;
|
|
||||||
bool autoCut;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "ImageBWBinaray.h"
|
|
||||||
|
|
||||||
|
|
||||||
CImageBWBinaray::CImageBWBinaray(bool needtoBW):needToBW(needtoBW)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CImageBWBinaray::~CImageBWBinaray(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageBWBinaray::apply(cv::Mat& dib,int side)
|
|
||||||
{
|
|
||||||
if (needToBW)
|
|
||||||
{
|
|
||||||
if (dib.channels()!=1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
threshold(dib,dib,128.0,255.0,CV_THRESH_BINARY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CImageBWBinaray::gray2binary(cv::Mat gray, unsigned char* binary){
|
|
||||||
if(gray.channels() != 1)
|
|
||||||
return;
|
|
||||||
int width = gray.cols;
|
|
||||||
int height = gray.rows;
|
|
||||||
int n_lineByte = (width + 7)/8;
|
|
||||||
int lineByte = (n_lineByte * 8 + 31)/32*4;
|
|
||||||
unsigned char * imageData = gray.data;
|
|
||||||
unsigned char temp;
|
|
||||||
for(int row = height -1 ; row >= 0 ; row--){
|
|
||||||
for(int col =0; col < width; col++ ){
|
|
||||||
int pos = col % 8;
|
|
||||||
int pix = *(imageData+ row * width + col);
|
|
||||||
temp = 1 << (7 - pos );
|
|
||||||
if( pix == 255 ){
|
|
||||||
*(binary + col /8) |= temp;
|
|
||||||
}else{
|
|
||||||
*(binary + col / 8 ) &= (~temp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
binary = binary + lineByte;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "ImageApply.h"
|
|
||||||
|
|
||||||
|
|
||||||
class CImageBWBinaray:public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CImageBWBinaray(bool needtoBW=false);
|
|
||||||
~CImageBWBinaray(void);
|
|
||||||
void apply(cv::Mat& dib,int side);
|
|
||||||
private:
|
|
||||||
void gray2binary(cv::Mat gray, unsigned char* binary);
|
|
||||||
bool needToBW;
|
|
||||||
};
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "ImageMatQueue.h"
|
#include "ImageMatQueue.h"
|
||||||
#include "PublicFunc.h"
|
#include "PublicFunc.h"
|
||||||
#include "filetools.h"
|
#include "filetools.h"
|
||||||
#include "ImageOutHole.h"
|
#include "ImageProcess/ImageApplyHeaders.h"
|
||||||
#include "ImageMultiOutput.h"
|
#include "ImageMultiOutput.h"
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
@ -73,25 +73,33 @@ void ImageMatQueue::setparam(SFreeImage param)
|
||||||
scanParam = param;
|
scanParam = param;
|
||||||
m_iaList.clear();
|
m_iaList.clear();
|
||||||
if (param.m_bAutoDiscardBlank || param.m_bAutoDiscardBlankInvoice)
|
if (param.m_bAutoDiscardBlank || param.m_bAutoDiscardBlankInvoice)
|
||||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageProcDiscardBlank(param.m_bAutoDiscardBlank ? true : false)));
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyDiscardBlank(param.m_bAutoDiscardBlank ? true : false)));
|
||||||
|
|
||||||
bool m_bAutoCrop = false;
|
{
|
||||||
if (param.m_HardWareParams.PaperType == 90)
|
CSize fixedSize = papersize.GetPaperSize(param.m_HardWareParams.PaperType, 200.0f);
|
||||||
m_bAutoCrop = true;
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAutoCrop(param.m_bAutoCrop, param.m_bFillBlackRect, param.m_bAutoDeskew, cv::Size(fixedSize.cx, fixedSize.cy))));
|
||||||
|
}
|
||||||
|
|
||||||
m_iaList.push_back(shared_ptr<CImageApply>(new CAutoCrop(param.m_bFillBlackRect, param.m_bAutoDeskew, param.m_bAutoCrop, papersize.GetPaperSize(param.m_HardWareParams.PaperType, param.m_fXResolution), papersize.GetPaperSize(param.m_HardWareParams.PaperType, 200.0), param.m_nPixelType)));
|
if (param.m_nPixelType != 0) //sharpen
|
||||||
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplySharpen()));
|
||||||
|
|
||||||
if (param.m_nFilter)
|
if (param.m_nFilter)
|
||||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageChannel(param.m_nFilter)));
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyChannel(param.m_nFilter)));
|
||||||
|
|
||||||
if (param.m_fBrightness != 0 || param.m_fContrast != 0 || param.m_fGamma != 1.0)
|
if (param.m_fBrightness != 0 || param.m_fContrast != 0 || param.m_fGamma != 1.0)
|
||||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageAdjustColors(param.m_fBrightness, param.m_fContrast, param.m_fGamma)));
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyAdjustColors(param.m_fBrightness, param.m_fContrast, param.m_fGamma)));
|
||||||
|
|
||||||
if (param.m_fXResolution != 200.0)
|
if (param.m_fXResolution != 200.0)
|
||||||
m_iaList.push_back(shared_ptr< CImageApply>(new CImageApplyResize(200.0, param.m_fXResolution, param.m_bAutoCrop, papersize.GetPaperSize(param.m_HardWareParams.PaperType, param.m_fXResolution))));
|
{
|
||||||
|
CSize dSize = papersize.GetPaperSize(param.m_HardWareParams.PaperType, param.m_fXResolution);
|
||||||
|
CImageApplyResize* apply = new CImageApplyResize();
|
||||||
|
apply->setType(CImageApplyResize::DSIZE);
|
||||||
|
apply->setDSize(cv::Size(dSize.cx, dSize.cy));
|
||||||
|
m_iaList.push_back(shared_ptr< CImageApply>(apply));
|
||||||
|
}
|
||||||
|
|
||||||
if (param.m_wRotation != 0 || param.m_bBackRotate180)
|
if (param.m_wRotation != 0 || param.m_bBackRotate180)
|
||||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageRotation(param.m_wRotation, param.m_bBackRotate180)));
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(param.m_wRotation, param.m_bBackRotate180)));
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat ImageMatQueue::_popMat()
|
cv::Mat ImageMatQueue::_popMat()
|
||||||
|
@ -154,16 +162,16 @@ void ImageMatQueue::proc()
|
||||||
// ImageOutHole().puncture(mats[0], mats[1], 50.0, scanParam.m_OutHole.OutHoleRatio / 100.0, 50);
|
// ImageOutHole().puncture(mats[0], mats[1], 50.0, scanParam.m_OutHole.OutHoleRatio / 100.0, 50);
|
||||||
//}
|
//}
|
||||||
|
|
||||||
//for (int i = 0; i < mats.size(); i++) {
|
for (int i = 0; i < mats.size(); i++) {
|
||||||
// if (!mats[i].empty()) {
|
if (!mats[i].empty()) {
|
||||||
// for (int j = 0; j < m_iaList.size(); j++) {
|
for (int j = 0; j < m_iaList.size(); j++) {
|
||||||
// if (mats[i].empty())//ÌÞ³ý¿Õ°×Ò³
|
if (mats[i].empty())//ÌÞ³ý¿Õ°×Ò³
|
||||||
// break;
|
break;
|
||||||
|
|
||||||
// m_iaList[j]->apply(mats[i], i);
|
m_iaList[j]->apply(mats[i], i);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mats.size(); i++) {
|
for (int i = 0; i < mats.size(); i++) {
|
||||||
//if (!scanParam.m_bDuplex && i == 1) {
|
//if (!scanParam.m_bDuplex && i == 1) {
|
||||||
|
|
|
@ -5,18 +5,12 @@
|
||||||
#include <opencv2\opencv.hpp>
|
#include <opencv2\opencv.hpp>
|
||||||
#include "JpegBuffer.h"
|
#include "JpegBuffer.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include "ImageApply.h"
|
#include "ImageProcess/ImageApplyHeaders.h"
|
||||||
#include "PublicFunc.h"
|
#include "PublicFunc.h"
|
||||||
#include "BlockingQueue.h"
|
#include "BlockingQueue.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include "PaperSize.h"
|
#include "PaperSize.h"
|
||||||
#include "AutoCrop.h"
|
|
||||||
#include "ImageAdjustColors.h"
|
|
||||||
#include "ImageApplyResize.h"
|
|
||||||
#include "ImageChannel.h"
|
|
||||||
#include "ImageProcDiscardBlank.h"
|
|
||||||
#include "ImageRotation.h"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class ImageMatQueue
|
class ImageMatQueue
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "ImageApply.h"
|
#include "ImageProcess/ImageApply.h"
|
||||||
|
|
||||||
class ImageMultiOutput
|
class ImageMultiOutput
|
||||||
{
|
{
|
||||||
|
|
315
ImageOutHole.cpp
315
ImageOutHole.cpp
|
@ -1,315 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "ImageOutHole.h"
|
|
||||||
#include <memory>
|
|
||||||
#include <math.h>
|
|
||||||
#include "opencv2/opencv.hpp"
|
|
||||||
#include "opencv/cv.h"
|
|
||||||
#include "opencv2/core/core.hpp"
|
|
||||||
|
|
||||||
using namespace cv;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
ImageOutHole::ImageOutHole(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ImageOutHole::~ImageOutHole(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOutHole::puncture(Mat& front, Mat& back, double threshold, float edgeScale, double areaThreshold)
|
|
||||||
{
|
|
||||||
//二值化正反面图像
|
|
||||||
//FileTools::write_log("D:\\1.txt", "enter ImageOutHole apply");
|
|
||||||
threshold = min(max(threshold, 1.0), 254.0);
|
|
||||||
Mat front_thre = threshold_mat(front, threshold);
|
|
||||||
Mat back_thre = threshold_mat(back, threshold);
|
|
||||||
|
|
||||||
//反面二值化图像水平翻转
|
|
||||||
flip(back_thre, back_thre, 1); //1:Horizontal
|
|
||||||
|
|
||||||
//正反面图像寻边
|
|
||||||
vector<vector<Point>> contours_front, contours_back;
|
|
||||||
vector<Vec4i> b1_front, b1_back;
|
|
||||||
findContours22(front_thre.clone(), contours_front, b1_front);
|
|
||||||
findContours22(back_thre.clone(), contours_back, b1_back);
|
|
||||||
#if 0
|
|
||||||
imwrite("front_thre.bmp", front_thre);
|
|
||||||
imwrite("back_thre.bmp", back_thre);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//提取正反面图像最大轮廓
|
|
||||||
vector<Point> maxContour_front = getMaxContour(contours_front, b1_front);
|
|
||||||
vector<Point> maxContour_back = getMaxContour(contours_back, b1_back);
|
|
||||||
|
|
||||||
RotatedRect rrect_front = minAreaRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
|
|
||||||
RotatedRect rrect_back = minAreaRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
|
|
||||||
|
|
||||||
//提取正反面图像重叠部分区域
|
|
||||||
Rect roi_front, roi_back;
|
|
||||||
RotatedRect mask_rotatedRect;
|
|
||||||
getRoi(rrect_front, rrect_back, Size(front.cols, front.rows), roi_front, roi_back, mask_rotatedRect);
|
|
||||||
Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
|
|
||||||
Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
|
|
||||||
|
|
||||||
//正反面二值图像做或运算,真正镂空区域保留0,其他地方填充为255
|
|
||||||
//为了避免孔洞彻底贯穿纸边,认为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连。
|
|
||||||
#if 0
|
|
||||||
imwrite("front_thre.bmp", roiMat_front);
|
|
||||||
imwrite("back_thre.bmp", roiMat_back);
|
|
||||||
#endif
|
|
||||||
Mat mask;
|
|
||||||
bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
|
|
||||||
vector<Point> vertices_point = getVertices(mask_rotatedRect);
|
|
||||||
|
|
||||||
polylines(mask, vertices_point, true, Scalar(255), 3); //绘制纸张矩形边缘
|
|
||||||
|
|
||||||
//二值图像重叠图像颜色取反,并提取轮廓
|
|
||||||
vector<vector<Point>> contours_mask;
|
|
||||||
vector<Vec4i> b1_mask;
|
|
||||||
bitwise_not(mask, mask); //取反
|
|
||||||
findContours22(mask.clone(), contours_mask, b1_mask); //提取重叠图像轮廓
|
|
||||||
|
|
||||||
//过滤非孔洞的联通区域
|
|
||||||
filterPoly(mask, contours_mask, mask_rotatedRect, edgeScale, areaThreshold);
|
|
||||||
|
|
||||||
//膨胀算法,增大孔洞连通区域面积
|
|
||||||
dilate(mask, mask, Mat(), Point(-1, -1), 3, BORDER_DEFAULT, Scalar(255));
|
|
||||||
|
|
||||||
vector<Point> rect_poly;
|
|
||||||
rect_poly.push_back(Point(2, 2));
|
|
||||||
rect_poly.push_back(Point(2, mask.rows - 2));
|
|
||||||
rect_poly.push_back(Point(mask.cols - 2, mask.rows - 2));
|
|
||||||
rect_poly.push_back(Point(mask.cols - 2, 2));
|
|
||||||
polylines(mask, rect_poly, true, Scalar(0), 5); //把mask边缘涂黑
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
imwrite("mask.bmp", mask);
|
|
||||||
#endif
|
|
||||||
//填充正面图像孔洞
|
|
||||||
Mat mask_flip;
|
|
||||||
flip(mask, mask_flip, 1); //因为之前反面图像翻转,所以现在要再翻转回去
|
|
||||||
roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转,所以现在ROI也要进行相应翻转
|
|
||||||
fillPuncture(front, mask, roi_front); //正面孔洞填充
|
|
||||||
fillPuncture(back, mask_flip, roi_back); //反面孔洞填充
|
|
||||||
#if 0
|
|
||||||
imwrite("111.jpg", front);
|
|
||||||
imwrite("222.jpg", back);
|
|
||||||
#endif
|
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit ImageOutHole apply");
|
|
||||||
}
|
|
||||||
|
|
||||||
cv::Mat ImageOutHole::threshold_mat(const Mat& src, double threshold)
|
|
||||||
{
|
|
||||||
Mat dst(src.rows, src.cols, CV_8UC1, 1);
|
|
||||||
|
|
||||||
if (src.channels() == 3)
|
|
||||||
{
|
|
||||||
Mat gray;
|
|
||||||
cvtColor(src, gray, COLOR_BGR2GRAY);
|
|
||||||
cv::threshold(gray, dst, threshold, 255, THRESH_BINARY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cv::threshold(src, dst, threshold, 255, THRESH_BINARY);
|
|
||||||
}
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOutHole::findContours22(const Mat& src, vector<vector<Point>>& contours, vector<Vec4i>& hierarchy,
|
|
||||||
int retr/* = RETR_CCOMP*/, int method/* = CHAIN_APPROX_SIMPLE*/, Point offset /*= Point(0, 0)*/)
|
|
||||||
{
|
|
||||||
CvMat c_image = src;
|
|
||||||
MemStorage storage(cvCreateMemStorage());
|
|
||||||
CvSeq* _ccontours = nullptr;
|
|
||||||
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
|
|
||||||
|
|
||||||
if (!_ccontours)
|
|
||||||
{
|
|
||||||
contours.clear();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
|
|
||||||
int total = (int)all_contours.size();
|
|
||||||
contours.resize(total);
|
|
||||||
|
|
||||||
SeqIterator<CvSeq*> it = all_contours.begin();
|
|
||||||
for (int i = 0; i < total; i++, ++it)
|
|
||||||
{
|
|
||||||
CvSeq* c = *it;
|
|
||||||
((CvContour*)c)->color = (int)i;
|
|
||||||
int count = (int)c->total;
|
|
||||||
int* data = new int[count * 2];
|
|
||||||
cvCvtSeqToArray(c, data);
|
|
||||||
for (int j = 0; j < count; j++)
|
|
||||||
{
|
|
||||||
contours[i].push_back(Point(data[j * 2], data[j * 2 + 1]));
|
|
||||||
}
|
|
||||||
delete[] data;
|
|
||||||
}
|
|
||||||
|
|
||||||
hierarchy.resize(total);
|
|
||||||
it = all_contours.begin();
|
|
||||||
for (int i = 0; i < total; i++, ++it)
|
|
||||||
{
|
|
||||||
CvSeq* c = *it;
|
|
||||||
int h_next = c->h_next ? ((CvContour*)c->h_next)->color : -1;
|
|
||||||
int h_prev = c->h_prev ? ((CvContour*)c->h_prev)->color : -1;
|
|
||||||
int v_next = c->v_next ? ((CvContour*)c->v_next)->color : -1;
|
|
||||||
int v_prev = c->v_prev ? ((CvContour*)c->v_prev)->color : -1;
|
|
||||||
hierarchy[i] = Vec4i(h_next, h_prev, v_next, v_prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
vector<Point> ImageOutHole::getMaxContour(const vector<vector<Point>>& contours, const vector<Vec4i>& hierarchy, int areaThreshold /*= 20000*/)
|
|
||||||
{
|
|
||||||
vector<Point> maxContour;
|
|
||||||
for (size_t i = 0, length = hierarchy.size(); i < length; i++)
|
|
||||||
{
|
|
||||||
Vec4i h = hierarchy[i];
|
|
||||||
if (h[3] == -1)
|
|
||||||
{
|
|
||||||
if (contourArea(contours[i]) > areaThreshold)
|
|
||||||
{
|
|
||||||
maxContour = contours[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return maxContour;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOutHole::getRoi(RotatedRect rrect_front, RotatedRect rrect_back, Size srcSize, Rect& roi_front, Rect& roi_back, RotatedRect& mask_rotatedRect)
|
|
||||||
{
|
|
||||||
Size size((rrect_front.size.width + rrect_back.size.width) / 2, (rrect_front.size.height + rrect_back.size.height) / 2);
|
|
||||||
float angle = (rrect_front.angle + rrect_back.angle) / 2;
|
|
||||||
|
|
||||||
rrect_front.size = rrect_back.size = size;
|
|
||||||
rrect_front.angle = rrect_back.angle = angle;
|
|
||||||
|
|
||||||
roi_front = rrect_front.boundingRect();
|
|
||||||
roi_back = rrect_back.boundingRect();
|
|
||||||
|
|
||||||
if (roi_front.width!=roi_back.width||roi_front.height!=roi_back.height)
|
|
||||||
{
|
|
||||||
roi_front.height=roi_back.height;
|
|
||||||
roi_front.width=roi_back.width;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point offset(0, 0);
|
|
||||||
int top = min(roi_front.y, roi_back.y);
|
|
||||||
if (top < 0)
|
|
||||||
{
|
|
||||||
roi_front.y -= top;
|
|
||||||
roi_back.y -= top;
|
|
||||||
roi_front.height += top;
|
|
||||||
roi_back.height += top;
|
|
||||||
offset.y += top;
|
|
||||||
}
|
|
||||||
|
|
||||||
int left = min(roi_front.x, roi_back.x);
|
|
||||||
if (left < 0)
|
|
||||||
{
|
|
||||||
roi_front.x -= left;
|
|
||||||
roi_back.x -= left;
|
|
||||||
roi_front.width += left;
|
|
||||||
roi_back.width += left;
|
|
||||||
offset.x += left;
|
|
||||||
}
|
|
||||||
|
|
||||||
int right = max(roi_front.x + roi_front.width, roi_back.x + roi_back.width);
|
|
||||||
if (right >= srcSize.width)
|
|
||||||
{
|
|
||||||
roi_front.width -= (right - srcSize.width + 1);
|
|
||||||
roi_back.width -= (right - srcSize.width + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bottom = max(roi_front.y + roi_front.height, roi_back.y + roi_back.height);
|
|
||||||
if (bottom >= srcSize.height)
|
|
||||||
{
|
|
||||||
roi_front.height -= (bottom - srcSize.height + 1);
|
|
||||||
roi_back.height -= (bottom - srcSize.height + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
mask_rotatedRect.center = Point((roi_front.width + offset.x) / 2, (roi_front.height + offset.y) / 2);
|
|
||||||
mask_rotatedRect.size = size;
|
|
||||||
mask_rotatedRect.angle = angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point ImageOutHole::rotatedPoint(Point p, Point center, double angle)
|
|
||||||
{
|
|
||||||
double cos_ = cos(angle / 180 * CV_PI);
|
|
||||||
double sin_ = sin(angle / 180 * CV_PI);
|
|
||||||
|
|
||||||
double x = (p.x - center.x) * cos_ - (p.y - center.y) * sin_ + center.x;
|
|
||||||
double y = (p.y - center.y) * cos_ + (p.x - center.x) * sin_ + center.y;
|
|
||||||
|
|
||||||
return Point(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<Point> ImageOutHole::getVertices(RotatedRect rect)
|
|
||||||
{
|
|
||||||
vector<Point> points;
|
|
||||||
|
|
||||||
Point leftTop(rect.center.x - rect.size.width / 2, rect.center.y - rect.size.height / 2);
|
|
||||||
Point leftBottom(rect.center.x - rect.size.width / 2, rect.center.y + rect.size.height / 2);
|
|
||||||
Point rightTop(rect.center.x + rect.size.width / 2, rect.center.y - rect.size.height / 2);
|
|
||||||
Point rigthBottom(rect.center.x + rect.size.width / 2, rect.center.y + rect.size.height / 2);
|
|
||||||
|
|
||||||
points.push_back(rotatedPoint(leftTop, rect.center, rect.angle));
|
|
||||||
points.push_back(rotatedPoint(leftBottom, rect.center, rect.angle));
|
|
||||||
points.push_back(rotatedPoint(rigthBottom, rect.center, rect.angle));
|
|
||||||
points.push_back(rotatedPoint(rightTop, rect.center, rect.angle));
|
|
||||||
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOutHole::filterPoly(const Mat& mask, vector<vector<Point>>& contours, RotatedRect roi, float edgeScale, double areaThreshold)
|
|
||||||
{
|
|
||||||
edgeScale = min(0.49f, max(edgeScale, 0.0f));
|
|
||||||
RotatedRect roi2(roi.center, Size(roi.size.width * (1 - edgeScale * 2), roi.size.height * (1 - edgeScale * 2)), roi.angle);
|
|
||||||
|
|
||||||
vector<Point> vertices_roi1 = getVertices(roi);
|
|
||||||
vector<Point> vertices_roi2 = getVertices(roi2);
|
|
||||||
|
|
||||||
vector<Point> contour;
|
|
||||||
for (size_t i = 0, length = contours.size(); i < length; i++)
|
|
||||||
{
|
|
||||||
//contour = /*Mat_<Point>*/(contours[i]);
|
|
||||||
if (contourArea(contours[i]) < areaThreshold)
|
|
||||||
{
|
|
||||||
fillConvexPoly(mask, contours[i], Scalar(0));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (int j = 0, count = contours[i].size(); j < count; j++)
|
|
||||||
{
|
|
||||||
Point p(contours[i][j]);
|
|
||||||
double temp1 = pointPolygonTest(vertices_roi1, p, false); //判断是否在纸张内 1:内;0:上;-1:外
|
|
||||||
double temp2 = pointPolygonTest(vertices_roi2, p, false); //判断是否在边缘区域内 1:内;0:上;-1:外
|
|
||||||
//如果在纸张外,或者边缘内,视为非孔洞,填充为0
|
|
||||||
if (temp1 < 0 || temp2 > 0)
|
|
||||||
{
|
|
||||||
fillConvexPoly(mask, contours[i], Scalar(0));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageOutHole::fillPuncture(Mat& src, const Mat& mask, Rect roi)
|
|
||||||
{
|
|
||||||
Mat mask_temp;
|
|
||||||
if (src.channels() == 3)
|
|
||||||
{
|
|
||||||
cvtColor(mask, mask_temp, COLOR_GRAY2RGB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mask_temp = mask;
|
|
||||||
}
|
|
||||||
Mat src_roi(src, roi);
|
|
||||||
bitwise_or(src_roi, mask_temp, src_roi);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "ImageApply.h"
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class ImageOutHole
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageOutHole(void);
|
|
||||||
~ImageOutHole(void);
|
|
||||||
public:
|
|
||||||
void puncture(cv::Mat& front, cv::Mat& back, double threshold, float edgeScale, double areaThreshold);
|
|
||||||
private:
|
|
||||||
cv::Mat threshold_mat(const cv::Mat& src, double threshold);
|
|
||||||
void findContours22(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr = cv::RETR_CCOMP, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
|
|
||||||
std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy, int areaThreshold = 20000);
|
|
||||||
void getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, cv::Rect& roi_front, cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect);
|
|
||||||
cv::Point rotatedPoint(cv::Point p, cv::Point center, double angle);
|
|
||||||
std::vector<cv::Point> getVertices(cv::RotatedRect rect);
|
|
||||||
void filterPoly(const cv::Mat& mask, std::vector<std::vector<cv::Point>>& contours, cv::RotatedRect roi, float edgeScale, double areaThreshold);
|
|
||||||
void fillPuncture(cv::Mat& src, const cv::Mat& mask, cv::Rect roi);
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "ImageApply.h"
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
|
||||||
CImageApply::CImageApply(void)
|
CImageApply::CImageApply(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CImageApply::~CImageApply(void)
|
CImageApply::~CImageApply(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
|
@ -1,8 +1,14 @@
|
||||||
#pragma once
|
#ifndef IMAGE_APPLY_H
|
||||||
|
#define IMAGE_APPLY_H
|
||||||
|
|
||||||
|
#include "../stdafx.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <opencv2/opencv.hpp>
|
#include <opencv2/opencv.hpp>
|
||||||
|
|
||||||
|
#if defined(LOG)
|
||||||
#include "filetools.h"
|
#include "filetools.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class CImageApply
|
class CImageApply
|
||||||
{
|
{
|
||||||
|
@ -11,8 +17,8 @@ public:
|
||||||
virtual ~CImageApply(void);
|
virtual ~CImageApply(void);
|
||||||
|
|
||||||
virtual void apply(cv::Mat& pDib,int side) = 0;
|
virtual void apply(cv::Mat& pDib,int side) = 0;
|
||||||
//virtual void apply(twainImage& pDib) = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::shared_ptr<CImageApply> ImageApplyPtr;
|
typedef std::shared_ptr<CImageApply> ImageApplyPtr;
|
||||||
|
|
||||||
|
#endif //!IMAGE_APPLY_H
|
|
@ -0,0 +1,79 @@
|
||||||
|
#include "ImageApplyAdjustColors.h"
|
||||||
|
|
||||||
|
CImageApplyAdjustColors::CImageApplyAdjustColors(void)
|
||||||
|
: m_brightness(0)
|
||||||
|
, m_contrast(0)
|
||||||
|
, m_gamma(1.0f)
|
||||||
|
, lut(1, 256, CV_8UC1)
|
||||||
|
{
|
||||||
|
update_lutData();
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageApplyAdjustColors::CImageApplyAdjustColors(int brightness, int contrast, float gamma)
|
||||||
|
: lut(1, 256, CV_8UC1)
|
||||||
|
{
|
||||||
|
setAdjustColors(brightness, contrast, gamma);
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageApplyAdjustColors::~CImageApplyAdjustColors(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAdjustColors::apply(cv::Mat& pDib,int side)
|
||||||
|
{
|
||||||
|
if (m_brightness != 0 || m_contrast != 0 || m_gamma != 1.0)
|
||||||
|
cv::LUT(pDib, lut, pDib);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAdjustColors::setAdjustColors(int brightness, int contrast, float gamma)
|
||||||
|
{
|
||||||
|
setBrightness(brightness);
|
||||||
|
setContrast(contrast);
|
||||||
|
setGamma(gamma);
|
||||||
|
update_lutData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAdjustColors::setBrightness(int brightness)
|
||||||
|
{
|
||||||
|
m_brightness = cv::max(-255, cv::min(brightness, 255));
|
||||||
|
update_lutData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAdjustColors::setContrast(int contrast)
|
||||||
|
{
|
||||||
|
m_contrast = cv::max(-127, cv::min(contrast, 127));
|
||||||
|
update_lutData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAdjustColors::setGamma(float gamma)
|
||||||
|
{
|
||||||
|
m_gamma = cv::max(0.1f, cv::min(gamma, 5.0f));
|
||||||
|
update_lutData();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAdjustColors::update_lutData()
|
||||||
|
{
|
||||||
|
unsigned char* ptr = lut.data;
|
||||||
|
|
||||||
|
if (m_gamma != 1.0f)
|
||||||
|
{
|
||||||
|
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(ptr[i] + m_brightness, 255)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef IMAGE_APPLY_ADJUST_COLOR_H
|
||||||
|
#define IMAGE_APPLY_ADJUST_COLOR_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class CImageApplyAdjustColors : public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CImageApplyAdjustColors(void);
|
||||||
|
|
||||||
|
CImageApplyAdjustColors(int brightness, int contrast, float gamma);
|
||||||
|
|
||||||
|
virtual ~CImageApplyAdjustColors(void);
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib, int side);
|
||||||
|
|
||||||
|
void setAdjustColors(int brightness, int contrast, float gamma);
|
||||||
|
|
||||||
|
int getContrast() { return m_contrast; }
|
||||||
|
|
||||||
|
int getBrightness() { return m_brightness; }
|
||||||
|
|
||||||
|
double getGamma() { return m_gamma; }
|
||||||
|
|
||||||
|
void setBrightness(int brightness);
|
||||||
|
|
||||||
|
void setContrast(int contrast);
|
||||||
|
|
||||||
|
void setGamma(float gamma);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void update_lutData();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
int m_brightness;
|
||||||
|
int m_contrast;
|
||||||
|
float m_gamma;
|
||||||
|
cv::Mat lut;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_ADJUST_COLOR_H
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
#include "ImageApplyAutoCrop.h"
|
||||||
|
#include "ImageProcess_Public.h"
|
||||||
|
|
||||||
|
#define RE 8
|
||||||
|
|
||||||
|
CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isFillBlank, bool isDesaskew, cv::Size size)
|
||||||
|
: m_isCrop(isCrop)
|
||||||
|
, m_isFillBlank(isFillBlank)
|
||||||
|
, m_isDesaskew(isDesaskew)
|
||||||
|
, m_fixedSize(size)
|
||||||
|
, m_threshold(35)
|
||||||
|
, m_noise(7)
|
||||||
|
, m_indent(5)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CImageApplyAutoCrop::~CImageApplyAutoCrop()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyAutoCrop::apply(cv::Mat & pDib, int side)
|
||||||
|
{
|
||||||
|
if (!m_isCrop && !m_isFillBlank && !m_isDesaskew) return;
|
||||||
|
cv::Mat src = pDib;
|
||||||
|
cv::Mat dst;
|
||||||
|
cv::Mat src_resize;
|
||||||
|
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);
|
||||||
|
|
||||||
|
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise, m_noise));
|
||||||
|
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element);
|
||||||
|
|
||||||
|
std::vector<cv::Vec4i> hierarchy;
|
||||||
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
|
||||||
|
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
|
||||||
|
std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
|
||||||
|
|
||||||
|
for (cv::Point& item : maxContour)
|
||||||
|
{
|
||||||
|
item.x = item.x * RE + RE / 2;
|
||||||
|
item.y = item.y * RE + RE / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxContour.size() == 0)
|
||||||
|
{
|
||||||
|
thre.release();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
thre.release();
|
||||||
|
dst.release();
|
||||||
|
|
||||||
|
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
|
||||||
|
|
||||||
|
hg::convexHull(maxContour, maxContour);
|
||||||
|
|
||||||
|
cv::Rect bounding_rect = rect.boundingRect();
|
||||||
|
|
||||||
|
if (m_isCrop)
|
||||||
|
if (m_isDesaskew)
|
||||||
|
dst = cv::Mat::zeros(cv::Size(rect.size), src.type());
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cv::Rect bounding_rect_clone = bounding_rect;
|
||||||
|
bounding_rect.x = cv::max(0, bounding_rect_clone.x);
|
||||||
|
bounding_rect.y = cv::max(0, bounding_rect_clone.y);
|
||||||
|
bounding_rect.width = cv::min(src.cols, bounding_rect_clone.x + bounding_rect_clone.width) - bounding_rect.x;
|
||||||
|
bounding_rect.height = cv::min(src.rows, bounding_rect_clone.y + bounding_rect_clone.height) - bounding_rect.y;
|
||||||
|
dst = src(bounding_rect).clone();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (m_isFillBlank)
|
||||||
|
dst = src.clone();
|
||||||
|
else
|
||||||
|
dst = cv::Mat(src.rows, src.cols, src.type());
|
||||||
|
|
||||||
|
cv::Mat warp_mat;
|
||||||
|
if (m_isDesaskew)
|
||||||
|
{
|
||||||
|
cv::Point2f dstTri[3];
|
||||||
|
cv::Point2f srcTri[4];
|
||||||
|
rect.points(srcTri);
|
||||||
|
|
||||||
|
for (cv::Point2f& p : srcTri)
|
||||||
|
p.y /= 1.5f;
|
||||||
|
|
||||||
|
if (m_isCrop)
|
||||||
|
{
|
||||||
|
dstTri[0] = cv::Point2f(0, rect.size.height - 1);
|
||||||
|
dstTri[1] = cv::Point2f(0, 0);
|
||||||
|
dstTri[2] = cv::Point2f(rect.size.width - 1, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float left = (src.cols - rect.size.width) / 2;
|
||||||
|
float right = left + rect.size.width - 1;
|
||||||
|
float top = (src.rows - rect.size.height) / 2;
|
||||||
|
float bottom = top + rect.size.height - 1;
|
||||||
|
dstTri[0] = cv::Point2f(left, bottom);
|
||||||
|
dstTri[1] = cv::Point2f(left, top);
|
||||||
|
dstTri[2] = cv::Point2f(right, top);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Size dSize = m_isCrop ? cv::Size(static_cast<int>(rect.size.width),
|
||||||
|
static_cast<int>(rect.size.height)) : dst.size();
|
||||||
|
bounding_rect.width = dSize.width;
|
||||||
|
bounding_rect.height = dSize.height;
|
||||||
|
|
||||||
|
warp_mat = cv::getAffineTransform(srcTri, dstTri);
|
||||||
|
cv::warpAffine(src, dst, warp_mat, dSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_isFillBlank)
|
||||||
|
{
|
||||||
|
if (m_isDesaskew)
|
||||||
|
for (cv::Point& item : maxContour)
|
||||||
|
item = hg::warpPoint(item, warp_mat);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_isCrop)
|
||||||
|
{
|
||||||
|
cv::Point offset = bounding_rect.tl();
|
||||||
|
for (cv::Point& item : maxContour)
|
||||||
|
item -= offset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hg::polyIndent(maxContour, m_indent);
|
||||||
|
hg::fillBlackBackGround(dst, maxContour);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_isCrop)
|
||||||
|
{
|
||||||
|
cv::Rect fixed_roi;
|
||||||
|
if (m_fixedSize.width > dst.cols)
|
||||||
|
{
|
||||||
|
fixed_roi.x = 0;
|
||||||
|
fixed_roi.width = dst.cols;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_roi.x = (dst.cols - m_fixedSize.width) / 2;
|
||||||
|
fixed_roi.width = m_fixedSize.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_fixedSize.height > dst.rows)
|
||||||
|
{
|
||||||
|
fixed_roi.y = 0;
|
||||||
|
fixed_roi.height = dst.rows;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fixed_roi.y = (dst.rows - m_fixedSize.height) / 2;
|
||||||
|
fixed_roi.height = m_fixedSize.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst = dst(fixed_roi);
|
||||||
|
}
|
||||||
|
|
||||||
|
pDib.release();
|
||||||
|
pDib = dst;
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
#ifndef IMAGE_APPLY_AUTO_CROP_H
|
||||||
|
#define IMAGE_APPLY_AUTO_CROP_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class CImageApplyAutoCrop : public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CImageApplyAutoCrop(bool isCrop,bool isFillBlank,bool isDesaskew,cv::Size size);
|
||||||
|
|
||||||
|
virtual ~CImageApplyAutoCrop();
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib, int side);
|
||||||
|
|
||||||
|
bool isAutoCrop() { return m_isCrop; }
|
||||||
|
|
||||||
|
bool isFillBlank() { return m_isFillBlank; }
|
||||||
|
|
||||||
|
bool isDesaskew() { return m_isDesaskew; }
|
||||||
|
|
||||||
|
double threshold() { return m_threshold; }
|
||||||
|
|
||||||
|
int noise() { return m_noise; }
|
||||||
|
|
||||||
|
int indent() { return m_indent; }
|
||||||
|
|
||||||
|
cv::Size fixedSize() { return m_fixedSize; }
|
||||||
|
|
||||||
|
void setAutoCrop(bool enabled) { m_isCrop = enabled; }
|
||||||
|
|
||||||
|
void setFillBlank(bool enabled) { m_isFillBlank = enabled; }
|
||||||
|
|
||||||
|
void setDesaskew(bool enabled) { m_isDesaskew = enabled; }
|
||||||
|
|
||||||
|
void setThreshold(double value) { m_threshold = value; }
|
||||||
|
|
||||||
|
void setNoise(int value) { m_noise = value; }
|
||||||
|
|
||||||
|
void setIndent(int value) { m_indent = value; }
|
||||||
|
|
||||||
|
void setFixedSize(cv::Size size) { m_fixedSize = size; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_isCrop;
|
||||||
|
bool m_isFillBlank;
|
||||||
|
bool m_isDesaskew;
|
||||||
|
|
||||||
|
double m_threshold;
|
||||||
|
int m_noise;
|
||||||
|
int m_indent;
|
||||||
|
cv::Size m_fixedSize;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_AUTO_CROP_H
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#include "ImageApplyBWBinaray.h"
|
||||||
|
|
||||||
|
CImageApplyBWBinaray::CImageApplyBWBinaray()
|
||||||
|
: m_threshold(127)
|
||||||
|
, m_type(THRESH_BINARY)
|
||||||
|
, m_blockSize(25)
|
||||||
|
, m_constant(5)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyBWBinaray::apply(cv::Mat& pDib,int side)
|
||||||
|
{
|
||||||
|
if (pDib.channels() == 3)
|
||||||
|
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||||||
|
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case THRESH_BINARY:
|
||||||
|
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_BINARY);
|
||||||
|
break;
|
||||||
|
case THRESH_OTSU:
|
||||||
|
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
||||||
|
break;
|
||||||
|
case ADAPTIVE_GAUSSIAN:
|
||||||
|
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||||||
|
break;
|
||||||
|
case ADAPTIVE_MEAN:
|
||||||
|
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||||||
|
break;
|
||||||
|
case ERROR_DIFFUSION:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
#ifndef IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
#define IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
|
||||||
|
class CImageApplyBWBinaray:public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ThresholdType
|
||||||
|
{
|
||||||
|
THRESH_BINARY,
|
||||||
|
THRESH_OTSU,
|
||||||
|
|
||||||
|
ADAPTIVE_GAUSSIAN,
|
||||||
|
ADAPTIVE_MEAN,
|
||||||
|
|
||||||
|
ERROR_DIFFUSION
|
||||||
|
};
|
||||||
|
|
||||||
|
CImageApplyBWBinaray();
|
||||||
|
|
||||||
|
virtual ~CImageApplyBWBinaray(void);
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
|
||||||
|
double getThreshold() { return m_threshold; }
|
||||||
|
|
||||||
|
ThresholdType getThresholdType() { return m_type; }
|
||||||
|
|
||||||
|
int getBlockSize() { return m_blockSize; }
|
||||||
|
|
||||||
|
double getConstant() { return m_constant; }
|
||||||
|
|
||||||
|
void setThreshold(double value) { m_threshold = value; }
|
||||||
|
|
||||||
|
void setThresholdType(ThresholdType type) { m_type = type; }
|
||||||
|
|
||||||
|
void setBlockSize(int value) { m_blockSize = value; }
|
||||||
|
|
||||||
|
void setConstant(double value) { m_constant = value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_threshold;
|
||||||
|
|
||||||
|
ThresholdType m_type;
|
||||||
|
|
||||||
|
int m_blockSize;
|
||||||
|
|
||||||
|
double m_constant;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //!IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include "StdAfx.h"
|
#include "ImageApplyChannel.h"
|
||||||
#include "ImageChannel.h"
|
|
||||||
using namespace cv;
|
|
||||||
|
|
||||||
CImageChannel::CImageChannel(int index)
|
CImageApplyChannel::CImageApplyChannel(int index)
|
||||||
: m_cmIndex(index)
|
: m_cmIndex(index)
|
||||||
{
|
{
|
||||||
colorTable=NULL;
|
colorTable=NULL;
|
||||||
|
@ -14,8 +12,7 @@ CImageChannel::CImageChannel(int index)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CImageApplyChannel::~CImageApplyChannel(void)
|
||||||
CImageChannel::~CImageChannel(void)
|
|
||||||
{
|
{
|
||||||
if (colorTable!=NULL)
|
if (colorTable!=NULL)
|
||||||
{
|
{
|
||||||
|
@ -23,7 +20,7 @@ CImageChannel::~CImageChannel(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageChannel::apply(cv::Mat& pDib,int side)
|
void CImageApplyChannel::apply(cv::Mat& pDib,int side)
|
||||||
{
|
{
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit CImageChannel apply");
|
//FileTools::write_log("D:\\1.txt", "Exit CImageChannel apply");
|
||||||
if (m_cmIndex>0&&m_cmIndex<4)
|
if (m_cmIndex>0&&m_cmIndex<4)
|
||||||
|
@ -50,18 +47,18 @@ void CImageChannel::apply(cv::Mat& pDib,int side)
|
||||||
//FileTools::write_log("D:\\1.txt", "Exit CImageChannel apply");
|
//FileTools::write_log("D:\\1.txt", "Exit CImageChannel apply");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageChannel::setCH(int channel)
|
void CImageApplyChannel::setCH(int channel)
|
||||||
{
|
{
|
||||||
m_cmIndex = channel;
|
m_cmIndex = channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CImageChannel::getCH()
|
int CImageApplyChannel::getCH()
|
||||||
{
|
{
|
||||||
return m_cmIndex;
|
return m_cmIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CImageChannel::RGBtoHSV(double r, double g, double b, double &h, double &s, double &v)
|
void CImageApplyChannel::RGBtoHSV(double r, double g, double b, double &h, double &s, double &v)
|
||||||
{
|
{
|
||||||
double min, max, delta;
|
double min, max, delta;
|
||||||
min = ( (r<g ? r:g) < b ) ?(r<g ? r:g):b;
|
min = ( (r<g ? r:g) < b ) ?(r<g ? r:g):b;
|
||||||
|
@ -100,7 +97,7 @@ void CImageChannel::RGBtoHSV(double r, double g, double b, double &h, double &s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageChannel::InitColorTable(short channel)
|
void CImageApplyChannel::InitColorTable(short channel)
|
||||||
{
|
{
|
||||||
//colorTable=new unsigned char();
|
//colorTable=new unsigned char();
|
||||||
colorTable=(unsigned char *)malloc(sizeof(unsigned char)*256*256*256);
|
colorTable=(unsigned char *)malloc(sizeof(unsigned char)*256*256*256);
|
||||||
|
@ -127,9 +124,9 @@ void CImageChannel::InitColorTable(short channel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat CImageChannel::colorEnhancement(cv::Mat image,short channel)
|
cv::Mat CImageApplyChannel::colorEnhancement(cv::Mat image,short channel)
|
||||||
{
|
{
|
||||||
Mat grayImage(image.rows,image.cols,CV_8UC1);
|
cv::Mat grayImage(image.rows,image.cols,CV_8UC1);
|
||||||
if (channel>3)
|
if (channel>3)
|
||||||
{
|
{
|
||||||
return grayImage;
|
return grayImage;
|
||||||
|
@ -148,9 +145,9 @@ cv::Mat CImageChannel::colorEnhancement(cv::Mat image,short channel)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat CImageChannel::FilterColor(cv::Mat image,short channel)
|
cv::Mat CImageApplyChannel::FilterColor(cv::Mat image,short channel)
|
||||||
{
|
{
|
||||||
Mat dstImage(image.rows,image.cols,CV_8UC1);
|
cv::Mat dstImage(image.rows,image.cols,CV_8UC1);
|
||||||
|
|
||||||
//int pixelSize = image.depth();
|
//int pixelSize = image.depth();
|
||||||
int channels = image.channels();
|
int channels = image.channels();
|
|
@ -1,11 +1,13 @@
|
||||||
#pragma once
|
#ifndef IMAGE_APPLY_CHANNEL_H
|
||||||
|
#define IMAGE_APPLY_CHANNEL_H
|
||||||
|
|
||||||
#include "imageapply.h"
|
#include "imageapply.h"
|
||||||
class CImageChannel :
|
|
||||||
public CImageApply
|
class CImageApplyChannel : public CImageApply
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CImageChannel(int index);
|
CImageApplyChannel(int index);
|
||||||
virtual ~CImageChannel(void);
|
virtual ~CImageApplyChannel(void);
|
||||||
|
|
||||||
virtual void apply(cv::Mat& pDib,int side);
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
void setCH(int channel);
|
void setCH(int channel);
|
||||||
|
@ -20,3 +22,4 @@ private:
|
||||||
unsigned char * colorTable;
|
unsigned char * colorTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_CHANNEL_H
|
|
@ -0,0 +1,18 @@
|
||||||
|
#include "ImageApplyCrop.h"
|
||||||
|
|
||||||
|
CImageApplyCrop::CImageApplyCrop(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CImageApplyCrop::~CImageApplyCrop(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyCrop::apply(cv::Mat& pDib,int side)
|
||||||
|
{
|
||||||
|
if (m_roi.x < 0 || m_roi.y < 0 || m_roi.br().x >= pDib.cols || m_roi.br().y >= pDib.rows || m_roi.width == 0 || m_roi.height == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pDib = pDib(m_roi).clone();
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef IMAGE_APPLY_CROP_H
|
||||||
|
#define IMAGE_APPLY_CROP_H
|
||||||
|
|
||||||
|
#include "imageapply.h"
|
||||||
|
|
||||||
|
class CImageApplyCrop : public CImageApply
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CImageApplyCrop(void);
|
||||||
|
|
||||||
|
virtual ~CImageApplyCrop(void);
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
|
||||||
|
cv::Rect getROI() { return m_roi; }
|
||||||
|
|
||||||
|
void setROI(const cv::Rect& rect) { m_roi = rect; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
cv::Rect m_roi;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_CROP_H
|
|
@ -1,10 +1,9 @@
|
||||||
#include "StdAfx.h"
|
#include "ImageApplyDiscardBlank.h"
|
||||||
#include "ImageProcDiscardBlank.h"
|
|
||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int CImageProcDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect, vector<Point>& maxContour, double scale, double thresh, int blobAreaSize)
|
int CImageApplyDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect, vector<Point>& maxContour, double scale, double thresh, int blobAreaSize)
|
||||||
{
|
{
|
||||||
Mat gray;
|
Mat gray;
|
||||||
int blockCount = 0;
|
int blockCount = 0;
|
||||||
|
@ -91,7 +90,7 @@ int CImageProcDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect,
|
||||||
return blockCount;
|
return blockCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CImageProcDiscardBlank:: Scalar_LE(cv::Scalar& val1, cv::Scalar& val2)
|
bool CImageApplyDiscardBlank:: Scalar_LE(cv::Scalar& val1, cv::Scalar& val2)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < 3; i++)
|
for(int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
|
@ -101,28 +100,28 @@ int CImageProcDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CImageProcDiscardBlank::CImageProcDiscardBlank(bool isnormal)
|
CImageApplyDiscardBlank::CImageApplyDiscardBlank(bool isnormal)
|
||||||
: devTh (10, 10, 10, 10), dSize(200),isNormalDiscard(isnormal)
|
: devTh (10, 10, 10, 10), dSize(200),isNormalDiscard(isnormal)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CImageProcDiscardBlank::~CImageProcDiscardBlank(void)
|
CImageApplyDiscardBlank::~CImageApplyDiscardBlank(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageProcDiscardBlank::setIntensity(int val)
|
void CImageApplyDiscardBlank::setIntensity(int val)
|
||||||
{
|
{
|
||||||
val = max(min(20, val), 2);
|
val = max(min(20, val), 2);
|
||||||
devTh = cv::Scalar(val, val, val, val);
|
devTh = cv::Scalar(val, val, val, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageProcDiscardBlank::setMinArea(int val)
|
void CImageApplyDiscardBlank::setMinArea(int val)
|
||||||
{
|
{
|
||||||
dSize = max(min(500, val), 100);
|
dSize = max(min(500, val), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageProcDiscardBlank::GetContours(const Mat& src, vector<vector<Point>>& contours, vector<Vec4i>& hierarchy, int retr /*= RETR_CCOMP*/)
|
void CImageApplyDiscardBlank::GetContours(const Mat& src, vector<vector<Point>>& contours, vector<Vec4i>& hierarchy, int retr /*= RETR_CCOMP*/)
|
||||||
{
|
{
|
||||||
CvMat c_image = src;
|
CvMat c_image = src;
|
||||||
MemStorage storage(cvCreateMemStorage());
|
MemStorage storage(cvCreateMemStorage());
|
||||||
|
@ -166,7 +165,7 @@ void CImageProcDiscardBlank::GetContours(const Mat& src, vector<vector<Point>>&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Mat CImageProcDiscardBlank::getRoiMat(cv::Mat& image)
|
cv::Mat CImageApplyDiscardBlank::getRoiMat(cv::Mat& image)
|
||||||
{
|
{
|
||||||
int gap = 100;
|
int gap = 100;
|
||||||
RotatedRect rect;
|
RotatedRect rect;
|
||||||
|
@ -183,7 +182,7 @@ cv::Mat CImageProcDiscardBlank::getRoiMat(cv::Mat& image)
|
||||||
return image(inRect);
|
return image(inRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageProcDiscardBlank::apply(cv::Mat& pDib,int side)
|
void CImageApplyDiscardBlank::apply(cv::Mat& pDib,int side)
|
||||||
{
|
{
|
||||||
//FileTools::write_log("D:\\1.txt", "enter CImageProcDiscardBlank apply");
|
//FileTools::write_log("D:\\1.txt", "enter CImageProcDiscardBlank apply");
|
||||||
setIntensity(isNormalDiscard?8:20);
|
setIntensity(isNormalDiscard?8:20);
|
|
@ -1,13 +1,13 @@
|
||||||
#pragma once
|
#ifndef IMAGE_APPLY_DISCARD_BLANK_H
|
||||||
#include "ImageApply.h"
|
#define IMAGE_APPLY_DISCARD_BLANK_H
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
class CImageProcDiscardBlank :
|
#include "ImageApply.h"
|
||||||
public CImageApply
|
|
||||||
|
class CImageApplyDiscardBlank : public CImageApply
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CImageProcDiscardBlank(bool isnormal=true);
|
CImageApplyDiscardBlank(bool isnormal=true);
|
||||||
virtual ~CImageProcDiscardBlank(void);
|
virtual ~CImageApplyDiscardBlank(void);
|
||||||
|
|
||||||
virtual void apply(cv::Mat& pDib,int side);
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
|
||||||
|
@ -27,3 +27,4 @@ private:
|
||||||
cv::Mat getRoiMat(cv::Mat& pDib);
|
cv::Mat getRoiMat(cv::Mat& pDib);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_DISCARD_BLANK_H
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef IMAGE_APPLY_HEADER_H
|
||||||
|
#define IMAGE_APPLY_HEADER_H
|
||||||
|
|
||||||
|
#include "../stdafx.h"
|
||||||
|
#include "ImageApply.h"
|
||||||
|
#include "ImageApplyAdjustColors.h"
|
||||||
|
#include "ImageApplyAutoCrop.h"
|
||||||
|
#include "ImageApplyBWBinaray.h"
|
||||||
|
#include "ImageApplyChannel.h"
|
||||||
|
#include "ImageApplyCrop.h"
|
||||||
|
#include "ImageApplyDiscardBlank.h"
|
||||||
|
#include "ImageApplyOutHole.h"
|
||||||
|
#include "ImageApplyResize.h"
|
||||||
|
#include "ImageApplyRotation.h"
|
||||||
|
#include "ImageApplySharpen.h"
|
||||||
|
#include "ImageApplyTextOrientation.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,204 @@
|
||||||
|
#include "ImageApplyOutHole.h"
|
||||||
|
#include "ImageProcess_Public.h"
|
||||||
|
|
||||||
|
ImageOutHole::ImageOutHole(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageOutHole::~ImageOutHole(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageOutHole::puncture(cv::Mat& front, cv::Mat& back, double threshold, float edgeScale, float borderSize, bool isDoubleFaces)
|
||||||
|
{
|
||||||
|
//二值化正反面图像
|
||||||
|
threshold = std::min(std::max(threshold, 1.0), 254.0);
|
||||||
|
cv::Mat front_thre, back_thre;
|
||||||
|
hg::threshold_Mat(front, front_thre, threshold);
|
||||||
|
hg::threshold_Mat(back, back_thre, threshold);
|
||||||
|
|
||||||
|
//反面二值化图像水平翻转
|
||||||
|
cv::flip(back_thre, back_thre, 1); //1:Horizontal
|
||||||
|
|
||||||
|
//正反面图像寻边
|
||||||
|
std::vector<std::vector<cv::Point>> contours_front, contours_back;
|
||||||
|
std::vector<cv::Vec4i> b1_front, b1_back;
|
||||||
|
hg::findContours(front_thre.clone(), contours_front, b1_front, cv::RETR_EXTERNAL);
|
||||||
|
hg::findContours(back_thre.clone(), contours_back, b1_back, cv::RETR_EXTERNAL);
|
||||||
|
|
||||||
|
//提取正反面图像最大轮廓
|
||||||
|
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
|
||||||
|
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
|
||||||
|
|
||||||
|
cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
|
||||||
|
cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
|
||||||
|
|
||||||
|
//提取正反面图像重叠部分区域
|
||||||
|
cv::Rect roi_front, roi_back;
|
||||||
|
cv::RotatedRect mask_rotatedRect;
|
||||||
|
getRoi(rrect_front, rrect_back, cv::Size(front.cols, front.rows), roi_front, roi_back, mask_rotatedRect);
|
||||||
|
|
||||||
|
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
|
||||||
|
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
|
||||||
|
|
||||||
|
//正反面二值图像做或运算,真正镂空区域保留0,其他地方填充为255
|
||||||
|
//为了避免孔洞彻底贯穿纸边,认为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连。
|
||||||
|
cv::Mat mask;
|
||||||
|
bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
|
||||||
|
|
||||||
|
//二值图像重叠图像颜色取反,膨胀,提取轮廓
|
||||||
|
std::vector<std::vector<cv::Point>> contours_mask;
|
||||||
|
std::vector<cv::Vec4i> b1_mask;
|
||||||
|
bitwise_not(mask, mask);
|
||||||
|
|
||||||
|
dilate(mask, mask, cv::Mat(), cv::Point(-1, -1), 3, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积
|
||||||
|
|
||||||
|
polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), 15); //绘制纸张矩形边缘
|
||||||
|
|
||||||
|
hg::findContours(mask.clone(), contours_mask, b1_mask, cv::RETR_TREE); //提取重叠图像轮廓
|
||||||
|
|
||||||
|
//过滤非孔洞的联通区域
|
||||||
|
std::vector<std::vector<cv::Point>> hole_contours = filterPoly(contours_mask, b1_mask, mask_rotatedRect, edgeScale, 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::Scalar color = getBackGroudColor(front(roi_front), hole_contours[i]);
|
||||||
|
cv::Mat temp = front(roi_front);
|
||||||
|
hg::fillPoly(temp, hole_contours[i], color);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isDoubleFaces)
|
||||||
|
{
|
||||||
|
int width_ = roi_back.width;
|
||||||
|
roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转,所以现在ROI也要进行相应翻转
|
||||||
|
for (size_t i = 0; i < hole_contours.size(); i++)
|
||||||
|
{
|
||||||
|
std::vector<cv::Point> hole_contour;
|
||||||
|
for (size_t j = 0; j < hole_contours[i].size(); j++)
|
||||||
|
hole_contour.push_back(cv::Point(width_ - hole_contours[i][j].x - 1, hole_contours[i][j].y));
|
||||||
|
|
||||||
|
cv::Scalar color = getBackGroudColor(back(roi_back), hole_contour);
|
||||||
|
cv::Mat temp = back(roi_back);
|
||||||
|
hg::fillPoly(temp, hole_contour, color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageOutHole::getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize,
|
||||||
|
cv::Rect& roi_front, cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect)
|
||||||
|
{
|
||||||
|
cv::Size size(static_cast<int>(rrect_front.size.width + rrect_back.size.width) / 2, static_cast<int>(rrect_front.size.height + rrect_back.size.height) / 2);
|
||||||
|
float angle = (rrect_front.angle + rrect_back.angle) / 2;
|
||||||
|
|
||||||
|
rrect_front.size = rrect_back.size = size;
|
||||||
|
rrect_front.angle = rrect_back.angle = angle;
|
||||||
|
|
||||||
|
roi_front = rrect_front.boundingRect();
|
||||||
|
roi_back = rrect_back.boundingRect();
|
||||||
|
|
||||||
|
if (roi_front.width != roi_back.width || roi_front.height != roi_back.height)
|
||||||
|
{
|
||||||
|
roi_front.height = roi_back.height;
|
||||||
|
roi_front.width = roi_back.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Point offset(0, 0);
|
||||||
|
int top = std::min(roi_front.y, roi_back.y);
|
||||||
|
if (top < 0)
|
||||||
|
{
|
||||||
|
roi_front.y -= top;
|
||||||
|
roi_back.y -= top;
|
||||||
|
roi_front.height += top;
|
||||||
|
roi_back.height += top;
|
||||||
|
offset.y += top;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = std::min(roi_front.x, roi_back.x);
|
||||||
|
if (left < 0)
|
||||||
|
{
|
||||||
|
roi_front.x -= left;
|
||||||
|
roi_back.x -= left;
|
||||||
|
roi_front.width += left;
|
||||||
|
roi_back.width += left;
|
||||||
|
offset.x += left;
|
||||||
|
}
|
||||||
|
|
||||||
|
int right = std::max(roi_front.x + roi_front.width, roi_back.x + roi_back.width);
|
||||||
|
if (right >= srcSize.width)
|
||||||
|
{
|
||||||
|
roi_front.width -= (right - srcSize.width + 1);
|
||||||
|
roi_back.width -= (right - srcSize.width + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int bottom = std::max(roi_front.y + roi_front.height, roi_back.y + roi_back.height);
|
||||||
|
if (bottom >= srcSize.height)
|
||||||
|
{
|
||||||
|
roi_front.height -= (bottom - srcSize.height + 1);
|
||||||
|
roi_back.height -= (bottom - srcSize.height + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mask_rotatedRect.center = cv::Point((roi_front.width + offset.x) / 2, (roi_front.height + offset.y) / 2);
|
||||||
|
mask_rotatedRect.size = size;
|
||||||
|
mask_rotatedRect.angle = angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::vector<cv::Point>> ImageOutHole::filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& m,
|
||||||
|
cv::RotatedRect roi, float edgeScale, float areaThreshold)
|
||||||
|
{
|
||||||
|
edgeScale = std::min(0.49f, std::max(edgeScale, 0.0f));
|
||||||
|
cv::RotatedRect roi2(roi.center, cv::Size(static_cast<int>(roi.size.width * (1 - edgeScale * 2)),
|
||||||
|
static_cast<int>(roi.size.height * (1 - edgeScale * 2))), roi.angle);
|
||||||
|
|
||||||
|
std::vector<cv::Point> vertices_roi1 = hg::getVertices(roi);
|
||||||
|
std::vector<cv::Point> vertices_roi2 = hg::getVertices(roi2);
|
||||||
|
|
||||||
|
std::vector<std::vector<cv::Point>> hole_contours;
|
||||||
|
for (size_t i = 0, length = contours.size(); i < length; i++)
|
||||||
|
{
|
||||||
|
if (m[i][2] != -1) continue;
|
||||||
|
|
||||||
|
cv::RotatedRect rrect = hg::getBoundingRect(contours[i]);
|
||||||
|
if (rrect.size.width > areaThreshold || rrect.size.height > areaThreshold) continue;
|
||||||
|
|
||||||
|
bool enabled = true;
|
||||||
|
for (size_t j = 0, count = contours[i].size(); j < count; j++)
|
||||||
|
{
|
||||||
|
cv::Point p(contours[i][j]);
|
||||||
|
double temp1 = pointPolygonTest(vertices_roi1, p, false); //判断是否在纸张内 1:内;0:上;-1:外
|
||||||
|
double temp2 = pointPolygonTest(vertices_roi2, p, false); //判断是否在边缘区域内 1:内;0:上;-1:外
|
||||||
|
//如果在纸张外,或者边缘内,视为非孔洞
|
||||||
|
if (temp1 < 0 || temp2 > 0)
|
||||||
|
{
|
||||||
|
enabled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (enabled)
|
||||||
|
hole_contours.push_back(contours[i]);
|
||||||
|
}
|
||||||
|
return hole_contours;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Scalar ImageOutHole::getBackGroudColor(const cv::Mat &image, const std::vector<cv::Point> pixelPoints)
|
||||||
|
{
|
||||||
|
if (pixelPoints.empty()) return cv::Scalar(255, 255, 255);
|
||||||
|
|
||||||
|
int channels = image.channels();
|
||||||
|
|
||||||
|
int temp[3] = { 0 };
|
||||||
|
for (size_t i = 0, length = pixelPoints.size(); i < length; ++i)
|
||||||
|
{
|
||||||
|
int x = cv::min(cv::max(0, pixelPoints[i].x), image.cols - 1);
|
||||||
|
int y = cv::min(cv::max(0, pixelPoints[i].y), image.rows - 1);
|
||||||
|
|
||||||
|
const unsigned char* ptr = image.ptr(y, x);
|
||||||
|
for (int j = 0; j < channels; ++j)
|
||||||
|
temp[j] += ptr[j];
|
||||||
|
}
|
||||||
|
|
||||||
|
return cv::Scalar(temp[0] / pixelPoints.size(), temp[1] / pixelPoints.size(), temp[2] / pixelPoints.size());
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef IMAGE_APPLY_OUT_HOLE_H
|
||||||
|
#define IMAGE_APPLY_OUT_HOLE_H
|
||||||
|
|
||||||
|
#include "opencv2/opencv.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class ImageOutHole
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
ImageOutHole(void);
|
||||||
|
|
||||||
|
~ImageOutHole(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void puncture(cv::Mat& front, cv::Mat& back, double threshold, float edgeScale, float borderSize, bool isDoubleFaces = true);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, cv::Rect& roi_front,
|
||||||
|
cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect);
|
||||||
|
|
||||||
|
std::vector<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i> &m, cv::RotatedRect roi,
|
||||||
|
float edgeScale, float areaThreshold);
|
||||||
|
|
||||||
|
cv::Scalar getBackGroudColor(const cv::Mat& image, const std::vector<cv::Point> pixelPoints);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_OUT_HOLE_H
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include "ImageApplyResize.h"
|
||||||
|
|
||||||
|
CImageApplyResize::CImageApplyResize()
|
||||||
|
: m_fx(1.0)
|
||||||
|
, m_fy(1.0)
|
||||||
|
, m_type(RATIO)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CImageApplyResize::~CImageApplyResize(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CImageApplyResize::apply(cv::Mat& pDib,int side)
|
||||||
|
{
|
||||||
|
if (m_type == RATIO)
|
||||||
|
cv::resize(pDib, pDib, cv::Size(0, 0), m_fx, m_fy);
|
||||||
|
else
|
||||||
|
cv::resize(pDib, pDib, m_dSize);
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef IMAGE_APPLY_RESIZE_H
|
||||||
|
#define IMAGE_APPLY_RESIZE_H
|
||||||
|
|
||||||
|
#include "imageapply.h"
|
||||||
|
|
||||||
|
class CImageApplyResize : public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
enum ResizeType
|
||||||
|
{
|
||||||
|
RATIO,
|
||||||
|
DSIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
CImageApplyResize();
|
||||||
|
|
||||||
|
virtual ~CImageApplyResize(void);
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
|
||||||
|
double getFX() { return m_fx; }
|
||||||
|
|
||||||
|
double getFY() { return m_fy; }
|
||||||
|
|
||||||
|
cv::Size getDSize() { return m_dSize; }
|
||||||
|
|
||||||
|
ResizeType getType() { return m_type; }
|
||||||
|
|
||||||
|
void setFX(double value) { m_fx = value; }
|
||||||
|
|
||||||
|
void setFY(double value) { m_fy = value; }
|
||||||
|
|
||||||
|
void setDSize(const cv::Size& size) { m_dSize = size; }
|
||||||
|
|
||||||
|
void setType(ResizeType type) { m_type = type; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
double m_fx;
|
||||||
|
double m_fy;
|
||||||
|
cv::Size m_dSize;
|
||||||
|
ResizeType m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_RESIZE_H
|
|
@ -1,28 +1,26 @@
|
||||||
#include "StdAfx.h"
|
#include "ImageApplyRotation.h"
|
||||||
#include "ImageRotation.h"
|
|
||||||
using namespace cv;
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
CImageRotation::CImageRotation(int index_of_orentation, bool m_bBackRotate) :m_nRotation(index_of_orentation), m_BackRotate(m_bBackRotate)
|
CImageApplyRotation::CImageApplyRotation(int index_of_orentation, bool m_bBackRotate)
|
||||||
|
: m_nRotation(index_of_orentation), m_BackRotate(m_bBackRotate)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CImageRotation::~CImageRotation()
|
CImageApplyRotation::~CImageApplyRotation()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageRotation::setRotationFlip(int flip)
|
void CImageApplyRotation::setRotationFlip(int flip)
|
||||||
{
|
{
|
||||||
m_nRotation = flip;
|
m_nRotation = flip;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CImageRotation::getRotetion()
|
int CImageApplyRotation::getRotetion()
|
||||||
{
|
{
|
||||||
return m_nRotation;
|
return m_nRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageRotation::apply(cv::Mat & pDib, int side)
|
void CImageApplyRotation::apply(cv::Mat & pDib, int side)
|
||||||
{
|
{
|
||||||
//FileTools::write_log("D:\\1.txt", "enter CImageRotation apply");
|
//FileTools::write_log("D:\\1.txt", "enter CImageRotation apply");
|
||||||
if (m_nRotation == 4)//自动文本方向识别
|
if (m_nRotation == 4)//自动文本方向识别
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef IMAGE_APPLY_ROTATION_H
|
||||||
|
#define IMAGE_APPLY_ROTATION_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class CImageApplyRotation : public CImageApply
|
||||||
|
{
|
||||||
|
enum RotationType
|
||||||
|
{
|
||||||
|
ROTATE_90_CLOCKWISE,
|
||||||
|
ROTATE_180,
|
||||||
|
ROTATE_90_COUNTERCLOCKWISE
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
CImageApplyRotation(int index_of_orentation,bool m_bBackRotate=false);
|
||||||
|
|
||||||
|
virtual ~CImageApplyRotation();
|
||||||
|
|
||||||
|
void setRotationFlip(int flip);
|
||||||
|
|
||||||
|
int getRotetion();
|
||||||
|
|
||||||
|
// ͨ¹ý CImageApply ¼Ì³Ð
|
||||||
|
virtual void apply(cv::Mat & pDib,int side) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_nRotation;
|
||||||
|
bool m_BackRotate;
|
||||||
|
int side;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_ROTATION_H
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include "ImageApplySharpen.h"
|
||||||
|
|
||||||
|
CImageApplySharpen::CImageApplySharpen()
|
||||||
|
: kernel(5, 5, CV_32FC1)
|
||||||
|
{
|
||||||
|
float kernel_data[] = { -0.1f, 0, 0, 0, -0.1f, 0, 0, 0, 0, 0, 0, 0, 1.5f, 0, 0, 0, 0, 0, 0, 0, -0.1f, 0, 0, 0, -0.1f };
|
||||||
|
memcpy(kernel.data, kernel_data, sizeof(float) * 25);
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageApplySharpen::~CImageApplySharpen()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplySharpen::apply(cv::Mat & pDib, int side)
|
||||||
|
{
|
||||||
|
cv::filter2D(pDib, pDib, pDib.depth(), kernel);
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef IMAGE_APPLY_SHARPEN_H
|
||||||
|
#define IMAGE_APPLY_SHARPEN_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class CImageApplySharpen : public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CImageApplySharpen();
|
||||||
|
|
||||||
|
virtual ~CImageApplySharpen();
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib, int side);
|
||||||
|
private:
|
||||||
|
cv::Mat kernel;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_SHARPEN_H
|
|
@ -0,0 +1,10 @@
|
||||||
|
#include "ImageApplyTextOrientation.h"
|
||||||
|
|
||||||
|
ImageApplyTextOrientation::ImageApplyTextOrientation()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ImageApplyTextOrientation::~ImageApplyTextOrientation()
|
||||||
|
{
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
#ifndef IMAGE_APPLY_TEXT_ORIENTATION_H
|
||||||
|
#define IMAGE_APPLY_TEXT_ORIENTATION_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class ImageApplyTextOrientation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageApplyTextOrientation();
|
||||||
|
~ImageApplyTextOrientation();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !IMAGE_APPLY_TEXT_ORIENTATION_H
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
#include "ImageProcess_Public.h"
|
||||||
|
|
||||||
|
namespace hg
|
||||||
|
{
|
||||||
|
void convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise)
|
||||||
|
{
|
||||||
|
CvMemStorage* storage = cvCreateMemStorage(); //
|
||||||
|
CvSeq* ptseq = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage); //ptseqstorage
|
||||||
|
|
||||||
|
//
|
||||||
|
for (const cv::Point& item : src)
|
||||||
|
{
|
||||||
|
CvPoint p;
|
||||||
|
p.x = item.x;
|
||||||
|
p.y = item.y;
|
||||||
|
cvSeqPush(ptseq, &p);
|
||||||
|
}
|
||||||
|
|
||||||
|
//¦Ìhullstorage
|
||||||
|
CvSeq* hull = cvConvexHull2(ptseq, nullptr, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 0);
|
||||||
|
|
||||||
|
//dst
|
||||||
|
dst.clear();
|
||||||
|
int hullCount = hull->total;
|
||||||
|
for (int i = 0; i < hullCount; i++)
|
||||||
|
dst.push_back(**CV_GET_SEQ_ELEM(CvPoint*, hull, i));
|
||||||
|
|
||||||
|
//storage
|
||||||
|
cvReleaseMemStorage(&storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define R_COLOR 255
|
||||||
|
void fillBlackBackGround(cv::Mat& src, std::vector<cv::Point> points)
|
||||||
|
{
|
||||||
|
uint index_top = 0;
|
||||||
|
uint index_bottom = 0;
|
||||||
|
for (size_t i = 0, length = points.size(); i < length; i++)
|
||||||
|
{
|
||||||
|
if (points[i].y < points[index_top].y)
|
||||||
|
index_top = i;
|
||||||
|
if (points[i].y > points[index_bottom].y)
|
||||||
|
index_bottom = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cv::Point> edge_left;
|
||||||
|
uint temp = index_top;
|
||||||
|
while (temp != index_bottom)
|
||||||
|
{
|
||||||
|
edge_left.push_back(points[temp]);
|
||||||
|
temp = (temp + points.size() - 1) % points.size();
|
||||||
|
}
|
||||||
|
edge_left.push_back(points[index_bottom]);
|
||||||
|
|
||||||
|
std::vector<cv::Point> edge_right;
|
||||||
|
temp = index_top;
|
||||||
|
while (temp != index_bottom)
|
||||||
|
{
|
||||||
|
edge_right.push_back(points[temp]);
|
||||||
|
temp = (temp + points.size() + 1) % points.size();
|
||||||
|
}
|
||||||
|
edge_right.push_back(points[index_bottom]);
|
||||||
|
|
||||||
|
std::vector<int> left_edge;
|
||||||
|
std::vector<int> left_ede_y;
|
||||||
|
for (size_t i = 0, length = edge_left.size() - 1; i < length; i++)
|
||||||
|
{
|
||||||
|
int y_top = edge_left[i].y;
|
||||||
|
int x_top = edge_left[i].x;
|
||||||
|
int y_bottom = edge_left[i + 1].y;
|
||||||
|
int x_bottom = edge_left[i + 1].x;
|
||||||
|
for (int y = y_top; y < y_bottom; y++)
|
||||||
|
if (y_top != y_bottom && y < src.rows)
|
||||||
|
{
|
||||||
|
left_edge.push_back(((x_bottom - x_top) * y + x_top * y_bottom - x_bottom * y_top) / (y_bottom - y_top));
|
||||||
|
left_ede_y.push_back(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t step = src.step;
|
||||||
|
unsigned char* ptr = src.data + static_cast<uint>(edge_left[0].y) * step;
|
||||||
|
for (size_t i = 0, length = cv::min(left_edge.size(), static_cast<size_t>(src.rows)); i < length; i++)
|
||||||
|
{
|
||||||
|
int offset = left_edge[i];
|
||||||
|
if (offset < src.cols - 1 && offset > 0)
|
||||||
|
memset(ptr + i * step, R_COLOR, static_cast<size_t>((offset + 1) * src.channels()));
|
||||||
|
}
|
||||||
|
std::vector<int> right_edge;
|
||||||
|
std::vector<int> right_edge_y;
|
||||||
|
for (size_t i = 0, length = edge_right.size() - 1; i < length; i++)
|
||||||
|
{
|
||||||
|
int y_top = edge_right[i].y;
|
||||||
|
int x_top = edge_right[i].x;
|
||||||
|
int y_bottom = edge_right[i + 1].y;
|
||||||
|
int x_bottom = edge_right[i + 1].x;
|
||||||
|
for (int y = y_top; y < y_bottom; y++)
|
||||||
|
if (y_top != y_bottom && y < src.rows)
|
||||||
|
{
|
||||||
|
right_edge.push_back(((x_bottom - x_top) * y + x_top * y_bottom - x_bottom * y_top) / (y_bottom - y_top));
|
||||||
|
right_edge_y.push_back(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = src.data + static_cast<uint>(edge_right[0].y) * step;
|
||||||
|
for (size_t i = 0, length = cv::min(right_edge.size(), static_cast<size_t>(src.rows)); i < length; i++)
|
||||||
|
{
|
||||||
|
int offset = right_edge[i];
|
||||||
|
if (offset < src.cols - 1 && offset > 0)
|
||||||
|
memset(ptr + i * step + offset * src.channels(), R_COLOR, step - static_cast<size_t>(offset * src.channels()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edge_left[0].y > 0)
|
||||||
|
memset(src.data, R_COLOR, static_cast<size_t>(edge_left[0].y) * step);
|
||||||
|
|
||||||
|
if (edge_left.back().y < src.rows - 1)
|
||||||
|
memset(src.data + static_cast<size_t>(edge_left.back().y) * step, R_COLOR,
|
||||||
|
static_cast<size_t>(src.rows - edge_left.back().y) * step);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fillPoly(cv::Mat & image, const std::vector<cv::Point>& contours, const cv::Scalar & color)
|
||||||
|
{
|
||||||
|
size_t count = contours.size();
|
||||||
|
cv::Point * points = new cv::Point[count];
|
||||||
|
for (size_t i = 0; i < count; i++)
|
||||||
|
points[i] = contours[i];
|
||||||
|
|
||||||
|
const cv::Point* pointss[1] = { points };
|
||||||
|
int npts[1];
|
||||||
|
npts[0] = static_cast<int>(count);
|
||||||
|
|
||||||
|
cv::fillPoly(image, pointss, npts, 1, color);
|
||||||
|
|
||||||
|
delete[] points;
|
||||||
|
}
|
||||||
|
|
||||||
|
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
|
||||||
|
{
|
||||||
|
CvMat c_image = src;
|
||||||
|
cv::MemStorage storage(cvCreateMemStorage());
|
||||||
|
CvSeq* _ccontours = nullptr;
|
||||||
|
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
|
||||||
|
|
||||||
|
if (!_ccontours)
|
||||||
|
{
|
||||||
|
contours.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
cv::Seq<CvSeq*> all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage));
|
||||||
|
size_t total = all_contours.size();
|
||||||
|
contours.resize(total);
|
||||||
|
|
||||||
|
cv::SeqIterator<CvSeq*> it = all_contours.begin();
|
||||||
|
for (size_t i = 0; i < total; i++, ++it)
|
||||||
|
{
|
||||||
|
CvSeq* c = *it;
|
||||||
|
reinterpret_cast<CvContour*>(c)->color = static_cast<int>(i);
|
||||||
|
int count = c->total;
|
||||||
|
int* data = new int[static_cast<size_t>(count * 2)];
|
||||||
|
cvCvtSeqToArray(c, data);
|
||||||
|
for (int j = 0; j < count; j++)
|
||||||
|
{
|
||||||
|
contours[i].push_back(cv::Point(data[j * 2], data[j * 2 + 1]));
|
||||||
|
}
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
hierarchy.resize(total);
|
||||||
|
it = all_contours.begin();
|
||||||
|
for (size_t i = 0; i < total; i++, ++it)
|
||||||
|
{
|
||||||
|
CvSeq* c = *it;
|
||||||
|
int h_next = c->h_next ? reinterpret_cast<CvContour*>(c->h_next)->color : -1;
|
||||||
|
int h_prev = c->h_prev ? reinterpret_cast<CvContour*>(c->h_prev)->color : -1;
|
||||||
|
int v_next = c->v_next ? reinterpret_cast<CvContour*>(c->v_next)->color : -1;
|
||||||
|
int v_prev = c->v_prev ? reinterpret_cast<CvContour*>(c->v_prev)->color : -1;
|
||||||
|
hierarchy[i] = cv::Vec4i(h_next, h_prev, v_next, v_prev);
|
||||||
|
}
|
||||||
|
|
||||||
|
storage.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour)
|
||||||
|
{
|
||||||
|
if (contour.empty()) return {};
|
||||||
|
|
||||||
|
cv::RotatedRect rect = minAreaRect(contour);
|
||||||
|
if (rect.angle < -45)
|
||||||
|
{
|
||||||
|
rect.angle += 90;
|
||||||
|
float temp = rect.size.width;
|
||||||
|
rect.size.width = rect.size.height;
|
||||||
|
rect.size.height = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy)
|
||||||
|
{
|
||||||
|
std::vector<cv::Point> maxContour;
|
||||||
|
if (contours.size() < 1) return {};
|
||||||
|
|
||||||
|
for (size_t i = 0, length = hierarchy.size(); i < length; i++)
|
||||||
|
if (hierarchy[i][3] == -1)
|
||||||
|
for (const auto &item : contours[i])
|
||||||
|
maxContour.push_back(item);
|
||||||
|
|
||||||
|
return maxContour;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<cv::Point> getVertices(const cv::RotatedRect& rect)
|
||||||
|
{
|
||||||
|
cv::Point2f box[4];
|
||||||
|
rect.points(box);
|
||||||
|
std::vector<cv::Point> points;
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
points.push_back(cv::Point(box[i]));
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
void polyIndent(std::vector<cv::Point>& points, float indent)
|
||||||
|
{
|
||||||
|
static cv::Point zero(0, 0);
|
||||||
|
cv::Point center = getBoundingRect(points).center;
|
||||||
|
for (cv::Point& item : points)
|
||||||
|
{
|
||||||
|
cv::Point vec = item - center;
|
||||||
|
if (vec != zero)
|
||||||
|
{
|
||||||
|
int length = vec.x * vec.x + vec.y * vec.y;
|
||||||
|
float x = cv::sqrt(static_cast<float>(vec.x * vec.x / length)) * indent;
|
||||||
|
float y = cv::sqrt(static_cast<float>(vec.y * vec.y / length)) * indent;
|
||||||
|
|
||||||
|
if (vec.x < 0) x *= -1.0f;
|
||||||
|
if (vec.y < 0) y *= -1.0f;
|
||||||
|
|
||||||
|
item.x -= static_cast<int>(x);
|
||||||
|
item.y -= static_cast<int>(y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
hg::convexHull(points, points);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat transforColor(const cv::Mat& src)
|
||||||
|
{
|
||||||
|
if (src.channels() == 1) return src.clone();
|
||||||
|
|
||||||
|
std::vector<cv::Mat> channels(3);
|
||||||
|
cv::split(src, channels);
|
||||||
|
|
||||||
|
cv::Mat temp, dst;
|
||||||
|
bitwise_or(channels[0], channels[1], temp);
|
||||||
|
bitwise_or(channels[2], temp, dst);
|
||||||
|
temp.release();
|
||||||
|
|
||||||
|
for (cv::Mat& index : channels)
|
||||||
|
index.release();
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre)
|
||||||
|
{
|
||||||
|
if (src.channels() == 3)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (cl_res.context)
|
||||||
|
transforColor_threshold_opencl(src, dst, static_cast<uchar>(thre));
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
cv::Mat gray = transforColor(src);
|
||||||
|
cv::threshold(gray, dst, thre, 255, cv::THRESH_BINARY);
|
||||||
|
gray.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cv::threshold(src, dst, thre, 255, cv::THRESH_BINARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Point warpPoint(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
|
||||||
|
|
||||||
|
cv::Mat dst = warp_mat * src;
|
||||||
|
double* ptr = reinterpret_cast<double*>(dst.data);
|
||||||
|
return cv::Point(static_cast<int>(ptr[0]), static_cast<int>(ptr[1]));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef IMAGE_PROCESS_PUBLIC_H
|
||||||
|
#define IMAGE_PROCESS_PUBLIC_H
|
||||||
|
|
||||||
|
#include "opencv2/opencv.hpp"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace hg
|
||||||
|
{
|
||||||
|
void convexHull(const std::vector<cv::Point>& src, std::vector<cv::Point>& dst, bool clockwise = false);
|
||||||
|
|
||||||
|
void fillBlackBackGround(cv::Mat& src, std::vector<cv::Point> points);
|
||||||
|
|
||||||
|
void fillPoly(cv::Mat& image, const std::vector<cv::Point>& contours, const cv::Scalar& color);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
std::vector<cv::Point> getMaxContour(const std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& hierarchy);
|
||||||
|
|
||||||
|
std::vector<cv::Point> getVertices(const cv::RotatedRect& rect);
|
||||||
|
|
||||||
|
void polyIndent(std::vector<cv::Point>& points, float indent);
|
||||||
|
|
||||||
|
void threshold_Mat(const cv::Mat& src, cv::Mat& dst, double thre);
|
||||||
|
|
||||||
|
cv::Mat transforColor(const cv::Mat& src);
|
||||||
|
|
||||||
|
cv::Point warpPoint(cv::Point p, const cv::Mat& warp_mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !IMAGE_PROCESS_C_H
|
|
@ -1,20 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "ImageApply.h"
|
|
||||||
class CImageRotation :
|
|
||||||
public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CImageRotation(int index_of_orentation,bool m_bBackRotate=false);
|
|
||||||
virtual ~CImageRotation();
|
|
||||||
void setRotationFlip(int flip);
|
|
||||||
int getRotetion();
|
|
||||||
// ͨ¹ý CImageApply ¼Ì³Ð
|
|
||||||
virtual void apply(cv::Mat & pDib,int side) override;
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
int m_nRotation;
|
|
||||||
bool m_BackRotate;
|
|
||||||
int side;
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
#include "StdAfx.h"
|
|
||||||
#include "TextDirection.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CTextDirection::CTextDirection(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CTextDirection::~CTextDirection(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CTextDirection::applyInPlace(cv::Mat& pDib)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CTextDirection::getResult()
|
|
||||||
{
|
|
||||||
return m_res;
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#include "ImageApply.h"
|
|
||||||
class CTextDirection :
|
|
||||||
public CImageApply
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CTextDirection(void);
|
|
||||||
virtual ~CTextDirection(void);
|
|
||||||
|
|
||||||
virtual void applyInPlace(cv::Mat& pDib);
|
|
||||||
|
|
||||||
bool getResult();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_res;
|
|
||||||
};
|
|
||||||
|
|
|
@ -74,4 +74,5 @@ void config_new::set_unused_default_value(void)
|
||||||
ms.v_setting = 0;
|
ms.v_setting = 0;
|
||||||
ms.speed_set_enable = 0;
|
ms.speed_set_enable = 0;
|
||||||
ms.key_staple_enable = 0;
|
ms.key_staple_enable = 0;
|
||||||
|
ms.scan_busy_motor_stop = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,9 +97,10 @@ typedef union Motor_Setting {
|
||||||
unsigned int iic_config : 1;
|
unsigned int iic_config : 1;
|
||||||
unsigned int v_setting : 2;
|
unsigned int v_setting : 2;
|
||||||
unsigned int speed_set_enable : 1;
|
unsigned int speed_set_enable : 1;
|
||||||
|
unsigned int scan_busy_motor_stop : 1;
|
||||||
unsigned int papar_type : 4;
|
unsigned int papar_type : 4;
|
||||||
unsigned int color_model : 1;
|
unsigned int color_model : 1;
|
||||||
unsigned int reserve : 3;
|
unsigned int reserve : 2;
|
||||||
};
|
};
|
||||||
} MotorSetting;
|
} MotorSetting;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "twainEx.h"
|
#include "twainEx.h"
|
||||||
#include "jpeglib.h"
|
#include "jpeglib.h"
|
||||||
#include "ImageApply.h"
|
#include "ImageProcess/ImageApplyHeaders.h"
|
||||||
#include "hugaotwainds.h"
|
#include "hugaotwainds.h"
|
||||||
#include "filetools.h"
|
#include "filetools.h"
|
||||||
#include "UsbScanEx.h"
|
#include "UsbScanEx.h"
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<ProjectGuid>{F928F998-CD13-478E-8D23-5943C2B108F5}</ProjectGuid>
|
<ProjectGuid>{F928F998-CD13-478E-8D23-5943C2B108F5}</ProjectGuid>
|
||||||
<Keyword>MFCDLLProj</Keyword>
|
<Keyword>MFCDLLProj</Keyword>
|
||||||
<RootNamespace>hugaotwainds</RootNamespace>
|
<RootNamespace>hugaotwainds</RootNamespace>
|
||||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
@ -213,7 +213,6 @@
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="AboutHuaGoDlg.cpp" />
|
<ClCompile Include="AboutHuaGoDlg.cpp" />
|
||||||
<ClCompile Include="AutoCrop.cpp" />
|
|
||||||
<ClCompile Include="BasicSetting.cpp" />
|
<ClCompile Include="BasicSetting.cpp" />
|
||||||
<ClCompile Include="BrightSetting.cpp" />
|
<ClCompile Include="BrightSetting.cpp" />
|
||||||
<ClCompile Include="cJSON.cpp" />
|
<ClCompile Include="cJSON.cpp" />
|
||||||
|
@ -234,18 +233,48 @@
|
||||||
<ClCompile Include="GScanO200.cpp" />
|
<ClCompile Include="GScanO200.cpp" />
|
||||||
<ClCompile Include="gscn_drv.cpp" />
|
<ClCompile Include="gscn_drv.cpp" />
|
||||||
<ClCompile Include="hugaotwainds.cpp" />
|
<ClCompile Include="hugaotwainds.cpp" />
|
||||||
<ClCompile Include="ImageAdjustColors.cpp" />
|
|
||||||
<ClCompile Include="ImageApply.cpp" />
|
|
||||||
<ClCompile Include="ImageApplyCrop.cpp" />
|
|
||||||
<ClCompile Include="ImageApplyResize.cpp" />
|
|
||||||
<ClCompile Include="ImageBWBinaray.cpp" />
|
|
||||||
<ClCompile Include="ImageChannel.cpp" />
|
|
||||||
<ClCompile Include="ImageMatQueue.cpp" />
|
<ClCompile Include="ImageMatQueue.cpp" />
|
||||||
<ClCompile Include="ImageMultiOutput.cpp" />
|
<ClCompile Include="ImageMultiOutput.cpp" />
|
||||||
<ClCompile Include="ImageOutHole.cpp" />
|
|
||||||
<ClCompile Include="ImageProcDiscardBlank.cpp" />
|
|
||||||
<ClCompile Include="ImageProcess.cpp" />
|
<ClCompile Include="ImageProcess.cpp" />
|
||||||
<ClCompile Include="ImageRotation.cpp" />
|
<ClCompile Include="ImageProcess\ImageApply.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyAdjustColors.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyAutoCrop.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyBWBinaray.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyChannel.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyCrop.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyDiscardBlank.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyOutHole.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyResize.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyRotation.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplySharpen.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyTextOrientation.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageProcess_Public.cpp">
|
||||||
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="ImageTranferBW.cpp" />
|
<ClCompile Include="ImageTranferBW.cpp" />
|
||||||
<ClCompile Include="ImageTranferMat.cpp" />
|
<ClCompile Include="ImageTranferMat.cpp" />
|
||||||
<ClCompile Include="IndicatorDlg.cpp" />
|
<ClCompile Include="IndicatorDlg.cpp" />
|
||||||
|
@ -264,7 +293,6 @@
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="SupperScanImageMTF.cpp" />
|
<ClCompile Include="SupperScanImageMTF.cpp" />
|
||||||
<ClCompile Include="TextDirection.cpp" />
|
|
||||||
<ClCompile Include="TWAINContainer.cpp" />
|
<ClCompile Include="TWAINContainer.cpp" />
|
||||||
<ClCompile Include="TWAINContainerBool.cpp" />
|
<ClCompile Include="TWAINContainerBool.cpp" />
|
||||||
<ClCompile Include="TWAINContainerFix32.cpp" />
|
<ClCompile Include="TWAINContainerFix32.cpp" />
|
||||||
|
@ -284,7 +312,6 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="AboutHuaGoDlg.h" />
|
<ClInclude Include="AboutHuaGoDlg.h" />
|
||||||
<ClInclude Include="AutoCrop.h" />
|
|
||||||
<ClInclude Include="BasicSetting.h" />
|
<ClInclude Include="BasicSetting.h" />
|
||||||
<ClInclude Include="BrightSetting.h" />
|
<ClInclude Include="BrightSetting.h" />
|
||||||
<ClInclude Include="cJSON.h" />
|
<ClInclude Include="cJSON.h" />
|
||||||
|
@ -309,18 +336,23 @@
|
||||||
<ClInclude Include="hugaotwainds.h" />
|
<ClInclude Include="hugaotwainds.h" />
|
||||||
<ClInclude Include="IConfig.h" />
|
<ClInclude Include="IConfig.h" />
|
||||||
<ClInclude Include="IGDevice.h" />
|
<ClInclude Include="IGDevice.h" />
|
||||||
<ClInclude Include="ImageAdjustColors.h" />
|
|
||||||
<ClInclude Include="ImageApply.h" />
|
|
||||||
<ClInclude Include="ImageApplyCrop.h" />
|
|
||||||
<ClInclude Include="ImageApplyResize.h" />
|
|
||||||
<ClInclude Include="ImageBWBinaray.h" />
|
|
||||||
<ClInclude Include="ImageChannel.h" />
|
|
||||||
<ClInclude Include="ImageMatQueue.h" />
|
<ClInclude Include="ImageMatQueue.h" />
|
||||||
<ClInclude Include="ImageMultiOutput.h" />
|
<ClInclude Include="ImageMultiOutput.h" />
|
||||||
<ClInclude Include="ImageOutHole.h" />
|
|
||||||
<ClInclude Include="ImageProcDiscardBlank.h" />
|
|
||||||
<ClInclude Include="ImageProcess.h" />
|
<ClInclude Include="ImageProcess.h" />
|
||||||
<ClInclude Include="ImageRotation.h" />
|
<ClInclude Include="ImageProcess\ImageApply.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyAdjustColors.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyAutoCrop.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyBWBinaray.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyChannel.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyCrop.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyDiscardBlank.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyHeaders.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyOutHole.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyResize.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyRotation.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplySharpen.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyTextOrientation.h" />
|
||||||
|
<ClInclude Include="ImageProcess\ImageProcess_Public.h" />
|
||||||
<ClInclude Include="ImageTranferBW.h" />
|
<ClInclude Include="ImageTranferBW.h" />
|
||||||
<ClInclude Include="ImageTranferMat.h" />
|
<ClInclude Include="ImageTranferMat.h" />
|
||||||
<ClInclude Include="ImageTransfer.h" />
|
<ClInclude Include="ImageTransfer.h" />
|
||||||
|
@ -341,7 +373,6 @@
|
||||||
<ClInclude Include="StopWatch.h" />
|
<ClInclude Include="StopWatch.h" />
|
||||||
<ClInclude Include="SupperScanImageMTF.h" />
|
<ClInclude Include="SupperScanImageMTF.h" />
|
||||||
<ClInclude Include="targetver.h" />
|
<ClInclude Include="targetver.h" />
|
||||||
<ClInclude Include="TextDirection.h" />
|
|
||||||
<ClInclude Include="TWAINContainer.h" />
|
<ClInclude Include="TWAINContainer.h" />
|
||||||
<ClInclude Include="TWAINContainerBool.h" />
|
<ClInclude Include="TWAINContainerBool.h" />
|
||||||
<ClInclude Include="TWAINContainerFix32.h" />
|
<ClInclude Include="TWAINContainerFix32.h" />
|
||||||
|
|
|
@ -117,42 +117,12 @@
|
||||||
<ClCompile Include="JsonConfig.cpp">
|
<ClCompile Include="JsonConfig.cpp">
|
||||||
<Filter>公共库</Filter>
|
<Filter>公共库</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ImageProcDiscardBlank.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageAdjustColors.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageApply.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageApplyCrop.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageApplyResize.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageChannel.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SupperScanImageMTF.cpp">
|
<ClCompile Include="SupperScanImageMTF.cpp">
|
||||||
<Filter>图像处理</Filter>
|
<Filter>图像处理</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="TextDirection.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="AboutHuaGoDlg.cpp">
|
<ClCompile Include="AboutHuaGoDlg.cpp">
|
||||||
<Filter>UI</Filter>
|
<Filter>UI</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="AutoCrop.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageRotation.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ImageBWBinaray.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="CTwainMutex.cpp">
|
<ClCompile Include="CTwainMutex.cpp">
|
||||||
<Filter>代码文件</Filter>
|
<Filter>代码文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -165,9 +135,6 @@
|
||||||
<ClCompile Include="jpeglib.cpp">
|
<ClCompile Include="jpeglib.cpp">
|
||||||
<Filter>USB通信</Filter>
|
<Filter>USB通信</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ImageOutHole.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="cJSON.cpp">
|
<ClCompile Include="cJSON.cpp">
|
||||||
<Filter>代码文件</Filter>
|
<Filter>代码文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -198,12 +165,51 @@
|
||||||
<ClCompile Include="UsbScanEx.cpp">
|
<ClCompile Include="UsbScanEx.cpp">
|
||||||
<Filter>USB通信</Filter>
|
<Filter>USB通信</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ImageMultiOutput.cpp">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="config_new.cpp">
|
<ClCompile Include="config_new.cpp">
|
||||||
<Filter>代码文件</Filter>
|
<Filter>代码文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageMultiOutput.cpp">
|
||||||
|
<Filter>代码文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApply.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyAdjustColors.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyAutoCrop.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyBWBinaray.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyChannel.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyCrop.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyDiscardBlank.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyOutHole.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyResize.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyRotation.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplyTextOrientation.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageProcess_Public.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="ImageProcess\ImageApplySharpen.cpp">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="hugaotwainds.def">
|
<None Include="hugaotwainds.def">
|
||||||
|
@ -322,45 +328,15 @@
|
||||||
<ClInclude Include="JsonConfig.h">
|
<ClInclude Include="JsonConfig.h">
|
||||||
<Filter>公共库</Filter>
|
<Filter>公共库</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ImageAdjustColors.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageProcDiscardBlank.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageApply.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageApplyCrop.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageApplyResize.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageChannel.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="SupperScanImageMTF.h">
|
<ClInclude Include="SupperScanImageMTF.h">
|
||||||
<Filter>图像处理</Filter>
|
<Filter>图像处理</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="TextDirection.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="twainEx.h">
|
<ClInclude Include="twainEx.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="AboutHuaGoDlg.h">
|
<ClInclude Include="AboutHuaGoDlg.h">
|
||||||
<Filter>UI</Filter>
|
<Filter>UI</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="AutoCrop.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageRotation.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageBWBinaray.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="CTwainMutex.h">
|
<ClInclude Include="CTwainMutex.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -376,9 +352,6 @@
|
||||||
<ClInclude Include="filetools.h">
|
<ClInclude Include="filetools.h">
|
||||||
<Filter>公共库</Filter>
|
<Filter>公共库</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ImageOutHole.h">
|
|
||||||
<Filter>图像处理</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ImageMultiOutput.h">
|
<ClInclude Include="ImageMultiOutput.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
@ -430,6 +403,48 @@
|
||||||
<ClInclude Include="config_new.h">
|
<ClInclude Include="config_new.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApply.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyAdjustColors.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyAutoCrop.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyBWBinaray.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyChannel.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyCrop.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyDiscardBlank.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyOutHole.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyResize.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyRotation.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyTextOrientation.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageProcess_Public.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplyHeaders.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ImageProcess\ImageApplySharpen.h">
|
||||||
|
<Filter>图像处理</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="hugaotwainds.rc">
|
<ResourceCompile Include="hugaotwainds.rc">
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LocalDebuggerCommand>C:\Program Files\XnView\xnview.exe</LocalDebuggerCommand>
|
<LocalDebuggerCommand>E:\软件安装包\xnviewer\xnviewer\xnview.exe</LocalDebuggerCommand>
|
||||||
<LocalDebuggerWorkingDirectory>C:\Windows\twain_32\huagoscan</LocalDebuggerWorkingDirectory>
|
<LocalDebuggerWorkingDirectory>C:\Windows\twain_32\huagoscan</LocalDebuggerWorkingDirectory>
|
||||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
Loading…
Reference in New Issue