图像处理单独线程处理

This commit is contained in:
masayume 2021-07-21 10:41:17 +08:00
parent d3c784a8b2
commit e580e312a8
3 changed files with 90 additions and 39 deletions

View File

@ -10,27 +10,35 @@ static std::mutex mx_ctrl;
static int scanner_read_reg(std::shared_ptr<IUsb>& usb, int addr) static int scanner_read_reg(std::shared_ptr<IUsb>& usb, int addr)
{ {
int val = 0; if (usb.get() && usb->is_connected()) {
std::lock_guard<std::mutex> lck(mx_ctrl); int val = 0;
usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val); std::lock_guard<std::mutex> lck(mx_ctrl);
return val; usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val);
return val;
}
return 0;
} }
static void scanner_write_reg(std::shared_ptr<IUsb>& usb, int addr, int val) static void scanner_write_reg(std::shared_ptr<IUsb>& usb, int addr, int val)
{ {
std::lock_guard<std::mutex> lck(mx_ctrl); if (usb.get() && usb->is_connected())
usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val); {
std::lock_guard<std::mutex> lck(mx_ctrl);
usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val);
}
} }
static void scanner_cmd(std::shared_ptr<IUsb>& usb, int cmd) static void scanner_cmd(std::shared_ptr<IUsb>& usb, int cmd)
{ {
scanner_write_reg(usb, 0, cmd); if (usb.get() && usb->is_connected())
scanner_write_reg(usb, 0, cmd);
} }
GScanO1003399::GScanO1003399(): GScanO1003399::GScanO1003399():
m_imgthread(1) m_imgthread(1)
,m_imgprocthread(1)
{ {
im_data.reset(new std::vector<char>()); im_data.reset(new std::vector<char>());
open(0, 0); open(0, 0);
@ -40,12 +48,14 @@ GScanO1003399::GScanO1003399():
GScanO1003399::~GScanO1003399() GScanO1003399::~GScanO1003399()
{ {
image = 0;
if (m_usbthread.get() && m_usbthread->joinable()) if (m_usbthread.get() && m_usbthread->joinable())
{ {
b_usbthread = false; b_usbthread = false;
m_usbthread->join(); m_usbthread->join();
m_usbthread.reset(); m_usbthread.reset();
} }
m_usb.reset();
} }
void GScanO1003399::open(int vid, int pid) void GScanO1003399::open(int vid, int pid)
@ -64,35 +74,55 @@ void GScanO1003399::open(int vid, int pid)
{ {
m_usb = *lsusb.begin(); m_usb = *lsusb.begin();
m_usb->open(); m_usb->open();
if (m_usb->is_open())
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
} }
} }
void GScanO1003399::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata) void GScanO1003399::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata)
{ {
huagods = usrdata;
dev_callback = callback;
} }
void GScanO1003399::usbhotplug_callback(bool isconnect, void* userdata)
{
GScanO1003399* This = (GScanO1003399*)userdata;
This->usbhotplug(isconnect);
}
void GScanO1003399::usbhotplug(bool isleft)
{
FileTools::writelog(log_ERROR, "enable usb callback ");
if (isleft) {
devState = DEV_WRONG;
Error_Code = USB_DISCONNECTED;
scanflag = false;
if (m_usb.get())
m_usb.reset();
if (huagods)
dev_callback(USB_DISCONNECTED, huagods);
}
}
void GScanO1003399::DogEar_callback(std::function<void(int)> fun) void GScanO1003399::DogEar_callback(std::function<void(int)> fun)
{ {
} }
static int aquirenum = 0; static int aquirenum = 0;
static int getimgnum = 0; static int getimgnum = 0;
static StopWatch stopwatch;
int GScanO1003399::aquire_bmpdata(std::vector<unsigned char>& bmpdata) int GScanO1003399::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
{ {
StopWatch sw; StopWatch sw;
while (true) while (true)
{ {
if ((image==0)&&(!is_runing())&&(!scanflag)) if ((image == 0) && (!is_runing()) && (!scanflag) || (sw.elapsed_s() > 30))
{ {
DoEvents(); DoEvents();
this_thread::sleep_for(chrono::milliseconds(1)); this_thread::sleep_for(chrono::milliseconds(1));
if (!is_runing())
{
int roller_num_new= count();
set_scannum(abs(roller_num_new - roller_num));
if (devState == DEV_WRONG)
return get_ErrorCode();
return -1;
}
if (sw.elapsed_s() > 30.0) if (sw.elapsed_s() > 30.0)
{ {
devState = DEV_STOP; devState = DEV_STOP;
@ -102,6 +132,14 @@ int GScanO1003399::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
set_scannum(abs(roller_num_new - roller_num)); set_scannum(abs(roller_num_new - roller_num));
return AQUIRE_IMAGE_TIMEOUT; return AQUIRE_IMAGE_TIMEOUT;
} }
if (!is_runing())
{
int roller_num_new = count();
set_scannum(abs(roller_num_new - roller_num));
if (devState == DEV_WRONG)
return get_ErrorCode();
return -1;
}
} }
else else
{ {
@ -111,6 +149,9 @@ int GScanO1003399::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
bmpdata = *(m_imagedata.Take()); bmpdata = *(m_imagedata.Take());
UpdateScanInfo(get_imgnReaded(), countNTransfered()); UpdateScanInfo(get_imgnReaded(), countNTransfered());
image--; image--;
sw.reset();
FileTools::writelog(log_DEBUG, "3399上层取图间隔 " + to_string(stopwatch.elapsed_ms()));
stopwatch.reset();
return 0; return 0;
} }
DoEvents(); DoEvents();
@ -407,7 +448,7 @@ void GScanO1003399::usb_run()
} }
if ((codeconvter(info) != 0)) if ((codeconvter(info) != 0))
{ {
if (info.Code==0x10||info.Code==0x20||info.Code==0x40) if (info.Code == 0x10 || info.Code == 0x20 || info.Code == 0x40)
{ {
while (scanner_read_reg(m_usb, SR_STATUS) & 0x1) while (scanner_read_reg(m_usb, SR_STATUS) & 0x1)
this_thread::sleep_for(chrono::microseconds(10)); this_thread::sleep_for(chrono::microseconds(10));
@ -415,7 +456,7 @@ void GScanO1003399::usb_run()
pop_dev_im(); pop_dev_im();
pop_dev_im(); pop_dev_im();
} }
else if ((get_ErrorCode() != PAPER_JAM) && (get_ErrorCode() != DETECT_DOUBLE_FEED) && (get_ErrorCode() != DETECT_STAPLE))
{ {
keeplastimg = false; keeplastimg = false;
im_rx(); im_rx();
@ -492,7 +533,7 @@ bool GScanO1003399::is_dev_tx()
{ {
return scanner_read_reg(m_usb, SR_IM_TXING); return scanner_read_reg(m_usb, SR_IM_TXING);
} }
static StopWatch swatch;
void GScanO1003399::im_rx() void GScanO1003399::im_rx()
{ {
if (!is_rx() && !is_dev_tx()) if (!is_rx() && !is_dev_tx())
@ -510,7 +551,8 @@ void GScanO1003399::im_rx()
if(im_dev_count()<2) if(im_dev_count()<2)
continue; continue;
} }
auto &buffi = im_data; //auto &buffi = im_data;
std::shared_ptr<std::vector<char>> buffi(new std::vector<char>);
int count = front_datasize(); int count = front_datasize();
buffi->resize(count); buffi->resize(count);
rx_cmd(); rx_cmd();
@ -518,13 +560,22 @@ void GScanO1003399::im_rx()
count = read_data(buffi->data(), count, count / (0.01 * 1024 * 1024)); count = read_data(buffi->data(), count, count / (0.01 * 1024 * 1024));
pop_dev_im(); pop_dev_im();
vector<cv::Mat> mats; vector<cv::Mat> mats;
auto& buffs = G400Decode(buffi).getImageBuffs();
if (m_param.multi_output_red) if (m_param.multi_output_red)
image += 2; image += 2;
else else
image++; image++;
UpdateScanInfo(countNReaded(), get_imgTransfered()); UpdateScanInfo(countNReaded(), get_imgTransfered());
imgproce(buffs); FileTools::writelog(log_DEBUG, "3399usb取图间隔 " + to_string(swatch.elapsed_ms()));
swatch.reset();
imgs.Put(buffi);
fu_imgpro.push(m_imgprocthread.enqueue([this] {
imgproce(imgs.Take());
}));
while (fu_imgpro.size()>1)
{
fu_imgpro.front().get();
fu_imgpro.pop();
}
} }
}); });
} }
@ -532,6 +583,8 @@ void GScanO1003399::im_rx()
int GScanO1003399::read_data(void* data, int length, int timeout) int GScanO1003399::read_data(void* data, int length, int timeout)
{ {
if (!m_usb.get() && !m_usb->is_connected())
return 0;
int readed = 0; int readed = 0;
int reading = 0; int reading = 0;
const int buffer_size = 2 * 1024 * 1024; const int buffer_size = 2 * 1024 * 1024;
@ -561,9 +614,11 @@ int GScanO1003399::im_dev_count()
return scanner_read_reg(m_usb, SR_IM_COUNT); //!< to-list ; return scanner_read_reg(m_usb, SR_IM_COUNT); //!< to-list ;
} }
void GScanO1003399::imgproce(std::vector<std::shared_ptr<std::vector<char>>>& buffs) void GScanO1003399::imgproce(std::shared_ptr<std::vector<char>>& buff)
{ {
auto& buffs= G400Decode(buff).getImageBuffs();
vector<cv::Mat> mats; vector<cv::Mat> mats;
StopWatch sw;
bool isbwimg = false; bool isbwimg = false;
for (auto& buf : buffs) { for (auto& buf : buffs) {
cv::ImreadModes rmc = m_param.pixtype == 2 ? cv::IMREAD_COLOR : cv::IMREAD_GRAYSCALE; cv::ImreadModes rmc = m_param.pixtype == 2 ? cv::IMREAD_COLOR : cv::IMREAD_GRAYSCALE;
@ -580,36 +635,27 @@ void GScanO1003399::imgproce(std::vector<std::shared_ptr<std::vector<char>>>& bu
continue; continue;
} }
buf.reset(); buf.reset();
//if (isbwimg)
// cv::flip(mat, mat, 0);
mats.push_back(mat); mats.push_back(mat);
FileTools::writelog(log_INFO, "push_back image num= " + to_string(getimgnum++)); FileTools::writelog(log_INFO, "push_back image num= " + to_string(getimgnum++));
} }
catch (const std::exception& e) catch (const std::exception& e)
{ {
//writelog(e.what());
FileTools::writelog(log_ERROR, e.what()); FileTools::writelog(log_ERROR, e.what());
} }
} }
FileTools::writelog(log_DEBUG, "3399图像解码耗时 " + to_string(sw.elapsed_ms()));
buffs.clear(); buffs.clear();
if (m_param.automaticcolor) if (m_param.automaticcolor)
{ {
CImageApplyColorRecognition(m_param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono).apply(mats,m_param.is_duplex); CImageApplyColorRecognition(m_param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono).apply(mats,m_param.is_duplex);
} }
for (int i = 0; i < mats.size(); i++) { for (int i = 0; i < mats.size(); i++) {
//if (!m_param.is_duplex && i == 1) {
// mats[i].release();
// break;
//}
if (!mats[i].empty()) { if (!mats[i].empty()) {
IMat2Bmp idata; IMat2Bmp idata;
if (m_param.pixtype == 1 && m_param.hsvcorrect) if (m_param.pixtype == 1 && m_param.hsvcorrect)
if (mats[i].channels() == 3) if (mats[i].channels() == 3)
cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY); cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY);
idata = (isbwimg|| m_param.pixtype == 0 || (((m_param.automaticcolortype == 0) && (m_param.automaticcolor == true)) && (mats[i].channels() == 1))) ? (IMat2Bmp)Mat2BmpBw(mats[i], m_param.resolution_dst) : Mat2Bmp(mats[i], m_param.resolution_dst); idata = (isbwimg|| m_param.pixtype == 0 || (((m_param.automaticcolortype == 0) && (m_param.automaticcolor == true)) && (mats[i].channels() == 1))) ? (IMat2Bmp)Mat2BmpBw(mats[i], m_param.resolution_dst) : Mat2Bmp(mats[i], m_param.resolution_dst);
//if (!m_param.multi_output_red)
// mats[i].release();
m_imagedata.Put(idata.getBmpDataBuffer()); m_imagedata.Put(idata.getBmpDataBuffer());
} }
} }

View File

@ -65,8 +65,10 @@ private:
void pop_dev_im(); void pop_dev_im();
int front_datasize(); int front_datasize();
int im_dev_count(); int im_dev_count();
void imgproce(std::vector<std::shared_ptr<std::vector<char>>>& buffs); void imgproce(std::shared_ptr<std::vector<char>>& buffs);
int codeconvter(HGEIntInfo code); int codeconvter(HGEIntInfo code);
static void usbhotplug_callback(bool isconnect, void* userdata);
void usbhotplug(bool isleft);
private: private:
volatile int devState; volatile int devState;
@ -76,12 +78,16 @@ private:
GScanCap m_param; GScanCap m_param;
std::shared_ptr<IUsb> m_usb; std::shared_ptr<IUsb> m_usb;
volatile bool b_usbthread; volatile bool b_usbthread;
BlockingQueue<std::shared_ptr<std::vector<char>>> imgs;
std::future<void> fu_rx; std::future<void> fu_rx;
std::queue<std::future<void>> fu_imgpro;
ThreadPool m_imgthread; ThreadPool m_imgthread;
ThreadPool m_imgprocthread;
std::shared_ptr<std::thread> m_usbthread; std::shared_ptr<std::thread> m_usbthread;
std::shared_ptr<std::vector<char>> im_data; std::shared_ptr<std::vector<char>> im_data;
BlockingQueue<std::shared_ptr<std::vector<unsigned char>>> m_imagedata; BlockingQueue<std::shared_ptr<std::vector<unsigned char>>> m_imagedata;
std::atomic_int image; std::atomic_int image;
void* huagods;
deviceevent_callback dev_callback;
}; };

View File

@ -2,7 +2,8 @@
#include "UsbScanEx.h" #include "UsbScanEx.h"
#include <tchar.h> #include <tchar.h>
#include <winioctl.h> #include <winioctl.h>
//#include "filetools.h"
#include "filetools.h"
UsbScanEx::UsbScanEx(int index) UsbScanEx::UsbScanEx(int index)
{ {
@ -177,7 +178,6 @@ int UsbScanEx::read_bulk(void* data, int len)
} }
break; break;
default: default:
//FileTools::writelog(log_INFO,"Usb read_bulk error code : " + std::to_string(error_code));
break; break;
} }
} }
@ -211,13 +211,11 @@ int UsbScanEx::write_bulk(void* data, int len)
case ERROR_FILE_NOT_FOUND: case ERROR_FILE_NOT_FOUND:
case ERROR_ACCESS_DENIED: case ERROR_ACCESS_DENIED:
m_b_is_connected = false; m_b_is_connected = false;
//FileTools::writelog(log_lv::log_WARN,"errorcode ="+ std::to_string(errorcode));
if (hotplug_call) { if (hotplug_call) {
hotplug_call(true, usrdata); hotplug_call(true, usrdata);
} }
break; break;
default: default:
//FileTools::writelog(log_INFO,"Usb write_bulk error code: " + std::to_string(errorcode));
break; break;
} }
} }
@ -283,6 +281,7 @@ int UsbScanEx::read_int(void* data, int len)
return dw_ret; return dw_ret;
case ERROR_FILE_NOT_FOUND: case ERROR_FILE_NOT_FOUND:
case ERROR_ACCESS_DENIED:
m_b_is_connected = false; m_b_is_connected = false;
if (hotplug_call) { if (hotplug_call) {
hotplug_call(true, usrdata); hotplug_call(true, usrdata);