1.调整了updatecaps中的一个协议类型与实际转换不匹配的问题

2.调整了异常提示的代码逻辑,调整为在twain中提示,以避免出现线程退出异常导致软件崩溃;
3.增加了除穿孔功能;
4.调整了uionly模式下的窗体置顶问题;
This commit is contained in:
pm 2019-09-04 09:46:32 +08:00
parent 7aa3df7bee
commit aed1f401f9
31 changed files with 938 additions and 338 deletions

View File

@ -3,10 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hugaotwainds", "hugaotwainds\hugaotwainds.vcxproj", "{F928F998-CD13-478E-8D23-5943C2B108F5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.WPF", "..\wpf源码\Sample.WPF.csproj", "{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Twacker", "H:\官方Twain工具及例子\Twacker source\TWAIN toolkit\twacker\Twacker.vcxproj", "{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -39,38 +35,6 @@ Global
{F928F998-CD13-478E-8D23-5943C2B108F5}.Release|x64.Build.0 = Release|x64
{F928F998-CD13-478E-8D23-5943C2B108F5}.Release|x86.ActiveCfg = Release|Win32
{F928F998-CD13-478E-8D23-5943C2B108F5}.Release|x86.Build.0 = Release|Win32
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|Win32.ActiveCfg = Debug|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|x64.ActiveCfg = Debug|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|x86.ActiveCfg = Debug|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Debug|x86.Build.0 = Debug|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|Any CPU.Build.0 = Release|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|Win32.ActiveCfg = Release|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|x64.ActiveCfg = Release|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|x86.ActiveCfg = Release|x86
{1715C2B7-5C35-4F8B-9D9B-8D68A3D5284D}.Release|x86.Build.0 = Release|x86
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|Any CPU.ActiveCfg = Debug|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|Mixed Platforms.ActiveCfg = Debug|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|Mixed Platforms.Build.0 = Debug|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|Win32.ActiveCfg = Debug|Win32
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|Win32.Build.0 = Debug|Win32
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|x64.ActiveCfg = Debug|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|x64.Build.0 = Debug|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Debug|x86.ActiveCfg = Debug|Win32
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|Any CPU.ActiveCfg = Release|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|Mixed Platforms.ActiveCfg = Release|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|Mixed Platforms.Build.0 = Release|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|Win32.ActiveCfg = Release|Win32
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|Win32.Build.0 = Release|Win32
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|x64.ActiveCfg = Release|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|x64.Build.0 = Release|x64
{3A13A242-7ED1-4167-8C39-15ABC3AD3A8A}.Release|x86.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

Binary file not shown.

View File

@ -6,8 +6,8 @@
#include <math.h>
#include "PublicFunc.h"
CAutoCrop::CAutoCrop( bool bFill,bool bautoDeScrew, bool bCrop,SIZE dstsize,SIZE originSize)
:m_bAutoDescrew(bautoDeScrew), m_bCrop(bCrop), m_bFill(bFill),m_dstSize(dstsize),m_originSize(originSize)
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)
{
}
@ -19,12 +19,76 @@ 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;
//RotatedRect rect;
//vector<Point> contour;
//double scale = 0.25;
//double thresh = 70;
//int blobSize = 200;
//int edgeWidth =5;
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;
}
//szActual.width=m_dstSize.cx;
//szActual.height=m_dstSize.cy;
//szOrg.width=m_originSize.cx;
//szOrg.height=m_originSize.cy;
//rectCrop.x = (dib.cols- szOrg.width) / 2 ;
//rectCrop.y = 0;
//rectCrop.width = szOrg.width;
//rectCrop.height = szOrg.height;
Rect rectImage(0, 0, dib.cols, dib.rows);
//Size CropOrg = (rectCrop & rectImage).size ();
dib = dib(rectCrop);
}
//imwrite("1.bmp",dib);
#if 0
ProcessRect(dib, rect, contour, scale, thresh, blobSize);
//XdPrint("Begin m_bFill \n");
if (m_bFill)
@ -54,8 +118,9 @@ void CAutoCrop::apply(cv::Mat & dib,int side)
dib=FixedCut(dib,side);
//XdPrint("m_bCrop \n");
}
#endif // false
}
static int i=0;
void CAutoCrop::setFill(bool val)
{
m_bFill = val;
@ -76,6 +141,7 @@ bool CAutoCrop::getCrop()
return m_bCrop;
}
#if 0
Point2f CAutoCrop::RotateP2P(Point2f p, Point2f center, double Angle)
{
double h = Angle * M_PI / 180;
@ -353,30 +419,412 @@ void CAutoCrop::GetContours(const Mat& src, vector<vector<Point>>& contours, vec
hierarchy[i] = Vec4i(h_next, h_prev, v_next, v_prev);
}
}
#endif // false
void CAutoCrop::MyFillPoly(Mat& img, vector<vector<Point>> contours, const Scalar& color, int lineType, int shift, Point offset)
void CAutoCrop::sharpen(Mat& mat)
{
Point** ptsptr = new Point*[contours.size()];
int length1 = contours.size();
int* npts = new int[length1];
for (size_t i = 0; i < length1; i++)
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)
{
int length2 = contours[i].size();
npts[i] = length2;
ptsptr[i] = new Point[length2];
for (size_t j = 0; j < length2; j++)
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(img, (const Point**)ptsptr, npts, length1, color, lineType, shift, offset);
fillPoly(src, (const Point**)ptsptr, (const int*)npts, ncontours, color, lineType, shift, offset);
for (size_t i = 0; i < length1; i++)
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();
}
vector<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 < channels.size();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);
}
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;
}

View File

@ -7,7 +7,7 @@ using namespace cv;
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));
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);
@ -21,23 +21,46 @@ public:
int m_side;
private:
cv::Point2f RotateP2P(cv::Point2f p, cv::Point2f center, double Angle);
void RotateImage(cv::Mat& image, cv::RotatedRect rotatedRect, bool bCrop = true,bool fillBlack=true);
//cv::Point2f RotateP2P(cv::Point2f p, cv::Point2f center, double Angle);
//void RotateImage(cv::Mat& image, cv::RotatedRect rotatedRect, bool bCrop = true,bool fillBlack=true);
int ProcessRect(cv::Mat& image, cv::RotatedRect &rotatedRect, std::vector<cv::Point> & maxContour, double scale, double thresh, int blobAreaSize);
void fillBlack(cv:: Mat & dib, std::vector<cv::Point>& contour, int edge = 10);
cv::Mat AutomaticDeskew(cv::Mat image,int thres,float scale);
cv::Mat FixedCut(cv::Mat image,int side);
void MyFillPoly(Mat& img, vector<vector<Point>> contours, const Scalar& color, int lineType=8, int shift=0,
Point offset=Point() );
//void fillrect(InputOutputArray img, InputArrayOfArrays pts,
// const Scalar& color, int lineType, int shift, Point offset);
int range(int low, int up, int value);
void GetContours(const Mat& src, cv::vector<cv::vector<Point>>& contours, cv::vector<Vec4i>& hierarchy, int retr = RETR_CCOMP);
//int ProcessRect(cv::Mat& image, cv::RotatedRect &rotatedRect, std::vector<cv::Point> & maxContour, double scale, double thresh, int blobAreaSize);
//void fillBlack(cv:: Mat & dib, std::vector<cv::Point>& contour, int edge = 10);
//cv::Mat AutomaticDeskew(cv::Mat image,int thres,float scale);
//cv::Mat FixedCut(cv::Mat image,int side);
//void MyFillPoly(Mat& img, vector<vector<Point>> contours, const Scalar& color, int lineType=8, int shift=0,
// Point offset=Point() );
////void fillrect(InputOutputArray img, InputArrayOfArrays pts,
//// const Scalar& color, int lineType, int shift, Point offset);
//int range(int low, int up, int value);
//void GetContours(const Mat& src, cv::vector<cv::vector<Point>>& contours, cv::vector<Vec4i>& hierarchy, int retr = RETR_CCOMP);
bool m_bCrop;
bool m_bFill;
bool m_bAutoDescrew;
SIZE m_dstSize;
SIZE m_originSize;
int tw_pixType;
enum RC_TYPE
{
RC_INVALID = 0x0,
RC_ROTATED = 0x1,
RC_CUT = 0x2,
RC_BLACK_BACKGROUD = 0x4,
RC_SHARPING=0x8
};
private:
void sharpen(Mat& mat);
Point2f warpPoint(Point p, const Mat& warp_mat);
void rotated_and_cut(Mat &src,Mat& dst,int flags,double threshold,int noise,int indent);
void fillBlackBackGround(Mat& src, vector<Point> points, float indent);
void polyIndent(vector<Point>& points, float indent);
void fill_poly(Mat& src, const vector<vector<Point>>& contours, const Scalar& color, int lineType = 8, int shift = 0, Point offset = Point());
RotatedRect getBoundingRect(const vector<Point>& contour);
vector<Point> getMaxContour(const vector<vector<Point>>& contours, const vector<Vec4i>& hierarchy);
void 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));
void threshold_Mat(const Mat& src, Mat& dst, double thre, int noise);
Mat transforColor(const Mat& src);
void MyConvexHull(const vector<Point>& src, vector<Point>& dst, bool clockwise = false);
};

Binary file not shown.

View File

@ -132,7 +132,21 @@ class ImageTranferBW : public ImageTransfer
public:
ImageTranferBW(cv::Mat& mat)
{
threshold(mat,mat,220.0,255.0,CV_THRESH_BINARY);
//threshold(mat,mat,200,255,CV_THRESH_BINARY);
StopWatch sw;
sw.start();
threshold(mat,mat,200,255,CV_THRESH_BINARY);
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);
//adaptiveThreshold(mat,mat,255,0,1,5,12);
//bitwise_not(mat,mat);
sw.stop();
double time=sw.time_run();
XdPrint("time eplesed :%f\n",time);
//imwrite("threshold.bmp",mat);
m_width = mat.cols;
m_height = mat.rows;
@ -506,6 +520,7 @@ CScanner_FreeImage::CScanner_FreeImage() :
initialDictionary();
// set default caps
resetScanner();
InitMSGMap();
g_drv.open(0x064B, 0x7823);
}
@ -515,6 +530,22 @@ CScanner_FreeImage::~CScanner_FreeImage()
//g_drv.reset();
}
void CScanner_FreeImage::InitMSGMap()
{
if (ntcMsg.size()>0){
ntcMsg.clear();
}
ntcMsg[COUNT_MODE]=StringToUtf("计数模式,请先退出计数模式!");
ntcMsg[NO_FEED]=StringToUtf("无纸,请放置纸张!");
ntcMsg[OPEN_COVER]=StringToUtf("扫描仪开盖!");
ntcMsg[FEED_IN_ERROR]=StringToUtf("拾纸错误!");
ntcMsg[PAPER_JAM]=StringToUtf("卡纸!");
ntcMsg[DETECT_DOUBLE_FEED]=StringToUtf("双张!");
ntcMsg[DETECT_STAPLE]=StringToUtf("订书针!");
ntcMsg[PAPER_SKEW]=StringToUtf("纸张歪斜!");
ntcMsg[HARDWARE_ERROR]=StringToUtf("硬件错误!");
ntcMsg[PC_SCAN_BUSY_or_ERROR]=StringToUtf("PC错误!");
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::resetScanner()
@ -547,7 +578,7 @@ SFreeImage* CScanner_FreeImage::getSetting() const
{
return (SFreeImage*)this;
}
//static bool isreported;
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::acquireImage(bool bscan)
{
@ -560,56 +591,6 @@ bool CScanner_FreeImage::acquireImage(bool bscan)
{
if (getDeviceOnline())
{
USBCB checkStatus= g_drv.Get_Scanner_Status();
UINT32 u32Data=checkStatus.u32_Data;
std::string notify=StringToUtf("提示");
int res;
std::string msg;
switch (u32Data)
{
case COUNT_MODE:
{
msg=StringToUtf("计数模式,请先退出计数模式!");
MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),msg.c_str(),notify.c_str(),MB_ICONINFORMATION|MB_OK);
return false;
}
//case OPEN_COVER:
// {
// msg=StringToUtf("开盖!请关闭扫描仪盖!");
// MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),msg.c_str(),notify.c_str(),MB_ICONINFORMATION|MB_OK);
// return false;
// }
//case PAPER_JAM:
// {
// msg=StringToUtf("卡纸!");
// MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),msg.c_str(),notify.c_str(),MB_ICONINFORMATION|MB_OK);
// return false;
// }
//case HARDWARE_ERROR:
// {
// msg=StringToUtf("硬件错误!");
// MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),msg.c_str(),notify.c_str(),MB_ICONINFORMATION|MB_OK);
// return false;
// }
//case PC_SCAN_BUSY_or_ERROR:
// {
// msg=StringToUtf("PC错误");
// MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),msg.c_str(),notify.c_str(),MB_ICONINFORMATION|MB_OK);
// return false;
// }
default:
break;
}
while (!isPaperOn())
{
std::string cvt=StringToUtf("纸仓内无纸,请放纸!");
res= MessageBox(NULL, cvt.c_str(),notify.c_str(), MB_OKCANCEL | MB_ICONINFORMATION);
switch (res)
{
case IDCANCEL:
return false;
}
}
UpdateList();
g_drv.setlist(m_iaList);
g_drv.SetIsDuplex(m_bDuplex);
@ -655,15 +636,17 @@ bool CScanner_FreeImage::acquireImage(bool bscan)
USBCB usbcb = { CONFIGURED_DATA , cfg_Value,0 };
g_drv.set_decompress_pix_type(m_HardWareParams.PixType);
g_drv.SetOutHoleParam(m_OutHole);
g_drv.SetMultiOutPutRParams(m_bMultiOutput);
g_drv.Config_Scanner(&usbcb);
g_drv.run();
g_drv.Scanner_StartScan(m_wScanCount);
//isreported=false;
}
else
{
std::string cvt=StringToUtf("请检查电源或USB通信是否正常!");
std::string notify=StringToUtf("提示");
MyMessageBox((TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_OK| MB_ICONINFORMATION);
MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),(TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_SYSTEMMODAL|MB_OK| MB_ICONINFORMATION);
return false;
}
}
@ -671,7 +654,22 @@ bool CScanner_FreeImage::acquireImage(bool bscan)
#ifdef HW_VER
m_matDib.release();
//m_matDib=imread("D:/1.jpg");
int ret = g_drv.aquire_image(m_matDib);
UINT32 ret = g_drv.aquire_image(m_matDib);
//CString str;
//str.Format("error_code :%d\n",ret);
//string ss((LPCTSTR)str);
//FileTools::write_log("D:\\1.txt",ss);
if (ret!=0)
{
/*if (!isreported)
{*/
//isreported=true;
std::string notify=StringToUtf("提示");
MessageBox(theApp.m_pMainWnd->GetSafeHwnd(),(TCHAR*)ntcMsg[ret].c_str(),(TCHAR*)notify.c_str(),MB_SYSTEMMODAL|MB_ICONINFORMATION|MB_OK);
g_drv.Set_ErrorCode(0);
return false;
/* }*/
}
//imwrite("1.bmp",m_matDib);
if (ret)
{
@ -686,6 +684,17 @@ bool CScanner_FreeImage::acquireImage(bool bscan)
return false;
}
if (m_bMultiOutput)
{
if (m_matDib.channels()==3)
{
m_nPixelType=TWPT_RGB;
}
else
{
m_nPixelType=TWPT_GRAY;
}
}
//Document scanned, remove it from simulated intray
m_nDocCount--;
@ -824,7 +833,7 @@ void CScanner_FreeImage::UpdateList(bool canUpdate/*=true*/)
m_bAutoCrop=true;
}
m_iaList.push_back(shared_ptr<CImageApply>(new CAutoCrop(m_bFillBlackRect, m_bAutoDeskew, m_bAutoCrop,getSize((TwSS)m_HardWareParams.PaperType,m_fXResolution),getSize((TwSS)m_HardWareParams.PaperType,200.0))));
m_iaList.push_back(shared_ptr<CImageApply>(new CAutoCrop(m_bFillBlackRect, m_bAutoDeskew, m_bAutoCrop,getSize((TwSS)m_HardWareParams.PaperType,m_fXResolution),getSize((TwSS)m_HardWareParams.PaperType,200.0),m_nPixelType)));
if (m_nFilter)
{
@ -924,13 +933,14 @@ bool CScanner_FreeImage::isPaperOn() const
bool CScanner_FreeImage::isImageQueueEmpty()
{
bool ret=true;
if (!g_drv.is_scan()&&g_drv.Get_IsImageQueueEmpty())
if (!g_drv.is_scan()&&g_drv.Get_IsImageQueueEmpty() &&(g_drv.get_ErrorCode() == 0))
{
//FileTools::write_log("D:/1.txt","!g_drv.is_scan()&&g_drv.Get_IsImageQueueEmpty()");
m_nDocCount=0;
}
else
{
//FileTools::write_log("D:/1.txt","!g_drv.is_scan() m_nDocCount=1;");
m_nDocCount=1;
ret=false;
}

View File

@ -40,15 +40,16 @@
#define __CSCANNER_H__
#include "Common.h"
#include "FreeImage.h"
#include "twain.h"
#include "gscn_drv.h"
//#include "IndicatorDlg.h"
#include <vector>
#include "gscn_drv.h"
#include <memory>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <map>
using namespace std;
/**
* This is a virtual scanner. The virtual scanner is used by the data source
* to try and somewhat simulate some real hardware interaction.
@ -145,6 +146,7 @@ struct SFreeImage
bool m_bAutoDiscardBlank; /**< 自动丢弃空白页通用*/
bool m_bAutoDiscardBlankInvoice;/**自动丢弃空白页发票*/
bool m_bAutoDeskew; /**< 自动纠偏*/
bool m_bMultiOutput; /*多流输出*/
WORD m_nFilter; /**< 除色*/
bool m_bFillBlackRect; /**< 填黑框*/
UINT16 m_wScanCount; /**< 扫描张数*/
@ -302,9 +304,11 @@ protected:
private:
bool can_updateList;
void UpdateList(bool canUpdate=true);
void InitMSGMap();
std::vector<std::shared_ptr<CImageApply>> m_iaList;
std::shared_ptr<ImageTransfer> m_imageTrans;
std::map<UINT32,std::string> ntcMsg;
};
#endif // __CSCANNER_H__

View File

@ -2179,7 +2179,7 @@ TW_INT16 CTWAINDS_Base::getDIBImage(TW_HANDLE& _hImage)
pPal->rgbReserved = 0x00;
pPal++;
pPal->rgbBlue = pPal->rgbGreen = pPal->rgbRed = 0xff;
pPal->rgbBlue = pPal->rgbGreen =pPal->rgbRed = 0xff;
pPal->rgbReserved = 0x00;
}
else if(numcolors==256)

View File

@ -103,7 +103,7 @@ TW_IDENTITY CTWAINDS_Base::m_TheIdentity =
#ifdef __APPLE__
"\p"
#endif
"HS-0805 TWAIN" // TW_STR32 ProductName; Product name, e.g. "ScanJet Plus"
"HUAGOSCAN Hi-5130 TWAIN" // TW_STR32 ProductName; Product name, e.g. "ScanJet Plus"
};
//////////////////////////////////////////////////////////////////////////////
@ -438,6 +438,7 @@ TW_INT16 CTWAINDS_FreeImage::Initialize()
|| !pnCap->Add(0x8005)//背面旋转180
|| !pnCap->Add(0x8004)//填充黑框
|| !pnCap->Add(0x8018)//去除穿孔
|| !pnCap->Add(0x8026)//多流除红
|| !pnCap->Add(0x8092)//去除穿孔所占幅面占比
//硬件协议
@ -1101,6 +1102,17 @@ TW_INT16 CTWAINDS_FreeImage::Initialize()
setConditionCode(TWCC_LOWMEMORY);
return TWRC_FAILURE;
}
//多流除红
m_IndependantCapMap[0x8026] = new CTWAINContainerBool(0x8026, TWON_ONEVALUE, TWQC_ALL);
if (NULL == (pbCap = dynamic_cast<CTWAINContainerBool*>(m_IndependantCapMap[0x8026]))
|| !pbCap->Add(TRUE)
|| !pbCap->Add(FALSE, true))
{
cerr << "Could not create multi output" << endl;
setConditionCode(TWCC_LOWMEMORY);
return TWRC_FAILURE;
}
return TWRC_SUCCESS;
}
@ -1210,7 +1222,7 @@ TW_INT16 CTWAINDS_FreeImage::openDS(pTW_IDENTITY _pOrigin)
{
std::string cvt=StringToUtf("请检查电源或USB通信是否正常!");
std::string notify=StringToUtf("提示");
MyMessageBox((TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_OK| MB_ICONINFORMATION);
MyMessageBox((TCHAR*)cvt.c_str(), (TCHAR*)notify.c_str(), MB_SYSTEMMODAL|MB_OK| MB_ICONINFORMATION);
return TWRC_FAILURE;
}
TW_INT16 ret = TWRC_SUCCESS;
@ -2025,7 +2037,8 @@ bool CTWAINDS_FreeImage::UpdateCapsFromConfig(CONFIGPARAMS pConfig)
}
else
{
pbCap->SetCurrent(pConfig.EnOutHole);
pbCap->SetCurrent(pConfig.EnOutHole?true:false);
int aa=2;
}
//去除穿孔占幅面比例
@ -2035,7 +2048,17 @@ bool CTWAINDS_FreeImage::UpdateCapsFromConfig(CONFIGPARAMS pConfig)
}
else
{
pbCap->SetCurrent(pConfig.OutHoleRatio);
pfRCap->SetCurrent(pConfig.OutHoleRatio);
}
//多流除红
if (0==(pbCap=dynamic_cast<CTWAINContainerBool*>(findCapability(0x8026))))
{
bret = false;
}
else
{
pbCap->SetCurrent(pConfig.EnMultiOutPutR);
}
return bret;
@ -2074,7 +2097,7 @@ bool CTWAINDS_FreeImage::updateScannerFromCaps()
CTWAINContainerFix32Range *pfRCap = 0;
//后加
CTWAINContainerBool *pbRCap = false;
CTWAINContainerBool *pbCap = false;
if (0 == (pnCap = dynamic_cast<CTWAINContainerInt*>(findCapability(ICAP_PIXELTYPE))))
{
@ -2107,14 +2130,14 @@ bool CTWAINDS_FreeImage::updateScannerFromCaps()
settings->m_HardWareParams.PaperType = nVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(CAP_DUPLEXENABLED))))
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(CAP_DUPLEXENABLED))))
{
cerr << "Could not get ICAP_PIXELTYPE" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bDuplex = bVal;
}
@ -2202,93 +2225,93 @@ bool CTWAINDS_FreeImage::updateScannerFromCaps()
settings->m_fGamma = fVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(ICAP_AUTOMATICCROPUSESFRAME))))
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(ICAP_AUTOMATICCROPUSESFRAME))))
{
cerr << "Could not get ICAP_AUTOMATICCROPUSESFRAME" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bAutoCrop = bVal;
}
//填充黑框
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8004))))
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8004))))
{
cerr << "Could not get ICAP_AUTOMATICCROPUSESFRAME" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bFillBlackRect=bVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(ICAP_AUTODISCARDBLANKPAGES))))
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(ICAP_AUTODISCARDBLANKPAGES))))
{
cerr << "Could not get ICAP_AUTODISCARDBLANKPAGES" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bAutoDiscardBlank = bVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8091))))
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8091))))
{
cerr << "Could not get ICAP_AUTODISCARDBLANKPAGES" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bAutoDiscardBlankInvoice = bVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(ICAP_AUTOMATICDESKEW))))
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(ICAP_AUTOMATICDESKEW))))
{
cerr << "Could not get ICAP_AUTOMATICDESKEW" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bAutoDeskew = bVal;
}
if (0==(pbRCap=dynamic_cast<CTWAINContainerBool*>(findCapability(CAP_DOUBLEFEEDDETECTION))))
if (0==(pbCap=dynamic_cast<CTWAINContainerBool*>(findCapability(CAP_DOUBLEFEEDDETECTION))))
{
cerr << "Could not get CAP_DOUBLEFEEDDETECTION" << endl;
bret = false;
}
else
{
bret= pbRCap->GetCurrent(bVal);
bret= pbCap->GetCurrent(bVal);
settings->m_HardWareParams.DoubleFeederOn=bVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8005))))//背面旋转180
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8005))))//背面旋转180
{
cerr << "Could not get CAP_SKREWDETECT" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_bBackRotate180 = bVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8006))))//歪斜检测
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8006))))//歪斜检测
{
cerr << "Could not get CAP_SKREWDETECT" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_HardWareParams.SkrewDetectOn = bVal;
}
@ -2304,14 +2327,14 @@ bool CTWAINDS_FreeImage::updateScannerFromCaps()
settings->m_HardWareParams.SkrewDetectLevel= fVal;
}
if (0 == (pbRCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8090))))//装订检测
if (0 == (pbCap = dynamic_cast<CTWAINContainerBool*>(findCapability(0x8090))))//装订检测
{
cerr << "Could not get CAP_STAPLEDETECT" << endl;
bret = false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_HardWareParams.StapleDetectOn = bVal;
}
@ -2330,17 +2353,17 @@ bool CTWAINDS_FreeImage::updateScannerFromCaps()
}
//去除穿孔
if (0==(pbRCap=dynamic_cast<CTWAINContainerBool*>(findCapability(0x8018))))
if (0==(pbCap=dynamic_cast<CTWAINContainerBool*>(findCapability(0x8018))))
{
bret=false;
}
else
{
bret=pbRCap->GetCurrent(bVal);
bret=pbCap->GetCurrent(bVal);
settings->m_OutHole.EnOutHole=bVal;
if (bVal)
{
//settings->m_bDuplex=true;
settings->m_bDuplex=true;
}
}
@ -2354,6 +2377,17 @@ bool CTWAINDS_FreeImage::updateScannerFromCaps()
pfRCap->GetCurrent(fVal);
settings->m_OutHole.OutHoleRatio=(int)fVal;
}
//多流除红
if (0==(pbCap=dynamic_cast<CTWAINContainerBool*>(findCapability(0x8026))))
{
bret=false;
}
else
{
bret=pbCap->GetCurrent(bVal);
settings->m_bMultiOutput=bVal;
}
return bret;
}
@ -2645,6 +2679,23 @@ TW_INT16 CTWAINDS_FreeImage::dat_imagelayout(TW_UINT16 _MSG,
return twrc;
}
TW_INT16 CTWAINDS_FreeImage::dat_extimageinfo(TW_UINT16 _MSG, pTW_EXTIMAGEINFO _pData)
{
//TW_INFO info;
//info.InfoID=TWEI_BOOKNAME;
//info.ItemType=TWTY_UINT32;
//uint aa=22;
//info.Item=&aa;
//info.ReturnCode=TWRC_SUCCESS;
//_pData->Info->NumItems=1;
//_pData->Info->
//_pData->Info=info;
//return TWRC_SUCCESS;
setConditionCode(TWCC_CAPUNSUPPORTED);
return TWRC_SUCCESS;
}
//////////////////////////////////////////////////////////////////////////////
TW_INT16 CTWAINDS_FreeImage::GetGustomDSData(pTW_CUSTOMDSDATA _pDSData)
{

View File

@ -180,6 +180,15 @@ public:
*/
TW_INT16 dat_imagelayout(TW_UINT16 _MSG, pTW_IMAGELAYOUT _pData);
/**
* Figures out what to do with the DAT_EXTIMAGEINFO request.
* @param[in] _MSG the message to handle.
* @param[in] _pData a pointer to a TW_EXTIMAGEINFO structure.
* @return a valid TWRC_xxxx return code.
*/
TW_INT16 dat_extimageinfo(TW_UINT16 _MSG,
pTW_EXTIMAGEINFO _pData);
/**
* Called by the base class to when the application wants to get memory transfer data.
* @param[in] _pData filled with buffer size data

View File

@ -14,6 +14,7 @@ CImageApplyResize::~CImageApplyResize(void)
void CImageApplyResize::apply(cv::Mat& pDib,int side)
{
//imwrite("o.bmp",pDib);
if(autoCut)
{
if (m_dpi != m_orgDpi)

View File

@ -109,7 +109,7 @@ void CImageChannel::InitColorTable(short channel)
{
if (channel == 2) //ºìÉ«ÔöÇ¿
{
*(colorTable + i * 256 * 256 + j * 256 + k )= (unsigned char)(0 + 0.833 * j + 0.167 * k);
*(colorTable + i * 256 * 256 + j * 256 + k )= (unsigned char)(0 + 0.833 * j + 0.167 * k);//0.833 * j + 0.167 * k
}
else if (channel == 1) //ÂÌÉ«ÔöÇ¿
{

View File

@ -3,6 +3,7 @@
#include "PublicFunc.h"
#include "filetools.h"
#include "ImageOutHole.h"
#include "ImageMultiOutput.h"
ImageMatQueue::ImageMatQueue(void)
{
@ -23,10 +24,16 @@ void ImageMatQueue::run()
}
}
void ImageMatQueue::setmultioutputR(bool canoutput/*=false*/)
{
can_multi_outputR=canoutput;
}
ImageMatQueue::~ImageMatQueue(void)
{
bRun = false;
Sleep(100);
//m_threadProc.~thread();
}
void ImageMatQueue::pushMat(JpegBuffer& data)
@ -79,6 +86,7 @@ bool ImageMatQueue::empty()
return m_images.empty() && m_pImages.empty();
}
static int num =0;
void ImageMatQueue::proc()
{
while(bRun)
@ -91,7 +99,7 @@ void ImageMatQueue::proc()
if (pixType!=-1)
{
if (outHole.EnOutHole&&m_pImages.size()>=2)//确保能够获取正反两面图
{
{
cv::Mat imgF=m_pImages.front().getMat(pixType);
m_pImages.pop();
cv::Mat imgB=m_pImages.front().getMat(pixType);
@ -109,38 +117,64 @@ void ImageMatQueue::proc()
{
for (int j=0;j<m_iaList.size();j++)
{
if (mats[i].empty())
if (mats[i].empty())//剔除空白页
break;
m_iaList[j]->apply(mats[i],i);
}
}
if (!mats[i].empty())
{
m_images.push(mats[i]);
}
if (can_multi_outputR)
{
ImageMultiOutput m_mlt;
Mat m_filterMat= m_mlt.GetMultiFilterMat(mats[i],1);
if (!m_filterMat.empty())
{
m_images.push(m_filterMat);
}
}
}
}
}
else
else//单面图像处理,不需要单双面特征信息
{
cv::Mat image = m_pImages.front().getMat(pixType);
int side=m_pImages.front().getSide();
m_pImages.pop();
static int inddd = 0;
//CString string;
//string.Format("d:\\pp%d.jpg", inddd++ );
for (int i=0;i<m_iaList.size();i++)
{
if (image.empty())
break;
//string.Format("d:\\pp%PB.jpg", (inddd+i) );
// cv::imwrite(string.GetString(), image);
m_iaList[i]->apply(image,side);
//string.Format("d:\\pp%PA.jpg", (inddd+i) );
// cv::imwrite(string.GetString(), image);
}
char pC[1000];
char* str="1111";
strcpy(pC,str);
if (!image.empty())
m_images.push(image);
}
if (can_multi_outputR)
{
ImageMultiOutput m_mlt;
Mat m_filterMat= m_mlt.GetMultiFilterMat(image,1);
if (!m_filterMat.empty())
{
m_images.push(m_filterMat);
}
}
}
}
}
}

View File

@ -24,6 +24,7 @@ public:
public:
int pixType;
OutHole outHole;
void setmultioutputR(bool canoutput=false);
private:
void proc();
cv::Mat _popMat();
@ -34,6 +35,7 @@ private:
boost::mutex m_mtxJB;
boost::thread m_threadProc;
volatile bool bRun;
bool can_multi_outputR;
std::vector<std::shared_ptr<CImageApply>> m_iaList;
};

Binary file not shown.

Binary file not shown.

View File

@ -38,8 +38,12 @@ int JpegBuffer::getSize()
cv::Mat JpegBuffer::getMat( int pixType)
{
static int inddd = 0;
JpegLib jl;
cv::Mat image = jl.decode(m_buffer, pixType);
//CString string;
//string.Format("d:\\aa%d.jpg", inddd++ );
//cv::imwrite(string.GetString(), image);
//FileTools::write_log("D:/1.txt",)
//StopWatch sw;
//sw.start();

View File

@ -40,6 +40,7 @@ void JsonConfig::WriteToJson(PCONFIGPARAMS pConfigItem,const std::string fileNam
outJson["Config"].Add(FILTERTYPE,(int)(pConfigItem->Filter));
outJson["Config"].Add(AUTODESCREW,(bool)(pConfigItem->EnAutoDescrew),false);
outJson["Config"].Add(FILLBLACK,(bool)(pConfigItem->EnFillBlack),false);
outJson["Config"].Add(MULTIOUTPUT,(bool)(pConfigItem->EnMultiOutPutR),false);
outJson["Config"].Add(OUTHOLE,(bool)(pConfigItem->EnOutHole),false);
outJson["Config"].Add(OUTHOLERATIO,(int)(pConfigItem->OutHoleRatio));
@ -98,6 +99,7 @@ void JsonConfig::WriteJsonArrayToFile(std::vector<CONFIGPARAMS> cfgArray,const s
root["Config"].AddEmptySubArray(FILTERTYPE);
root["Config"].AddEmptySubArray(AUTODESCREW);
root["Config"].AddEmptySubArray(FILLBLACK);
root["Config"].AddEmptySubArray(MULTIOUTPUT);
root["Config"].AddEmptySubArray(OUTHOLE);
root["Config"].AddEmptySubArray(OUTHOLERATIO);
@ -129,6 +131,7 @@ void JsonConfig::WriteJsonArrayToFile(std::vector<CONFIGPARAMS> cfgArray,const s
root["Config"][FILTERTYPE].Add(cfgArray[i].Filter);
root["Config"][AUTODESCREW].Add(i,cfgArray[i].EnAutoDescrew);
root["Config"][FILLBLACK].Add(i,cfgArray[i].EnFillBlack);
root["Config"][MULTIOUTPUT].Add(i,cfgArray[i].EnMultiOutPutR);
root["Config"][OUTHOLE].Add(i,cfgArray[i].EnOutHole);
root["Config"][OUTHOLERATIO].Add(cfgArray[i].OutHoleRatio);
@ -222,6 +225,7 @@ CONFIGPARAMS JsonConfig::GetDefaultConfigParams()
params.Filter=0;//除色 无
params.EnFillBlack=FALSE;//不填黑框
params.EnAutoDescrew=TRUE;//不自动纠偏
params.EnMultiOutPutR=FALSE;//不多流输出除红
params.EnOutHole=FALSE;//不去除孔洞
params.OutHoleRatio=10;//默认值0.10
@ -275,6 +279,8 @@ std::vector<CONFIGPARAMS> JsonConfig::parseJsonFromString(const std::string str)
root["Config"].Get(AUTODESCREW,itmAutoDescrew);
neb::CJsonObject itmFillBlack;
root["Config"].Get(FILLBLACK,itmFillBlack);
neb::CJsonObject itmMultiOutput;
root["Config"].Get(MULTIOUTPUT,itmMultiOutput);
neb::CJsonObject itmOutHole;
root["Config"].Get(OUTHOLE,itmOutHole);
neb::CJsonObject itmOutHoleRatio;
@ -342,6 +348,8 @@ std::vector<CONFIGPARAMS> JsonConfig::parseJsonFromString(const std::string str)
cfp.EnAutoDescrew=b_value;
itmFillBlack.Get(i,b_value);
cfp.EnFillBlack=b_value;
itmMultiOutput.Get(i,b_value);
cfp.EnMultiOutPutR=b_value;
itmOutHole.Get(i,b_value);
cfp.EnOutHole=b_value;
itmOutHoleRatio.Get(i,i_value);
@ -412,6 +420,8 @@ std::vector<CONFIGPARAMS> JsonConfig::parseJsonFromString(const std::string str)
cfp.EnAutoCrop=bvalue;
root["Config"].Get(FILLBLACK,bvalue);
cfp.EnFillBlack=bvalue;
root["Config"].Get(MULTIOUTPUT,bvalue);
cfp.EnMultiOutPutR=bvalue;
root["Config"].Get(OUTHOLE,bvalue);
cfp.EnOutHole=bvalue;
root["Config"].Get(OUTHOLERATIO,index);

View File

@ -46,9 +46,9 @@ TW_INT16 MFC_UI::DisplayTWAINGUI(TW_USERINTERFACE Data, bool bSetup, bool bIndic
{
CDialog* dlg =new CDialog();
dlg->Create(IDD_DIALOGBACK);
m_pChildWnd = dlg;
theApp.m_pMainWnd = m_pChildWnd;
//long ll = GetWindowLong(m_pChildWnd->GetSafeHwnd(), GWL_STYLE);
//SetWindowLong(m_pChildWnd->GetSafeHwnd(), GWL_STYLE, WS_CHILD | ll);
SetParent(m_pChildWnd->GetSafeHwnd(), (HWND)Data.hParent);
@ -75,9 +75,9 @@ TW_INT16 MFC_UI::DisplayTWAINGUI(TW_USERINTERFACE Data, bool bSetup, bool bIndic
if (m_pDlg)
{
//long ll = GetWindowLong(m_pChildWnd->GetSafeHwnd(), GWL_STYLE);
SetWindowPos((HWND)Data.hParent,HWND_TOP,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
m_pDlg->ShowWindow(SW_SHOWNORMAL);
SetWindowPos(m_pDlg->m_hWnd,HWND_TOPMOST,500,500,0,0,SWP_NOSIZE|SWP_NOMOVE);
//m_pDlg->BringWindowToTop();
}
else
{
@ -157,7 +157,7 @@ void MFC_UI::UpdateProgress(bool bShow, unsigned char ucProgress, unsigned int
}
}
unsigned int MFC_UI::MessageBox(string strMessage, string strTitle, unsigned int unIconID)
unsigned int MFC_UI::MyMessageBox(string strMessage, string strTitle, unsigned int unIconID)
{
//QMessageBox msgBox(QMessageBox::NoIcon, strTitle.c_str(), strMessage.c_str());
if (m_pChildWnd!=NULL)

View File

@ -25,7 +25,7 @@ public:
*/
void DestroyTWAINGUI();
void UpdateProgress(bool bShow, unsigned char ucProgress, unsigned int unPageNo, string strProgressTitle);
unsigned int MessageBox(string strMessage, string strTitle, unsigned int unIconID);
unsigned int MyMessageBox(string strMessage, string strTitle, unsigned int unIconID);
bool processEvent(pTW_EVENT _pEvent);
private:

View File

@ -36,6 +36,7 @@ using namespace std;
#define SCREWLEVEL "iScrewLevel"
#define ITEMCAPTION "Caption"
#define SAVEPATH "SavePath"
#define MULTIOUTPUT "iMultiOutPut"
#define OUTHOLE "bOutHole"
#define OUTHOLERATIO "iOutHoleRatio"
@ -63,6 +64,7 @@ struct tagCONFIGPARAMS
INT Filter;
BOOL EnFillBlack;
BOOL EnAutoDescrew;
//BOOL EnMulti
BOOL EnOutHole;
INT OutHoleRatio;
BOOL EnMultiOutPutR;
@ -99,6 +101,128 @@ struct tagOutHole
typedef tagOutHole OutHole,*pOutHole;
typedef struct tag_USBCB {
UINT32 u32_CMD;
UINT32 u32_Data;
UINT32 u32_Count;
}USBCB, *PUSBCB;
//u32_CMD
enum tagUsbKeyWords :UINT32
{
//无命令
NO_COMMAND = 0,
//获取dsp 状态
GET_DSP_STATUS = 1,
//取图
GET_IMAGE = 2,
//销毁DSP中驻存的图
POP_IMAGE = 3,
//开始扫描命令
START_COMMAND = 4,
//停止扫描命令
STOP = 5,
//获取扫描仪扫描模式
GET_SCAN_MODE = 6,
//获取固件版本号
GET_FW_VERSION = 7,
//返回PC端的状态
SEND_STATUS_PC = 8,
//下发扫描配置参数
CONFIGURED_DATA = 9,
//下发固件信息
SEND_FW = 10,
//获取扫描参数
GET_CONFIG_DATA = 11,
//获取扫描总张数
GET_SCANN_NUM = 12,
//获取有无纸的状态
GET_PAPERFEEDER_STATUS = 13,
//DSP初始化
INIT_HARDWARE_SYS = 14,
//获取有无纸的状态
GET_PAPER_STATUS = 0x0d,
//下发元器件配置参数灰度LED R曝光时间
SEND_COMPONENTS_GR = 15,
//下发元器件配置参数LED G/B曝光时间
SEND_COMPONENTS_GB = 16,
//下发扫描模式
SEND_SCAN_MODE = 17,
//开始进行平场矫正
START_FLAT = 18,
//停止平场矫正
STOP_FLAT = 19,
//下发200dpi彩色平场矫正参数
SEND_200_COLOR_FLAT_DATA = 20,
//下发300dpi彩色平场矫正参数
SEND_300_COLOR_FLAT_DATA = 21,
//获取200dpi彩色平场矫正参数
GET_200_COLOR_FLAT_DATA = 22,
//获取300dpi彩色平场矫正参数
GET_300_COLOR_FLAT_DATA = 23,
//下发200dpi灰度平场校正参数
SEND_200_GRAY_FLAT_DATA = 24,
//下发300dpi灰度平场校正参数
SEND_300_GRAY_FLAT_DATA = 25,
//获取200DPI灰度平场校正参数
GET_200_GRAY_FLAT_DATA = 26,
//获取300DPI灰度平场校正参数
GET_300_GRAY_FLAT_DATA = 27,
//下发序列号命令
SEND_SERIAL = 28,
//获取序列号命令
GET_SERIAL = 29
};
typedef enum tagUsbKeyWords UsbKeyWords, *PUsbKeyWords;
//u32_Data
enum tagUsbSupported
{
//停止扫描
SCAN_STOP = -2,
//异常
HAVE_ERROR = -1,
//正常状态
NORMAL = 0,
//开盖
OPEN_COVER = 1,
// 无纸
NO_FEED = 2,
// 搓纸失败
FEED_IN_ERROR = 4,
// 卡纸
PAPER_JAM = 8,
// 检测到双张
DETECT_DOUBLE_FEED = 16,
// 检测到订书钉
DETECT_STAPLE = 32,
// 纸张倾斜
PAPER_SKEW = 64,
// 自动模式
AUTO_SCAN_MODE = 65,
// 手动模式
MANAUL_SCAN_MODE = 66,
// 计数模式
COUNT_MODE = 67,
// 硬件错误
HARDWARE_ERROR = 68,
// FPGA崩溃
FPGA_ERROR = 68,
// 开始
START_SCAN = 69,
//停止
STOP_SCAN = 70,
//有图
HAVE_IMAGE = 71,
// 更新扫描参数
UPDATE_SCAN_PARAMETER = 72,
// PC繁忙或出错
PC_SCAN_BUSY_or_ERROR = 73
};
typedef enum tagUsbSupported UsbSupported, *PUsbSupported;
#define CAPTION_LEN 256
#define TWAIN_IMAGE_FILE_LIST_NAME TEXT(".dat")

Binary file not shown.

Binary file not shown.

View File

@ -8,6 +8,8 @@
#include "ImageProcDiscardBlank.h"
#include "ImageApply.h"
#include "hugaotwainds.h"
#include "filetools.h"
extern ChugaotwaindsApp theApp;
GScn_Drv::GScn_Drv()
@ -18,33 +20,18 @@ GScn_Drv::GScn_Drv()
devState = DEV_STOP;
isDuplex=TRUE;
m_h_usb_thread=NULL;
InitMSGMap();
Error_Code=0;
}
GScn_Drv::~GScn_Drv()
{
if (m_threadUsb.joinable())
{
//XdPrint("out 1");
m_bRun = false;
//m_threadUsb.join();
Sleep(500);
}
}
void GScn_Drv::InitMSGMap()
{
if (ntcMsg.size()>0)
ntcMsg.clear();
ntcMsg[COUNT_MODE]="计数模式,请先退出计数模式!";
ntcMsg[NO_FEED]="无纸,请放置纸张!";
ntcMsg[OPEN_COVER]="扫描仪开盖!";
ntcMsg[FEED_IN_ERROR]="拾纸错误!";
ntcMsg[PAPER_JAM]="卡纸!";
ntcMsg[DETECT_DOUBLE_FEED]="双张!";
ntcMsg[DETECT_STAPLE]="订书针!";
ntcMsg[PAPER_SKEW]="纸张歪斜!";
ntcMsg[HARDWARE_ERROR]="硬件错误!";
ntcMsg[PC_SCAN_BUSY_or_ERROR]="PC错误";
}
void GScn_Drv::open(int vid, int pid)
@ -86,30 +73,23 @@ twainImage GScn_Drv::PopTwainImage()
return cv::Mat();
}
bool reported=false;
int GScn_Drv::aquire_image(cv::Mat& image)
{
bool begin=false;
struct timeval start;
struct timeval end;
float time_used=0;
while (true)
{
if (Get_IsImageQueueEmpty())
{
if (!begin)
{
begin=true;
//DWORD s= timeGetTime();
//gettimeofday(&start,NULL);
}
//gettimeofday(&end,NULL);
//time_used=end.tv_sec-start.tv_sec;
//Sleep(100);
DoEvents();
if (!is_scan())
break;
{
if (devState==DEV_WRONG)
{
return get_ErrorCode();
}
return 0;
}
}
else
{
@ -120,7 +100,6 @@ int GScn_Drv::aquire_image(cv::Mat& image)
}
}
}
return -1;
}
void GScn_Drv::reset()
@ -155,6 +134,26 @@ cv::Mat GScn_Drv::Get_Img_Data(int bufferSize)
return iData;
}
UINT32 GScn_Drv::get_ErrorCode()
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
//CString str;
//str.Format("GScn_Drv GET error_code :%d\n",Error_Code);
//string ss((LPCTSTR)str);
//FileTools::write_log("D:\\1.txt",ss);
return Error_Code;
}
void GScn_Drv::Set_ErrorCode(UINT32 value)
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
//CString str;
//str.Format("GScn_Drv error_code :%d\n",value);
//string ss((LPCTSTR)str);
//FileTools::write_log("D:\\1.txt",ss);
Error_Code=value;
}
void GScn_Drv::run()
{
if (!m_threadUsb.joinable())
@ -211,8 +210,17 @@ void GScn_Drv::SetOutHoleParam(OutHole outhole)
m_pImages.outHole=outhole;
}
void GScn_Drv::SetMultiOutPutRParams(bool canmultioutR)
{
m_pImages.setmultioutputR(canmultioutR);
}
static int indexIm = 0;
DWORD GScn_Drv::usbmain()
{
cv::Mat imgData;// = Get_Img_Data(totalNum);
cv::Mat bufferF;// = imgData.clone();
cv::Mat bufferB;// = imgData.clone();
while (m_bRun)
{
if (!m_usb.is_connected())
@ -228,9 +236,9 @@ DWORD GScn_Drv::usbmain()
int totalNum = usbcb.u32_Count;
DWORD transferCount = 0;
cv::Mat imgData = Get_Img_Data(totalNum);
cv::Mat bufferF = imgData.clone();
cv::Mat bufferB = imgData.clone();
imgData = Get_Img_Data(totalNum);
bufferF = Mat(imgData.rows,imgData.cols,CV_8UC1);
bufferB = Mat(imgData.rows,imgData.cols,CV_8UC1);
int j = 0;
int k = 0;
for (int i = 0; i < totalNum / 1024; i++)
@ -246,13 +254,29 @@ DWORD GScn_Drv::usbmain()
memcpy(&(bufferF.data[(k - 1) * 1023]), &(imgData.data[(j + k - 1) * 1024]), 1023);
}
}
//CString string;
//string.Format("d:\\%db.jpg",indexIm ++ );
//XdPrint(" the path is ....%s \n",string);
//CFile file(string, CFile::modeReadWrite | CFile::modeCreate);
//file.Write(bufferB.data, bufferB.cols);
//XdPrint(" Write Back ....%s \n",string);
//file.Flush();
//file.Close();
pushMat(JpegBuffer(bufferB,pixType,0,0));
//XdPrint("Enter Front\n");
if (isDuplex)
{
/* string.Format("d:/%df.jpg",indexIm);
file.Open(string, CFile::modeReadWrite | CFile::modeCreate);
file.Write(bufferF.data, bufferF.cols);
file.Flush();
file.Close();*/
pushMat(JpegBuffer(bufferF,pixType,1,0));
}
imgData.release();
bufferB.release();
bufferF.release();
Pop_Image();
break;
}
@ -270,16 +294,16 @@ DWORD GScn_Drv::usbmain()
case DETECT_STAPLE:
case PAPER_SKEW:
case HARDWARE_ERROR:
case PC_SCAN_BUSY_or_ERROR:
MessageBox(theApp.m_pMainWnd->GetSafeHwnd(), ntcMsg[usbcb.u32_Data].c_str(), "提示", MB_OK | MB_ICONERROR);
case PC_SCAN_BUSY_or_ERROR:
devState = DEV_WRONG;
Set_ErrorCode(usbcb.u32_Data);
break;
case NORMAL:
break;
default:
break;
}
Sleep(50);
Sleep(20);
}
m_h_usb_thread = NULL;
return 0;

View File

@ -13,130 +13,9 @@
#include <boost\thread\mutex.hpp>
#include <boost\thread.hpp>
#include "ImageMatQueue.h"
#include <map>
#include "PublicFunc.h"
using namespace cv;
typedef struct tag_USBCB {
UINT32 u32_CMD;
UINT32 u32_Data;
UINT32 u32_Count;
}USBCB, *PUSBCB;
//u32_CMD
enum tagUsbKeyWords :UINT32
{
//无命令
NO_COMMAND = 0,
//获取dsp 状态
GET_DSP_STATUS = 1,
//取图
GET_IMAGE = 2,
//销毁DSP中驻存的图
POP_IMAGE = 3,
//开始扫描命令
START_COMMAND = 4,
//停止扫描命令
STOP = 5,
//获取扫描仪扫描模式
GET_SCAN_MODE = 6,
//获取固件版本号
GET_FW_VERSION = 7,
//返回PC端的状态
SEND_STATUS_PC = 8,
//下发扫描配置参数
CONFIGURED_DATA = 9,
//下发固件信息
SEND_FW = 10,
//获取扫描参数
GET_CONFIG_DATA = 11,
//获取扫描总张数
GET_SCANN_NUM = 12,
//获取有无纸的状态
GET_PAPERFEEDER_STATUS = 13,
//DSP初始化
INIT_HARDWARE_SYS = 14,
//获取有无纸的状态
GET_PAPER_STATUS = 0x0d,
//下发元器件配置参数灰度LED R曝光时间
SEND_COMPONENTS_GR = 15,
//下发元器件配置参数LED G/B曝光时间
SEND_COMPONENTS_GB = 16,
//下发扫描模式
SEND_SCAN_MODE = 17,
//开始进行平场矫正
START_FLAT = 18,
//停止平场矫正
STOP_FLAT = 19,
//下发200dpi彩色平场矫正参数
SEND_200_COLOR_FLAT_DATA = 20,
//下发300dpi彩色平场矫正参数
SEND_300_COLOR_FLAT_DATA = 21,
//获取200dpi彩色平场矫正参数
GET_200_COLOR_FLAT_DATA = 22,
//获取300dpi彩色平场矫正参数
GET_300_COLOR_FLAT_DATA = 23,
//下发200dpi灰度平场校正参数
SEND_200_GRAY_FLAT_DATA = 24,
//下发300dpi灰度平场校正参数
SEND_300_GRAY_FLAT_DATA = 25,
//获取200DPI灰度平场校正参数
GET_200_GRAY_FLAT_DATA = 26,
//获取300DPI灰度平场校正参数
GET_300_GRAY_FLAT_DATA = 27,
//下发序列号命令
SEND_SERIAL = 28,
//获取序列号命令
GET_SERIAL = 29
};
typedef enum tagUsbKeyWords UsbKeyWords, *PUsbKeyWords;
//u32_Data
enum tagUsbSupported
{
//停止扫描
SCAN_STOP = -2,
//异常
HAVE_ERROR = -1,
//正常状态
NORMAL = 0,
//开盖
OPEN_COVER = 1,
// 无纸
NO_FEED = 2,
// 搓纸失败
FEED_IN_ERROR = 4,
// 卡纸
PAPER_JAM = 8,
// 检测到双张
DETECT_DOUBLE_FEED = 16,
// 检测到订书钉
DETECT_STAPLE = 32,
// 纸张倾斜
PAPER_SKEW = 64,
// 自动模式
AUTO_SCAN_MODE = 65,
// 手动模式
MANAUL_SCAN_MODE = 66,
// 计数模式
COUNT_MODE = 67,
// 硬件错误
HARDWARE_ERROR = 68,
// FPGA崩溃
FPGA_ERROR = 68,
// 开始
START_SCAN = 69,
//停止
STOP_SCAN = 70,
//有图
HAVE_IMAGE = 71,
// 更新扫描参数
UPDATE_SCAN_PARAMETER = 72,
// PC繁忙或出错
PC_SCAN_BUSY_or_ERROR = 73
};
typedef enum tagUsbSupported UsbSupported, *PUsbSupported;
enum tagDevState
{
@ -212,6 +91,7 @@ public:
void open(int vid, int pid);
//int aquire_image(cv::Mat& image);
int aquire_image(cv::Mat& image);
volatile UINT32 Error_Code;
BOOL IsConnected();
std::string GetFWVersion();
std::string GetSerialNum();
@ -240,12 +120,17 @@ public:
void SetOutHoleParam(OutHole outhole);
void SetMultiOutPutRParams(bool canmultioutR=false);
UINT32 get_ErrorCode();
void Set_ErrorCode(UINT32 value);
private:
cv::Mat popMat();
twainImage PopTwainImage();
void pushMat(JpegBuffer& data);
void InitMSGMap();
cv::Mat Get_Img_Data(int buffersize);
TCHAR *m_sMutexName;
DWORD usbmain();
void Pop_Image();
@ -268,5 +153,4 @@ private:
BOOL canUseDiscardBlank;
boost::thread m_threadUsb;
std::vector<std::shared_ptr<CImageApply>> m_iaList;
std::map<int,string> ntcMsg;
};

Binary file not shown.

Binary file not shown.

View File

@ -234,6 +234,7 @@ opencv_imgproc2410.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ClCompile Include="ImageBWBinaray.cpp" />
<ClCompile Include="ImageChannel.cpp" />
<ClCompile Include="ImageMatQueue.cpp" />
<ClCompile Include="ImageMultiOutput.cpp" />
<ClCompile Include="ImageOutHole.cpp" />
<ClCompile Include="ImageProcDiscardBlank.cpp" />
<ClCompile Include="ImageProcess.cpp" />
@ -296,6 +297,7 @@ opencv_imgproc2410.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ClInclude Include="ImageBWBinaray.h" />
<ClInclude Include="ImageChannel.h" />
<ClInclude Include="ImageMatQueue.h" />
<ClInclude Include="ImageMultiOutput.h" />
<ClInclude Include="ImageOutHole.h" />
<ClInclude Include="ImageProcDiscardBlank.h" />
<ClInclude Include="ImageProcess.h" />

View File

@ -171,6 +171,9 @@
<ClCompile Include="ImageOutHole.cpp">
<Filter>图像处理</Filter>
</ClCompile>
<ClCompile Include="ImageMultiOutput.cpp">
<Filter>代码文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="hugaotwainds.def">
@ -349,6 +352,9 @@
<ClInclude Include="ImageOutHole.h">
<Filter>图像处理</Filter>
</ClInclude>
<ClInclude Include="ImageMultiOutput.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="hugaotwainds.rc">

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>C:\Program Files (x86)\TWAIN Working Group\Twacker 32\Twack_32.exe</LocalDebuggerCommand>
<LocalDebuggerCommand>C:\Program Files (x86)\TWAIN Working Group\TWAIN 2.3 App Sample\TWAIN_App_mfc32.exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>C:\Windows\twain_32\huagoscan</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
@ -12,7 +12,7 @@
<DebuggerFlavor Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommand>C:\Program Files (x86)\TWAIN Working Group\TWAIN 2.3 App Sample\TWAIN_App_mfc32.exe</LocalDebuggerCommand>
<LocalDebuggerCommand>G:\软件安装包\xnviewer\xnviewer\xnview.exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>..\..\..\..\..\..\..\Windows\twain_32\huagoscan</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>

Binary file not shown.