1.在图像处理线程增加原图畸变拉伸功能;

2.内存优化,针对300DPI 做内存限制
This commit is contained in:
lovelyyoung 2020-05-16 09:55:40 +08:00
parent 639a175a17
commit a11f063bf4
2 changed files with 79 additions and 57 deletions

View File

@ -39,6 +39,7 @@ G200Decode::G200Decode(std::shared_ptr<std::vector<char>> buff)
buffF->resize(f_buffer_size); buffF->resize(f_buffer_size);
m_buffs.push_back(buffB); m_buffs.push_back(buffB);
m_buffs.push_back(buffF); m_buffs.push_back(buffF);
buff.reset();
#else // G200 #else // G200
m_buffs.push_back(buff); m_buffs.push_back(buff);
#endif #endif
@ -47,13 +48,14 @@ G200Decode::G200Decode(std::shared_ptr<std::vector<char>> buff)
ImageMatQueue::ImageMatQueue(void) ImageMatQueue::ImageMatQueue(void)
: bRun(false) : bRun(false)
, is_scanning(false) , is_scanning(false)
,fx(1.001)
,fy(1.007)
{ {
atm_orgin_image_remains = 0; atm_orgin_image_remains = 0;
} }
void ImageMatQueue::run() void ImageMatQueue::run()
{ {
GetFixRatio(fx, fy);
if (!m_threadProc) { if (!m_threadProc) {
bRun = true; bRun = true;
m_threadProc.reset(new thread(&ImageMatQueue::proc, this)); m_threadProc.reset(new thread(&ImageMatQueue::proc, this));
@ -65,6 +67,23 @@ int ImageMatQueue::orginimgcount()
return atm_orgin_image_remains; return atm_orgin_image_remains;
} }
float ImageMatQueue::getdpi()
{
return scanParam.resolution_dst;
}
void ImageMatQueue::updatefixratio(float& hratio, float& vratio)
{
if (hratio > 0.80f && hratio < 1.2f && vratio >0.80f && vratio < 1.2f) {
fx = hratio;
fy = vratio;
}
else
{
writelog("error horizental or vertical ratio");
}
}
ImageMatQueue::~ImageMatQueue(void) ImageMatQueue::~ImageMatQueue(void)
{ {
m_rawBuffs.Clear(); m_rawBuffs.Clear();
@ -80,16 +99,13 @@ ImageMatQueue::~ImageMatQueue(void)
void ImageMatQueue::pushMat(std::shared_ptr<IDecode> data) void ImageMatQueue::pushMat(std::shared_ptr<IDecode> data)
{ {
//std::lock_guard<std::mutex> lock(m_mtxJB);
m_rawBuffs.Put(data); m_rawBuffs.Put(data);
atm_orgin_image_remains++; atm_orgin_image_remains++;
} }
std::vector<unsigned char> ImageMatQueue::popBmpdata() std::shared_ptr<std::vector<unsigned char>> ImageMatQueue::popBmpdata()
{ {
//std::lock_guard<std::mutex> lock(m_mtxJB); return m_imagedata.Take();
std::vector<unsigned char> retdata = m_imagedata.Take();
return retdata;
} }
bool ImageMatQueue::valid() bool ImageMatQueue::valid()
@ -210,9 +226,12 @@ void ImageMatQueue::setparam(const GScanCap& param)
void ImageMatQueue::EnqueueBmpBuffer(std::vector<unsigned char>& bmpdata) void ImageMatQueue::EnqueueBmpBuffer(std::vector<unsigned char>& bmpdata)
{ {
//std::lock_guard<std::mutex> lock(m_Locker); //std::lock_guard<std::mutex> lock(m_Locker);
//m_imagedata.Put(bmpdata);
}
void ImageMatQueue::EnqueueBmpBuffer(std::shared_ptr<std::vector<unsigned char>> bmpdata)
{
m_imagedata.Put(bmpdata); m_imagedata.Put(bmpdata);
} }
void ImageMatQueue::PaniusCount() void ImageMatQueue::PaniusCount()
{ {
atm_orgin_image_remains--; atm_orgin_image_remains--;
@ -251,12 +270,14 @@ void ImageMatQueue::proc()
try try
{ {
cv::Mat mat = cv::imdecode(*buf, rm); cv::Mat mat = cv::imdecode(*buf, rm);
buf.reset();
if (mat.empty()) { if (mat.empty()) {
writelog("decode image data error"); writelog("decode image data error");
} }
#ifdef G200 #ifdef G200
resize(mat, mat, cv::Size(), 1.001, 1.007);//用于修正与佳能机器幅面大小不匹配问题 此系数请勿轻易动 resize(mat, mat, cv::Size(), fx, fy);//用于修正与佳能机器幅面大小不匹配问题 此系数请勿轻易动
mats.push_back(mat); mats.push_back(mat);
mat.release();
#else // G200 #else // G200
//resize(mat, mat, cv::Size(), 1.001, 1.0070);//用于修正与佳能机器幅面大小不匹配问题 此系数请勿轻易动 //resize(mat, mat, cv::Size(), 1.001, 1.0070);//用于修正与佳能机器幅面大小不匹配问题 此系数请勿轻易动
Mat front = mat(Rect(0, 0, mat.cols / 2, mat.rows)); Mat front = mat(Rect(0, 0, mat.cols / 2, mat.rows));
@ -271,6 +292,7 @@ void ImageMatQueue::proc()
writelog(e.what()); writelog(e.what());
} }
} }
buffs.clear();
for (int j = 0; j < m_iaList.size(); j++) { for (int j = 0; j < m_iaList.size(); j++) {
m_iaList[j]->apply(mats, scanParam.is_duplex); m_iaList[j]->apply(mats, scanParam.is_duplex);
@ -285,6 +307,7 @@ void ImageMatQueue::proc()
IMat2Bmp idata; IMat2Bmp idata;
idata = scanParam.pixtype == 0 ? (IMat2Bmp)Mat2BmpBw(mats[i], scanParam.resolution_dst) : Mat2Bmp(mats[i], scanParam.resolution_dst); idata = scanParam.pixtype == 0 ? (IMat2Bmp)Mat2BmpBw(mats[i], scanParam.resolution_dst) : Mat2Bmp(mats[i], scanParam.resolution_dst);
auto data = idata.getBmpDataBuffer(); auto data = idata.getBmpDataBuffer();
//mats[i].release();
EnqueueBmpBuffer(data); EnqueueBmpBuffer(data);
} }
else else
@ -298,6 +321,7 @@ void ImageMatQueue::proc()
if (!mats[i].empty()) { if (!mats[i].empty()) {
ImageMultiOutput m_mlt; ImageMultiOutput m_mlt;
Mat ret = m_mlt.GetMultiFilterMat(mats[i], 2); Mat ret = m_mlt.GetMultiFilterMat(mats[i], 2);
mats[i].release();
if (!ret.empty()) { if (!ret.empty()) {
if (!scanParam.is_duplex && i == 1) { if (!scanParam.is_duplex && i == 1) {
ret.release(); ret.release();
@ -305,43 +329,18 @@ void ImageMatQueue::proc()
} }
Mat2Bmp mb(ret, scanParam.resolution_dst); Mat2Bmp mb(ret, scanParam.resolution_dst);
auto data = mb.getBmpDataBuffer(); auto data = mb.getBmpDataBuffer();
ret.release();
EnqueueBmpBuffer(data); EnqueueBmpBuffer(data);
} }
} }
} }
} }
mats.clear();
PaniusCount(); PaniusCount();
} }
} }
} }
void ImageMatQueue::GetFixRatio(double& fixX,double& fixY)
{
//TCHAR szIniFile[MAX_PATH] = { 0 };
//SHGetSpecialFolderPath(NULL, szIniFile, CSIDL_LOCAL_APPDATA, TRUE);
//_tcscat(szIniFile, HUAGAO_SCAN);
//_tcscat(szIniFile, _T("\\fixed.txt"));
//string path = TCHAR2STRING(szIniFile);
fixX = 1.0010;
fixY = 1.0070;
//if (path.length() > 1) {
// ifstream io(path);
// if (io.is_open()) {
// int linenum = 0;
// string str_line;
// while (!io.eof())
// {
// getline(io, str_line);
// linenum == 0 ? fixY = stod(str_line) : fixX = stod(str_line);
// }
// }
// else
// {
// writelog("error on getting xy ratio");
// }
//}
}
GRawDecode::GRawDecode(std::shared_ptr<std::vector<char>> buff) GRawDecode::GRawDecode(std::shared_ptr<std::vector<char>> buff)
{ {
m_buffs.push_back(buff); m_buffs.push_back(buff);

View File

@ -12,21 +12,47 @@
class IMat2Bmp { class IMat2Bmp {
public: public:
virtual ~IMat2Bmp() {} virtual ~IMat2Bmp() {}
virtual std::vector<unsigned char> getBmpDataBuffer() { virtual std::shared_ptr<std::vector<unsigned char>> getBmpDataBuffer() {
return m_data; return m_data;
}; };
virtual void setBmpFileHeader(const cv::Mat& mat) {};
virtual void setBmpInfoHeader(const cv::Mat& mat, const long res) {};
protected: protected:
std::vector<unsigned char> m_data; std::shared_ptr<std::vector<unsigned char>> m_data;
}; };
class Mat2Bmp:public IMat2Bmp { class Mat2Bmp:public IMat2Bmp {
public: public:
Mat2Bmp(const cv::Mat& mat,float res) { Mat2Bmp(const cv::Mat& mat,float res) {
m_data =std::shared_ptr<std::vector<unsigned char>>(new std::vector<unsigned char>());
int headersize = mat.channels() == 3 ? 54 : 1078; int headersize = mat.channels() == 3 ? 54 : 1078;
int bmpdatasize = mat.step1() * mat.rows; int bmpdatasize = mat.step1() * mat.rows;
m_data.resize(headersize + bmpdatasize); m_data->resize(headersize + bmpdatasize);
cv::imencode(".bmp", mat, m_data); cv::imencode(".bmp", mat, *(m_data.get()));
BITMAPINFOHEADER* infoheader = (BITMAPINFOHEADER*)(m_data.data() + sizeof(BITMAPFILEHEADER)); setBmpFileHeader(mat);
setBmpInfoHeader(mat, res);
}
private:
void setBmpFileHeader(const cv::Mat& mat)
{
BITMAPFILEHEADER* fileheader = (BITMAPFILEHEADER*)(m_data->data());
fileheader->bfType = ((unsigned short)('M' << 8) | 'B');
fileheader->bfSize = m_data.get()->size();
fileheader->bfReserved1 = 0;
fileheader->bfReserved2 = 0;
fileheader->bfOffBits = mat.channels() == 3 ? 54 : 1078;
}
void setBmpInfoHeader(const cv::Mat& mat, const long res)
{
BITMAPINFOHEADER* infoheader = (BITMAPINFOHEADER*)(m_data->data() + sizeof(BITMAPFILEHEADER));
infoheader->biSize = sizeof(BITMAPINFOHEADER);
infoheader->biWidth = mat.cols;
infoheader->biHeight = mat.rows;
infoheader->biPlanes = 1;
infoheader->biBitCount = mat.channels() == 3 ? 24 : 8;
infoheader->biCompression = 0;
infoheader->biSizeImage = (int)((mat.cols * mat.channels() * 8 + 31) / 32) * 4 * mat.rows;
infoheader->biXPelsPerMeter = infoheader->biYPelsPerMeter = static_cast<LONG>(res * 39.37F + 0.5); infoheader->biXPelsPerMeter = infoheader->biYPelsPerMeter = static_cast<LONG>(res * 39.37F + 0.5);
infoheader->biClrUsed = infoheader->biClrImportant = infoheader->biBitCount == 8 ? 256 : 0; infoheader->biClrUsed = infoheader->biClrImportant = infoheader->biBitCount == 8 ? 256 : 0;
} }
@ -35,18 +61,18 @@ public:
class Mat2BmpBw :public IMat2Bmp { class Mat2BmpBw :public IMat2Bmp {
public: public:
Mat2BmpBw(const cv::Mat& mat,float res) { Mat2BmpBw(const cv::Mat& mat,float res) {
//cv::imwrite("bw.bmp", mat); m_data = std::shared_ptr<std::vector<unsigned char>>(new std::vector<unsigned char >());
int headsize = 62; int headsize = 62;
int width = mat.cols; int width = mat.cols;
int height = mat.rows; int height = mat.rows;
int bmpdatasize = (width + 31) / 32 * 4*height; int bmpdatasize = (width + 31) / 32 * 4*height;
m_data.resize(headsize + bmpdatasize); m_data->resize(headsize + bmpdatasize);
unsigned char* binary = m_data.data()+62;//file header(14)+info header(40)+RGBQUAD(8) unsigned char* binary = m_data->data()+62;//file header(14)+info header(40)+RGBQUAD(8)
setBmpFileHeader(mat,bmpdatasize); setBmpFileHeader(mat,bmpdatasize);
setBmpInfoHeader(mat, bmpdatasize, res); setBmpInfoHeader(mat, bmpdatasize, res);
memcpy(m_data.data(), &m_fileHeader, sizeof(BITMAPFILEHEADER)); memcpy(m_data->data(), &m_fileHeader, sizeof(BITMAPFILEHEADER));
memcpy(m_data.data() + sizeof(BITMAPFILEHEADER), &m_infoHeader, sizeof(BITMAPINFOHEADER)); memcpy(m_data->data() + sizeof(BITMAPFILEHEADER), &m_infoHeader, sizeof(BITMAPINFOHEADER));
RGBQUAD* quad = (RGBQUAD*)(m_data.data() + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)); RGBQUAD* quad = (RGBQUAD*)(m_data->data() + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER));
quad->rgbBlue = quad->rgbGreen = quad->rgbRed = quad->rgbReserved = 0; quad->rgbBlue = quad->rgbGreen = quad->rgbRed = quad->rgbReserved = 0;
quad++; quad++;
quad->rgbBlue = quad->rgbGreen = quad->rgbRed = 255; quad->rgbBlue = quad->rgbGreen = quad->rgbRed = 255;
@ -83,7 +109,7 @@ private:
m_fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + nDIBSize; m_fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + nDIBSize;
} }
void setBmpInfoHeader(const cv::Mat& mat,const int bmpDataLen, const long res) { void setBmpInfoHeader(const cv::Mat& mat,const int bmpDataLen, const long res){
memset(&m_infoHeader, 0, sizeof(BITMAPINFOHEADER)); memset(&m_infoHeader, 0, sizeof(BITMAPINFOHEADER));
m_infoHeader.biSize = sizeof(BITMAPINFOHEADER); m_infoHeader.biSize = sizeof(BITMAPINFOHEADER);
m_infoHeader.biWidth = mat.cols; m_infoHeader.biWidth = mat.cols;
@ -93,8 +119,7 @@ private:
m_infoHeader.biCompression = 0; m_infoHeader.biCompression = 0;
m_infoHeader.biSizeImage = bmpDataLen; m_infoHeader.biSizeImage = bmpDataLen;
m_infoHeader.biXPelsPerMeter = m_infoHeader.biYPelsPerMeter = static_cast<LONG>(res * 39.37F + 0.5); m_infoHeader.biXPelsPerMeter = m_infoHeader.biYPelsPerMeter = static_cast<LONG>(res * 39.37F + 0.5);
m_infoHeader.biClrUsed = 2; m_infoHeader.biClrUsed = m_infoHeader.biClrImportant = 2;
m_infoHeader.biClrImportant = 2;
} }
private: private:
@ -129,7 +154,7 @@ public:
virtual ~ImageMatQueue(void); virtual ~ImageMatQueue(void);
void pushMat(std::shared_ptr<IDecode> buf); void pushMat(std::shared_ptr<IDecode> buf);
std::vector<unsigned char> popBmpdata(); std::shared_ptr<std::vector<unsigned char>> popBmpdata();
bool empty(); bool empty();
bool valid(); bool valid();
void clear(); void clear();
@ -137,16 +162,14 @@ public:
void run(); void run();
int orginimgcount(); int orginimgcount();
void setscanflags(const bool flags) { is_scanning = flags; } void setscanflags(const bool flags) { is_scanning = flags; }
float getdpi();
void updatefixratio(float& hratio, float& vratio);
private: private:
void proc(); void proc();
void GetFixRatio(double& fixX, double& fixY);
void EnqueueBmpBuffer(std::vector<unsigned char>& bmpdata); void EnqueueBmpBuffer(std::vector<unsigned char>& bmpdata);
void EnqueueBmpBuffer(std::shared_ptr<std::vector<unsigned char>>);
void PaniusCount(); void PaniusCount();
BlockingQueue<std::vector<unsigned char>> m_imagedata; BlockingQueue<std::shared_ptr<std::vector<unsigned char>>>m_imagedata;
std::mutex m_Locker;
std::mutex m_mtxJB;
std::mutex m_mtxscan;
std::unique_ptr<thread> m_threadProc; std::unique_ptr<thread> m_threadProc;
volatile bool bRun; volatile bool bRun;
volatile int atm_orgin_image_remains; volatile int atm_orgin_image_remains;
@ -155,5 +178,5 @@ private:
Device::PaperSize papersize; Device::PaperSize papersize;
std::vector<std::shared_ptr<CImageApply>> m_iaList; std::vector<std::shared_ptr<CImageApply>> m_iaList;
BlockingQueue<std::shared_ptr<IDecode>> m_rawBuffs; BlockingQueue<std::shared_ptr<IDecode>> m_rawBuffs;
double fx, fy; float fx, fy;
}; };