diff --git a/AutoCrop.cpp b/AutoCrop.cpp deleted file mode 100644 index 72c6b3a..0000000 --- a/AutoCrop.cpp +++ /dev/null @@ -1,510 +0,0 @@ -#include "StdAfx.h" -#include "AutoCrop.h" -#ifndef _USE_MATH_DEFINES -#define _USE_MATH_DEFINES -#endif // !_USE_MATH_DEFINES -#include -#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 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 hierarchy; - vector> contours; - findContours(thre, contours, hierarchy, RETR_EXTERNAL); - if (contours.size()<=0) - { - dst = src.clone(); - flags=0; - return; - } - - vector 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 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& points, float indent) -{ - static Point zero(0, 0); - Point center = getBoundingRect(points).center; - for (int i=0;i>& 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& 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 CAutoCrop::getMaxContour(const vector>& contours, const vector& hierarchy) -{ - vector 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, vector& 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 all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage)); - int total = (int)all_contours.size(); - contours.resize(total); - - SeqIterator 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& src, vector& 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;itotal; - 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 getMaxContour(const vector>& contours, const vector& hierarchy) -{ - vector 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 points, float indent); - void polyIndent(std::vector& points, float indent); - void fill_poly(cv::Mat& src, const std::vector>& contours, const cv::Scalar& color, int lineType = 8, int shift = 0, cv::Point offset = cv::Point()); - cv::RotatedRect getBoundingRect(const std::vector& contour); - std::vector getMaxContour(const std::vector>& contours, const std::vector& hierarchy); - void findContours(const cv::Mat& src, std::vector>& contours, std::vector& 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& src, std::vector& dst, bool clockwise = false); - - bool m_bCrop; - bool m_bFill; - bool m_bAutoDescrew; - SIZE m_dstSize; - SIZE m_originSize; - int tw_pixType; -}; - diff --git a/CScanner_FreeImage.cpp b/CScanner_FreeImage.cpp index 2b40671..bf2a662 100644 --- a/CScanner_FreeImage.cpp +++ b/CScanner_FreeImage.cpp @@ -48,12 +48,7 @@ #include #include "scn_config.h" #include "PublicFunc.h" -#include "AutoCrop.h" -#include "ImageAdjustColors.h" -#include "ImageChannel.h" -#include "ImageApplyResize.h" -#include "ImageRotation.h" -#include "ImageProcDiscardBlank.h" +#include "ImageProcess/ImageApplyHeaders.h" #include "filetools.h" #include "hugaotwainds.h" #include "GScanO200.h" diff --git a/ImageAdjustColors.cpp b/ImageAdjustColors.cpp deleted file mode 100644 index f9d51f7..0000000 --- a/ImageAdjustColors.cpp +++ /dev/null @@ -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 (valueup) - { - return up; - } - return value; -} diff --git a/ImageAdjustColors.h b/ImageAdjustColors.h deleted file mode 100644 index 12cf67c..0000000 --- a/ImageAdjustColors.h +++ /dev/null @@ -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; -}; - diff --git a/ImageApplyCrop.cpp b/ImageApplyCrop.cpp deleted file mode 100644 index 1585a98..0000000 --- a/ImageApplyCrop.cpp +++ /dev/null @@ -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; -} diff --git a/ImageApplyCrop.h b/ImageApplyCrop.h deleted file mode 100644 index 5d8d62b..0000000 --- a/ImageApplyCrop.h +++ /dev/null @@ -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; -}; - diff --git a/ImageApplyHeaders.h b/ImageApplyHeaders.h new file mode 100644 index 0000000..7768730 --- /dev/null +++ b/ImageApplyHeaders.h @@ -0,0 +1,8 @@ +#ifndef IMAGE_APPLY_HEADER_H +#define IMAGE_APPLY_HEADER_H + +#include "ImageApply.h" +#include "ImageApplyAdjustColors.h" + + +#endif diff --git a/ImageApplyResize.cpp b/ImageApplyResize.cpp deleted file mode 100644 index 151d1bc..0000000 --- a/ImageApplyResize.cpp +++ /dev/null @@ -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; -} diff --git a/ImageApplyResize.h b/ImageApplyResize.h deleted file mode 100644 index 3fc97a3..0000000 --- a/ImageApplyResize.h +++ /dev/null @@ -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; -}; - diff --git a/ImageBWBinaray.cpp b/ImageBWBinaray.cpp deleted file mode 100644 index 03524e6..0000000 --- a/ImageBWBinaray.cpp +++ /dev/null @@ -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; - } - } \ No newline at end of file diff --git a/ImageBWBinaray.h b/ImageBWBinaray.h deleted file mode 100644 index 66a3c2d..0000000 --- a/ImageBWBinaray.h +++ /dev/null @@ -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; -}; - diff --git a/ImageMatQueue.cpp b/ImageMatQueue.cpp index d04121e..73951fd 100644 --- a/ImageMatQueue.cpp +++ b/ImageMatQueue.cpp @@ -2,7 +2,7 @@ #include "ImageMatQueue.h" #include "PublicFunc.h" #include "filetools.h" -#include "ImageOutHole.h" +#include "ImageProcess/ImageApplyHeaders.h" #include "ImageMultiOutput.h" using namespace cv; @@ -73,25 +73,33 @@ void ImageMatQueue::setparam(SFreeImage param) scanParam = param; m_iaList.clear(); if (param.m_bAutoDiscardBlank || param.m_bAutoDiscardBlankInvoice) - m_iaList.push_back(shared_ptr(new CImageProcDiscardBlank(param.m_bAutoDiscardBlank ? true : false))); + m_iaList.push_back(shared_ptr(new CImageApplyDiscardBlank(param.m_bAutoDiscardBlank ? true : false))); - bool m_bAutoCrop = false; - if (param.m_HardWareParams.PaperType == 90) - m_bAutoCrop = true; + { + CSize fixedSize = papersize.GetPaperSize(param.m_HardWareParams.PaperType, 200.0f); + m_iaList.push_back(shared_ptr(new CImageApplyAutoCrop(param.m_bAutoCrop, param.m_bFillBlackRect, param.m_bAutoDeskew, cv::Size(fixedSize.cx, fixedSize.cy)))); + } - m_iaList.push_back(shared_ptr(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(new CImageApplySharpen())); if (param.m_nFilter) - m_iaList.push_back(shared_ptr(new CImageChannel(param.m_nFilter))); + m_iaList.push_back(shared_ptr(new CImageApplyChannel(param.m_nFilter))); if (param.m_fBrightness != 0 || param.m_fContrast != 0 || param.m_fGamma != 1.0) - m_iaList.push_back(shared_ptr(new CImageAdjustColors(param.m_fBrightness, param.m_fContrast, param.m_fGamma))); + m_iaList.push_back(shared_ptr(new CImageApplyAdjustColors(param.m_fBrightness, param.m_fContrast, param.m_fGamma))); 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) - m_iaList.push_back(shared_ptr(new CImageRotation(param.m_wRotation, param.m_bBackRotate180))); + m_iaList.push_back(shared_ptr(new CImageApplyRotation(param.m_wRotation, param.m_bBackRotate180))); } 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); //} - //for (int i = 0; i < mats.size(); i++) { - // if (!mats[i].empty()) { - // for (int j = 0; j < m_iaList.size(); j++) { - // if (mats[i].empty())//剔除空白页 - // break; + for (int i = 0; i < mats.size(); i++) { + if (!mats[i].empty()) { + for (int j = 0; j < m_iaList.size(); j++) { + if (mats[i].empty())//剔除空白页 + break; - // m_iaList[j]->apply(mats[i], i); - // } - // } - //} + m_iaList[j]->apply(mats[i], i); + } + } + } for (int i = 0; i < mats.size(); i++) { //if (!scanParam.m_bDuplex && i == 1) { diff --git a/ImageMatQueue.h b/ImageMatQueue.h index 9da78dc..c26e06d 100644 --- a/ImageMatQueue.h +++ b/ImageMatQueue.h @@ -5,18 +5,12 @@ #include #include "JpegBuffer.h" #include -#include "ImageApply.h" +#include "ImageProcess/ImageApplyHeaders.h" #include "PublicFunc.h" #include "BlockingQueue.h" #include #include #include "PaperSize.h" -#include "AutoCrop.h" -#include "ImageAdjustColors.h" -#include "ImageApplyResize.h" -#include "ImageChannel.h" -#include "ImageProcDiscardBlank.h" -#include "ImageRotation.h" #include class ImageMatQueue diff --git a/ImageMultiOutput.h b/ImageMultiOutput.h index a7e699d..f272570 100644 --- a/ImageMultiOutput.h +++ b/ImageMultiOutput.h @@ -1,5 +1,5 @@ #pragma once -#include "ImageApply.h" +#include "ImageProcess/ImageApply.h" class ImageMultiOutput { diff --git a/ImageOutHole.cpp b/ImageOutHole.cpp deleted file mode 100644 index 14c452d..0000000 --- a/ImageOutHole.cpp +++ /dev/null @@ -1,315 +0,0 @@ -#include "StdAfx.h" -#include "ImageOutHole.h" -#include -#include -#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> contours_front, contours_back; - vector 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 maxContour_front = getMaxContour(contours_front, b1_front); - vector 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 vertices_point = getVertices(mask_rotatedRect); - - polylines(mask, vertices_point, true, Scalar(255), 3); //绘制纸张矩形边缘 - - //二值图像重叠图像颜色取反,并提取轮廓 - vector> contours_mask; - vector 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 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>& contours, vector& 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 all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage)); - int total = (int)all_contours.size(); - contours.resize(total); - - SeqIterator 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 ImageOutHole::getMaxContour(const vector>& contours, const vector& hierarchy, int areaThreshold /*= 20000*/) -{ - vector 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 ImageOutHole::getVertices(RotatedRect rect) -{ - vector 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>& 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 vertices_roi1 = getVertices(roi); - vector vertices_roi2 = getVertices(roi2); - - vector contour; - for (size_t i = 0, length = contours.size(); i < length; i++) - { - //contour = /*Mat_*/(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); -} - diff --git a/ImageOutHole.h b/ImageOutHole.h deleted file mode 100644 index 696c43b..0000000 --- a/ImageOutHole.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once -#include "ImageApply.h" -#include - -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>& contours, std::vector& hierarchy, int retr = cv::RETR_CCOMP, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0)); - std::vector getMaxContour(const std::vector>& contours, const std::vector& 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 getVertices(cv::RotatedRect rect); - void filterPoly(const cv::Mat& mask, std::vector>& contours, cv::RotatedRect roi, float edgeScale, double areaThreshold); - void fillPuncture(cv::Mat& src, const cv::Mat& mask, cv::Rect roi); -}; - diff --git a/ImageApply.cpp b/ImageProcess/ImageApply.cpp similarity index 81% rename from ImageApply.cpp rename to ImageProcess/ImageApply.cpp index b94872c..80f5fbf 100644 --- a/ImageApply.cpp +++ b/ImageProcess/ImageApply.cpp @@ -1,12 +1,9 @@ -#include "StdAfx.h" #include "ImageApply.h" - CImageApply::CImageApply(void) { } - CImageApply::~CImageApply(void) { } diff --git a/ImageApply.h b/ImageProcess/ImageApply.h similarity index 70% rename from ImageApply.h rename to ImageProcess/ImageApply.h index c19d875..a63da5e 100644 --- a/ImageApply.h +++ b/ImageProcess/ImageApply.h @@ -1,8 +1,14 @@ -#pragma once +#ifndef IMAGE_APPLY_H +#define IMAGE_APPLY_H + +#include "../stdafx.h" #include #include #include + +#if defined(LOG) #include "filetools.h" +#endif class CImageApply { @@ -11,8 +17,8 @@ public: virtual ~CImageApply(void); virtual void apply(cv::Mat& pDib,int side) = 0; - //virtual void apply(twainImage& pDib) = 0; }; typedef std::shared_ptr ImageApplyPtr; +#endif //!IMAGE_APPLY_H diff --git a/ImageProcess/ImageApplyAdjustColors.cpp b/ImageProcess/ImageApplyAdjustColors.cpp new file mode 100644 index 0000000..9e183b1 --- /dev/null +++ b/ImageProcess/ImageApplyAdjustColors.cpp @@ -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(cv::min(255, static_cast(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(cv::max(0, cv::min(i - m_contrast, 127))); + else + ptr[i] = static_cast(cv::max(127, cv::min(i + m_contrast, 255))); + + //update brightness + ptr[i] = static_cast(cv::max(0, cv::min(ptr[i] + m_brightness, 255))); + } + } +} diff --git a/ImageProcess/ImageApplyAdjustColors.h b/ImageProcess/ImageApplyAdjustColors.h new file mode 100644 index 0000000..eb7a554 --- /dev/null +++ b/ImageProcess/ImageApplyAdjustColors.h @@ -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 + + diff --git a/ImageProcess/ImageApplyAutoCrop.cpp b/ImageProcess/ImageApplyAutoCrop.cpp new file mode 100644 index 0000000..b6eb66a --- /dev/null +++ b/ImageProcess/ImageApplyAutoCrop.cpp @@ -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 hierarchy; + std::vector> contours; + + hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL); + std::vector 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(rect.size.width), + static_cast(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; +} diff --git a/ImageProcess/ImageApplyAutoCrop.h b/ImageProcess/ImageApplyAutoCrop.h new file mode 100644 index 0000000..491b2b8 --- /dev/null +++ b/ImageProcess/ImageApplyAutoCrop.h @@ -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 + + diff --git a/ImageProcess/ImageApplyBWBinaray.cpp b/ImageProcess/ImageApplyBWBinaray.cpp new file mode 100644 index 0000000..e321a5e --- /dev/null +++ b/ImageProcess/ImageApplyBWBinaray.cpp @@ -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; + } +} \ No newline at end of file diff --git a/ImageProcess/ImageApplyBWBinaray.h b/ImageProcess/ImageApplyBWBinaray.h new file mode 100644 index 0000000..b84e0a8 --- /dev/null +++ b/ImageProcess/ImageApplyBWBinaray.h @@ -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 + diff --git a/ImageChannel.cpp b/ImageProcess/ImageApplyChannel.cpp similarity index 84% rename from ImageChannel.cpp rename to ImageProcess/ImageApplyChannel.cpp index 85a6cb0..b38a341 100644 --- a/ImageChannel.cpp +++ b/ImageProcess/ImageApplyChannel.cpp @@ -1,8 +1,6 @@ -#include "StdAfx.h" -#include "ImageChannel.h" -using namespace cv; +#include "ImageApplyChannel.h" -CImageChannel::CImageChannel(int index) +CImageApplyChannel::CImageApplyChannel(int index) : m_cmIndex(index) { colorTable=NULL; @@ -14,8 +12,7 @@ CImageChannel::CImageChannel(int index) } - -CImageChannel::~CImageChannel(void) +CImageApplyChannel::~CImageApplyChannel(void) { 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"); 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"); } -void CImageChannel::setCH(int channel) +void CImageApplyChannel::setCH(int channel) { m_cmIndex = channel; } -int CImageChannel::getCH() +int CImageApplyChannel::getCH() { 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; min = ( (r3) { 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 channels = image.channels(); diff --git a/ImageChannel.h b/ImageProcess/ImageApplyChannel.h similarity index 66% rename from ImageChannel.h rename to ImageProcess/ImageApplyChannel.h index 97aebfb..97fbaae 100644 --- a/ImageChannel.h +++ b/ImageProcess/ImageApplyChannel.h @@ -1,11 +1,13 @@ -#pragma once +#ifndef IMAGE_APPLY_CHANNEL_H +#define IMAGE_APPLY_CHANNEL_H + #include "imageapply.h" -class CImageChannel : - public CImageApply + +class CImageApplyChannel : public CImageApply { public: - CImageChannel(int index); - virtual ~CImageChannel(void); + CImageApplyChannel(int index); + virtual ~CImageApplyChannel(void); virtual void apply(cv::Mat& pDib,int side); void setCH(int channel); @@ -20,3 +22,4 @@ private: unsigned char * colorTable; }; +#endif // !IMAGE_APPLY_CHANNEL_H \ No newline at end of file diff --git a/ImageProcess/ImageApplyCrop.cpp b/ImageProcess/ImageApplyCrop.cpp new file mode 100644 index 0000000..f18842e --- /dev/null +++ b/ImageProcess/ImageApplyCrop.cpp @@ -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(); +} diff --git a/ImageProcess/ImageApplyCrop.h b/ImageProcess/ImageApplyCrop.h new file mode 100644 index 0000000..c3ce1e0 --- /dev/null +++ b/ImageProcess/ImageApplyCrop.h @@ -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 \ No newline at end of file diff --git a/ImageProcDiscardBlank.cpp b/ImageProcess/ImageApplyDiscardBlank.cpp similarity index 85% rename from ImageProcDiscardBlank.cpp rename to ImageProcess/ImageApplyDiscardBlank.cpp index c4c49f7..74746dd 100644 --- a/ImageProcDiscardBlank.cpp +++ b/ImageProcess/ImageApplyDiscardBlank.cpp @@ -1,10 +1,9 @@ -#include "StdAfx.h" -#include "ImageProcDiscardBlank.h" +#include "ImageApplyDiscardBlank.h" using namespace cv; using namespace std; -int CImageProcDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect, vector& maxContour, double scale, double thresh, int blobAreaSize) +int CImageApplyDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect, vector& maxContour, double scale, double thresh, int blobAreaSize) { Mat gray; int blockCount = 0; @@ -91,7 +90,7 @@ int CImageProcDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect, 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++) { @@ -101,28 +100,28 @@ int CImageProcDiscardBlank::ProcessRectR(Mat & image, RotatedRect & rotatedRect, return true; } -CImageProcDiscardBlank::CImageProcDiscardBlank(bool isnormal) + CImageApplyDiscardBlank::CImageApplyDiscardBlank(bool 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); devTh = cv::Scalar(val, val, val, val); } -void CImageProcDiscardBlank::setMinArea(int val) +void CImageApplyDiscardBlank::setMinArea(int val) { dSize = max(min(500, val), 100); } -void CImageProcDiscardBlank::GetContours(const Mat& src, vector>& contours, vector& hierarchy, int retr /*= RETR_CCOMP*/) +void CImageApplyDiscardBlank::GetContours(const Mat& src, vector>& contours, vector& hierarchy, int retr /*= RETR_CCOMP*/) { CvMat c_image = src; MemStorage storage(cvCreateMemStorage()); @@ -166,7 +165,7 @@ void CImageProcDiscardBlank::GetContours(const Mat& src, vector>& } } -cv::Mat CImageProcDiscardBlank::getRoiMat(cv::Mat& image) +cv::Mat CImageApplyDiscardBlank::getRoiMat(cv::Mat& image) { int gap = 100; RotatedRect rect; @@ -183,7 +182,7 @@ cv::Mat CImageProcDiscardBlank::getRoiMat(cv::Mat& image) 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"); setIntensity(isNormalDiscard?8:20); diff --git a/ImageProcDiscardBlank.h b/ImageProcess/ImageApplyDiscardBlank.h similarity index 71% rename from ImageProcDiscardBlank.h rename to ImageProcess/ImageApplyDiscardBlank.h index da0703a..73ade6b 100644 --- a/ImageProcDiscardBlank.h +++ b/ImageProcess/ImageApplyDiscardBlank.h @@ -1,13 +1,13 @@ -#pragma once -#include "ImageApply.h" -#include +#ifndef IMAGE_APPLY_DISCARD_BLANK_H +#define IMAGE_APPLY_DISCARD_BLANK_H -class CImageProcDiscardBlank : - public CImageApply +#include "ImageApply.h" + +class CImageApplyDiscardBlank : public CImageApply { public: - CImageProcDiscardBlank(bool isnormal=true); - virtual ~CImageProcDiscardBlank(void); + CImageApplyDiscardBlank(bool isnormal=true); + virtual ~CImageApplyDiscardBlank(void); virtual void apply(cv::Mat& pDib,int side); @@ -27,3 +27,4 @@ private: cv::Mat getRoiMat(cv::Mat& pDib); }; +#endif // !IMAGE_APPLY_DISCARD_BLANK_H \ No newline at end of file diff --git a/ImageProcess/ImageApplyHeaders.h b/ImageProcess/ImageApplyHeaders.h new file mode 100644 index 0000000..b166ba9 --- /dev/null +++ b/ImageProcess/ImageApplyHeaders.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 diff --git a/ImageProcess/ImageApplyOutHole.cpp b/ImageProcess/ImageApplyOutHole.cpp new file mode 100644 index 0000000..3ae1053 --- /dev/null +++ b/ImageProcess/ImageApplyOutHole.cpp @@ -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> contours_front, contours_back; + std::vector 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 maxContour_front = hg::getMaxContour(contours_front, b1_front); + std::vector 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> contours_mask; + std::vector 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> 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 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(rrect_front.size.width + rrect_back.size.width) / 2, static_cast(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> ImageOutHole::filterPoly(std::vector>& contours, const std::vector& 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(roi.size.width * (1 - edgeScale * 2)), + static_cast(roi.size.height * (1 - edgeScale * 2))), roi.angle); + + std::vector vertices_roi1 = hg::getVertices(roi); + std::vector vertices_roi2 = hg::getVertices(roi2); + + std::vector> 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 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()); +} + diff --git a/ImageProcess/ImageApplyOutHole.h b/ImageProcess/ImageApplyOutHole.h new file mode 100644 index 0000000..4b57067 --- /dev/null +++ b/ImageProcess/ImageApplyOutHole.h @@ -0,0 +1,31 @@ +#ifndef IMAGE_APPLY_OUT_HOLE_H +#define IMAGE_APPLY_OUT_HOLE_H + +#include "opencv2/opencv.hpp" +#include + +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 > filterPoly(std::vector>& contours, const std::vector &m, cv::RotatedRect roi, + float edgeScale, float areaThreshold); + + cv::Scalar getBackGroudColor(const cv::Mat& image, const std::vector pixelPoints); +}; + +#endif // !IMAGE_APPLY_OUT_HOLE_H \ No newline at end of file diff --git a/ImageProcess/ImageApplyResize.cpp b/ImageProcess/ImageApplyResize.cpp new file mode 100644 index 0000000..6339ab4 --- /dev/null +++ b/ImageProcess/ImageApplyResize.cpp @@ -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); +} diff --git a/ImageProcess/ImageApplyResize.h b/ImageProcess/ImageApplyResize.h new file mode 100644 index 0000000..6dee284 --- /dev/null +++ b/ImageProcess/ImageApplyResize.h @@ -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 \ No newline at end of file diff --git a/ImageRotation.cpp b/ImageProcess/ImageApplyRotation.cpp similarity index 66% rename from ImageRotation.cpp rename to ImageProcess/ImageApplyRotation.cpp index bca4b0f..beaba6d 100644 --- a/ImageRotation.cpp +++ b/ImageProcess/ImageApplyRotation.cpp @@ -1,28 +1,26 @@ -#include "StdAfx.h" -#include "ImageRotation.h" -using namespace cv; -using namespace std; +#include "ImageApplyRotation.h" -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; } -int CImageRotation::getRotetion() +int CImageApplyRotation::getRotetion() { 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"); if (m_nRotation == 4)//自动文本方向识别 diff --git a/ImageProcess/ImageApplyRotation.h b/ImageProcess/ImageApplyRotation.h new file mode 100644 index 0000000..6a8bfb3 --- /dev/null +++ b/ImageProcess/ImageApplyRotation.h @@ -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 \ No newline at end of file diff --git a/ImageProcess/ImageApplySharpen.cpp b/ImageProcess/ImageApplySharpen.cpp new file mode 100644 index 0000000..1245788 --- /dev/null +++ b/ImageProcess/ImageApplySharpen.cpp @@ -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); +} diff --git a/ImageProcess/ImageApplySharpen.h b/ImageProcess/ImageApplySharpen.h new file mode 100644 index 0000000..aaee71c --- /dev/null +++ b/ImageProcess/ImageApplySharpen.h @@ -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 diff --git a/ImageProcess/ImageApplyTextOrientation.cpp b/ImageProcess/ImageApplyTextOrientation.cpp new file mode 100644 index 0000000..3dce548 --- /dev/null +++ b/ImageProcess/ImageApplyTextOrientation.cpp @@ -0,0 +1,10 @@ +#include "ImageApplyTextOrientation.h" + +ImageApplyTextOrientation::ImageApplyTextOrientation() +{ +} + + +ImageApplyTextOrientation::~ImageApplyTextOrientation() +{ +} diff --git a/ImageProcess/ImageApplyTextOrientation.h b/ImageProcess/ImageApplyTextOrientation.h new file mode 100644 index 0000000..ecefa54 --- /dev/null +++ b/ImageProcess/ImageApplyTextOrientation.h @@ -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 + diff --git a/ImageProcess/ImageProcess_Public.cpp b/ImageProcess/ImageProcess_Public.cpp new file mode 100644 index 0000000..709222f --- /dev/null +++ b/ImageProcess/ImageProcess_Public.cpp @@ -0,0 +1,289 @@ +#include "ImageProcess_Public.h" + +namespace hg +{ + void convexHull(const std::vector& src, std::vector& 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 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 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 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 left_edge; + std::vector 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(edge_left[0].y) * step; + for (size_t i = 0, length = cv::min(left_edge.size(), static_cast(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((offset + 1) * src.channels())); + } + std::vector right_edge; + std::vector 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(edge_right[0].y) * step; + for (size_t i = 0, length = cv::min(right_edge.size(), static_cast(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(offset * src.channels())); + } + + if (edge_left[0].y > 0) + memset(src.data, R_COLOR, static_cast(edge_left[0].y) * step); + + if (edge_left.back().y < src.rows - 1) + memset(src.data + static_cast(edge_left.back().y) * step, R_COLOR, + static_cast(src.rows - edge_left.back().y) * step); + } + + void fillPoly(cv::Mat & image, const std::vector& 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(count); + + cv::fillPoly(image, pointss, npts, 1, color); + + delete[] points; + } + + void findContours(const cv::Mat& src, std::vector>& contours, std::vector& 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 all_contours(cvTreeToNodeSeq(_ccontours, sizeof(CvSeq), storage)); + size_t total = all_contours.size(); + contours.resize(total); + + cv::SeqIterator it = all_contours.begin(); + for (size_t i = 0; i < total; i++, ++it) + { + CvSeq* c = *it; + reinterpret_cast(c)->color = static_cast(i); + int count = c->total; + int* data = new int[static_cast(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(c->h_next)->color : -1; + int h_prev = c->h_prev ? reinterpret_cast(c->h_prev)->color : -1; + int v_next = c->v_next ? reinterpret_cast(c->v_next)->color : -1; + int v_prev = c->v_prev ? reinterpret_cast(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& 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 getMaxContour(const std::vector>& contours, const std::vector& hierarchy) + { + std::vector 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 getVertices(const cv::RotatedRect& rect) + { + cv::Point2f box[4]; + rect.points(box); + std::vector points; + for (int i = 0; i < 4; i++) + points.push_back(cv::Point(box[i])); + + return points; + } + + void polyIndent(std::vector& 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(vec.x * vec.x / length)) * indent; + float y = cv::sqrt(static_cast(vec.y * vec.y / length)) * indent; + + if (vec.x < 0) x *= -1.0f; + if (vec.y < 0) y *= -1.0f; + + item.x -= static_cast(x); + item.y -= static_cast(y); + } + } + + hg::convexHull(points, points); + } + + cv::Mat transforColor(const cv::Mat& src) + { + if (src.channels() == 1) return src.clone(); + + std::vector 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(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(p.x), static_cast(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(dst.data); + return cv::Point(static_cast(ptr[0]), static_cast(ptr[1])); + } +} \ No newline at end of file diff --git a/ImageProcess/ImageProcess_Public.h b/ImageProcess/ImageProcess_Public.h new file mode 100644 index 0000000..f9c37a0 --- /dev/null +++ b/ImageProcess/ImageProcess_Public.h @@ -0,0 +1,33 @@ +#ifndef IMAGE_PROCESS_PUBLIC_H +#define IMAGE_PROCESS_PUBLIC_H + +#include "opencv2/opencv.hpp" +#include + +namespace hg +{ + void convexHull(const std::vector& src, std::vector& dst, bool clockwise = false); + + void fillBlackBackGround(cv::Mat& src, std::vector points); + + void fillPoly(cv::Mat& image, const std::vector& contours, const cv::Scalar& color); + + void findContours(const cv::Mat& src, std::vector>& contours, std::vector& 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& contour); + + std::vector getMaxContour(const std::vector>& contours, const std::vector& hierarchy); + + std::vector getVertices(const cv::RotatedRect& rect); + + void polyIndent(std::vector& 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 diff --git a/ImageRotation.h b/ImageRotation.h deleted file mode 100644 index 46181c3..0000000 --- a/ImageRotation.h +++ /dev/null @@ -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; -}; - diff --git a/TextDirection.cpp b/TextDirection.cpp deleted file mode 100644 index a882a0b..0000000 --- a/TextDirection.cpp +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/TextDirection.h b/TextDirection.h deleted file mode 100644 index b84ee1f..0000000 --- a/TextDirection.h +++ /dev/null @@ -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; -}; - diff --git a/config_new.cpp b/config_new.cpp index 34a6614..ce923f7 100644 --- a/config_new.cpp +++ b/config_new.cpp @@ -74,4 +74,5 @@ void config_new::set_unused_default_value(void) ms.v_setting = 0; ms.speed_set_enable = 0; ms.key_staple_enable = 0; + ms.scan_busy_motor_stop = 1; } diff --git a/device_common.h b/device_common.h index e9d404d..d4553b6 100644 --- a/device_common.h +++ b/device_common.h @@ -97,9 +97,10 @@ typedef union Motor_Setting { unsigned int iic_config : 1; unsigned int v_setting : 2; unsigned int speed_set_enable : 1; + unsigned int scan_busy_motor_stop : 1; unsigned int papar_type : 4; unsigned int color_model : 1; - unsigned int reserve : 3; + unsigned int reserve : 2; }; } MotorSetting; diff --git a/gscn_drv.cpp b/gscn_drv.cpp index 705bc68..8471b46 100644 --- a/gscn_drv.cpp +++ b/gscn_drv.cpp @@ -5,7 +5,7 @@ #include #include "twainEx.h" #include "jpeglib.h" -#include "ImageApply.h" +#include "ImageProcess/ImageApplyHeaders.h" #include "hugaotwainds.h" #include "filetools.h" #include "UsbScanEx.h" diff --git a/hugaotwainds.vcxproj b/hugaotwainds.vcxproj index a511f73..1cdef2d 100644 --- a/hugaotwainds.vcxproj +++ b/hugaotwainds.vcxproj @@ -23,7 +23,7 @@ {F928F998-CD13-478E-8D23-5943C2B108F5} MFCDLLProj hugaotwainds - 10.0 + 10.0.18362.0 @@ -213,7 +213,6 @@ - @@ -234,18 +233,48 @@ - - - - - - - - - + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + + + NotUsing + @@ -264,7 +293,6 @@ Create - @@ -284,7 +312,6 @@ - @@ -309,18 +336,23 @@ - - - - - - - - - + + + + + + + + + + + + + + @@ -341,7 +373,6 @@ - diff --git a/hugaotwainds.vcxproj.filters b/hugaotwainds.vcxproj.filters index dad94b6..4660950 100644 --- a/hugaotwainds.vcxproj.filters +++ b/hugaotwainds.vcxproj.filters @@ -117,42 +117,12 @@ 鍏叡搴 - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - 鍥惧儚澶勭悊 - - 鍥惧儚澶勭悊 - UI - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - 浠g爜鏂囦欢 @@ -165,9 +135,6 @@ USB閫氫俊 - - 鍥惧儚澶勭悊 - 浠g爜鏂囦欢 @@ -198,12 +165,51 @@ USB閫氫俊 - - 鍥惧儚澶勭悊 - 浠g爜鏂囦欢 + + 浠g爜鏂囦欢 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + @@ -322,45 +328,15 @@ 鍏叡搴 - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - 鍥惧儚澶勭悊 - - 鍥惧儚澶勭悊 - 澶存枃浠 UI - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - - - 鍥惧儚澶勭悊 - 澶存枃浠 @@ -376,9 +352,6 @@ 鍏叡搴 - - 鍥惧儚澶勭悊 - 澶存枃浠 @@ -430,6 +403,48 @@ 澶存枃浠 + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + + + 鍥惧儚澶勭悊 + diff --git a/hugaotwainds.vcxproj.user b/hugaotwainds.vcxproj.user index ad2d9c4..2bba54f 100644 --- a/hugaotwainds.vcxproj.user +++ b/hugaotwainds.vcxproj.user @@ -1,7 +1,7 @@ 锘 - C:\Program Files\XnView\xnview.exe + E:\杞欢瀹夎鍖匼xnviewer\xnviewer\xnview.exe C:\Windows\twain_32\huagoscan WindowsLocalDebugger