2022-05-05 09:30:13 +00:00
|
|
|
|
#include "image_process.h"
|
2022-05-30 03:04:26 +00:00
|
|
|
|
#include "../wrapper/hg_log.h"
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
#include <string.h>
|
2022-07-18 08:56:03 +00:00
|
|
|
|
#if !defined(WIN32) && !defined(_WIN64)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
#include <unistd.h>
|
2022-07-14 06:21:53 +00:00
|
|
|
|
#pragma pack(push)
|
|
|
|
|
#pragma pack(1)
|
2022-06-28 09:16:03 +00:00
|
|
|
|
typedef struct BITMAPFILEHEADER
|
|
|
|
|
{
|
|
|
|
|
u_int16_t bfType;
|
|
|
|
|
u_int32_t bfSize;
|
|
|
|
|
u_int16_t bfReserved1;
|
|
|
|
|
u_int16_t bfReserved2;
|
|
|
|
|
u_int32_t bfOffBits;
|
|
|
|
|
}BITMAPFILEHEADER;
|
|
|
|
|
|
|
|
|
|
typedef struct BITMAPINFOHEADER
|
|
|
|
|
{
|
|
|
|
|
u_int32_t biSize;
|
|
|
|
|
u_int32_t biWidth;
|
|
|
|
|
u_int32_t biHeight;
|
|
|
|
|
u_int16_t biPlanes;
|
|
|
|
|
u_int16_t biBitCount;
|
|
|
|
|
u_int32_t biCompression;
|
|
|
|
|
u_int32_t biSizeImage;
|
|
|
|
|
u_int32_t biXPelsPerMeter;
|
|
|
|
|
u_int32_t biYPelsPerMeter;
|
|
|
|
|
u_int32_t biClrUsed;
|
|
|
|
|
u_int32_t biClrImportant;
|
|
|
|
|
}BITMAPINFODEADER;
|
2022-07-14 06:21:53 +00:00
|
|
|
|
#pragma pack(pop)
|
|
|
|
|
#define BI_RGB 0
|
|
|
|
|
#define MAKEWORD(a, b) (((a) & 0x0ff) | (((b) & 0x0ff) << 8))
|
|
|
|
|
#define MAKELONG(a, b) (((a) & 0x0ffff) | (((b) & 0x0ffff) << 16))
|
|
|
|
|
#define _countof(a) (sizeof(a) / sizeof((a)[0]))
|
2022-05-03 03:56:07 +00:00
|
|
|
|
#else
|
|
|
|
|
#include <Windows.h>
|
|
|
|
|
#include <shlobj.h>
|
|
|
|
|
#pragma comment(lib, "Shell32.lib")
|
2022-05-16 05:44:58 +00:00
|
|
|
|
#pragma comment(lib, "hanwangOCRdetect.lib")
|
2022-05-03 03:56:07 +00:00
|
|
|
|
#endif
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include "ImageMatQueue.h"
|
|
|
|
|
#include "../ImageProcess/ImageApplyHeaders.h"
|
|
|
|
|
#include "ImageMultiOutput.h"
|
|
|
|
|
#include "PaperSize.h"
|
|
|
|
|
|
2022-07-18 08:56:03 +00:00
|
|
|
|
#if defined(WIN32) || defined(_WIN64)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
#include "scanner_manager.h"
|
2022-05-17 07:04:55 +00:00
|
|
|
|
#include "ocr/hanwangOCRdetect.h"
|
2022-05-13 08:39:21 +00:00
|
|
|
|
#else
|
|
|
|
|
#include <dlfcn.h>
|
2022-05-17 07:04:55 +00:00
|
|
|
|
extern "C"
|
|
|
|
|
{
|
|
|
|
|
#include "ocr/hanwangOCRdetect.h"
|
|
|
|
|
}
|
2022-05-03 03:56:07 +00:00
|
|
|
|
#endif
|
2022-06-01 03:04:10 +00:00
|
|
|
|
#include "hg_ipc.h"
|
2022-06-28 09:16:03 +00:00
|
|
|
|
#include "../ImageProcess/G4Tiff.h"
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
#define GET_BYTE(a) ((a) & 0x0ff)
|
|
|
|
|
#define MAKE_INT(a, b, c, d) (GET_BYTE(a) | (GET_BYTE(b) << 8) | (GET_BYTE(c) << 16) | (GET_BYTE(d) << 24))
|
|
|
|
|
#define IMAGE_DATA_BUF_CVMAT (void*)MAKE_INT('M', 'T', 'R', 'X')
|
|
|
|
|
#define IMAGE_DATA_BUF_CHAR (void*)MAKE_INT('C', 'H', 'A', 'R')
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// functional ...
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
2022-05-19 06:35:38 +00:00
|
|
|
|
// NEW£¬flow ...
|
2022-05-03 03:56:07 +00:00
|
|
|
|
static int num=0;
|
|
|
|
|
|
|
|
|
|
namespace hg_imgproc
|
|
|
|
|
{
|
|
|
|
|
class imgproc
|
|
|
|
|
{
|
|
|
|
|
std::string my_path_;
|
|
|
|
|
IMGPRCPARAM param_;
|
|
|
|
|
SCANCONF img_conf_;
|
|
|
|
|
std::shared_ptr<std::string> raw_data_;
|
|
|
|
|
std::shared_ptr<vector<char>> buffer_;
|
|
|
|
|
std::vector<cv::Mat> mats_;
|
2022-05-04 08:57:05 +00:00
|
|
|
|
int pid_;
|
2022-07-23 05:42:34 +00:00
|
|
|
|
Device::PaperSize papersize_;
|
|
|
|
|
SANE_Image_Statu img_statu_;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void swap_rgb(cv::Mat& mat)
|
|
|
|
|
{
|
|
|
|
|
unsigned char* first = (unsigned char*)mat.data,
|
|
|
|
|
* oper = first;
|
|
|
|
|
int line_bytes = mat.rows ? mat.total() * mat.channels() / mat.rows : mat.cols * mat.channels();
|
|
|
|
|
for (int i = 0; i < mat.rows; ++i)
|
|
|
|
|
{
|
|
|
|
|
oper = first;
|
|
|
|
|
for (int j = 0; j < mat.cols; ++j)
|
|
|
|
|
{
|
|
|
|
|
unsigned char ch = oper[0];
|
|
|
|
|
oper[0] = oper[2];
|
|
|
|
|
oper[2] = ch;
|
|
|
|
|
oper += 3;
|
|
|
|
|
}
|
|
|
|
|
first += line_bytes;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// construction
|
|
|
|
|
public:
|
2022-05-04 08:57:05 +00:00
|
|
|
|
imgproc(LPSCANCONF img_param,LPIMGPRCPARAM param,int pid) : img_conf_(*img_param),param_(*param),pid_(pid),papersize_(pid_)
|
2022-07-23 05:42:34 +00:00
|
|
|
|
, img_statu_(SANE_Image_Statu_OK)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
|
|
|
|
my_path_ = hg_log::pe_path();
|
|
|
|
|
}
|
|
|
|
|
~imgproc()
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
// load data
|
|
|
|
|
public:
|
2022-06-01 03:04:10 +00:00
|
|
|
|
int load_raw_data(std::shared_ptr<tiny_buffer> buff)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-06-06 04:03:24 +00:00
|
|
|
|
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
|
|
|
|
|
2022-06-01 03:04:10 +00:00
|
|
|
|
buffer_.reset(new std::vector<char>(buff->size()));
|
|
|
|
|
if (buffer_.get())
|
2022-06-06 04:03:24 +00:00
|
|
|
|
{
|
|
|
|
|
unsigned int total = buff->size(),
|
|
|
|
|
off = 0, size = total;
|
|
|
|
|
unsigned char* mem = buff->data(off, &size);
|
|
|
|
|
while (mem)
|
|
|
|
|
{
|
|
|
|
|
memcpy(buffer_->data(), mem, size);
|
|
|
|
|
off += size;
|
|
|
|
|
if (off >= total)
|
|
|
|
|
{
|
|
|
|
|
ret = SCANNER_ERR_OK;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size = total - off;
|
|
|
|
|
mem = buff->data(off, &size);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-05-03 03:56:07 +00:00
|
|
|
|
mats_.clear();
|
2022-07-23 05:42:34 +00:00
|
|
|
|
img_statu_ = (SANE_Image_Statu)buff->get_image_statu();
|
2022-06-06 04:03:24 +00:00
|
|
|
|
|
|
|
|
|
return ret;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int load_file(const char* path_file)
|
|
|
|
|
{
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
FILE* src = fopen(path_file, "rb");
|
|
|
|
|
if (!src)
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OPEN_FILE_FAILED;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
long len = 0;
|
|
|
|
|
fseek(src, 0, SEEK_END);
|
|
|
|
|
len = ftell(src);
|
|
|
|
|
fseek(src, 0, SEEK_SET);
|
|
|
|
|
if (len > 1 * 1024 * 1024 * 1024)
|
|
|
|
|
{
|
|
|
|
|
fclose(src);
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_INSUFFICIENT_MEMORY;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
raw_data_.reset(new std::string());
|
|
|
|
|
raw_data_->resize(len);
|
|
|
|
|
fread(&(*raw_data_)[0], 1, len, src);
|
|
|
|
|
fclose(src);
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// image-processing
|
|
|
|
|
public:
|
|
|
|
|
int decode(int pid)
|
|
|
|
|
{
|
|
|
|
|
if (!buffer_)
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_NO_DATA;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
size_t origin = buffer_->size();
|
|
|
|
|
std::vector<std::shared_ptr<std::vector<char>>> buffs;
|
|
|
|
|
if(pid == 0x100 || pid == 0x200)
|
|
|
|
|
buffs = G200Decode(buffer_,img_conf_.is_duplex,img_conf_.is_switchfrontback).getImageBuffs();
|
|
|
|
|
else if(pid == 0x139 || pid == 0x239)
|
|
|
|
|
buffs = GRawDecode(buffer_).getImageBuffs();
|
2022-08-04 07:01:27 +00:00
|
|
|
|
else if(pid == 0x300 || pid == 0x400 ||pid == 0x402)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
buffs = G400Decode(buffer_,img_conf_.is_duplex).getImageBuffs();
|
|
|
|
|
|
|
|
|
|
if(buffs.empty())
|
|
|
|
|
return -1;
|
|
|
|
|
|
2022-05-16 09:56:07 +00:00
|
|
|
|
buffer_.reset(new std::vector<char >());
|
|
|
|
|
int i=0;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
for (auto& buf : buffs) {
|
2022-05-16 09:56:07 +00:00
|
|
|
|
i++;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
cv::ImreadModes rmc = param_.channels > 1 ? cv::IMREAD_COLOR : cv::IMREAD_GRAYSCALE;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (buf->at(0) == -119 && buf->at(1) == 0x50 && buf->at(2) == 0x4e && buf->at(3) == 0x47)
|
|
|
|
|
{
|
|
|
|
|
rmc = cv::IMREAD_GRAYSCALE;
|
|
|
|
|
param_.black_white = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
param_.black_white = false;
|
|
|
|
|
|
2022-08-04 07:01:27 +00:00
|
|
|
|
if((pid == 0x100 || pid == 0x200 || pid == 0x300 || pid == 0x400|| pid == 0x402)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
&& (img_conf_.filter != 3
|
|
|
|
|
|| img_conf_.multiOutput == 1
|
|
|
|
|
|| img_conf_.multiOutput == 2
|
|
|
|
|
|| img_conf_.multiOutput == 0))
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
rmc = cv::IMREAD_COLOR;
|
|
|
|
|
}
|
|
|
|
|
cv::Mat mat(cv::imdecode(*buf, rmc));
|
|
|
|
|
//("/home/huagao/Desktop/1.jpg",mat);
|
|
|
|
|
if (mat.empty())
|
|
|
|
|
{
|
2022-05-30 03:04:26 +00:00
|
|
|
|
LOG_INFO(LOG_LEVEL_FATAL, "decode image data error\n");
|
2022-05-03 03:56:07 +00:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if(pid == 0x100 || pid == 0x200 || pid == 0x139 || pid == 0x239)
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(mat);
|
2022-05-16 09:56:07 +00:00
|
|
|
|
//cv::imwrite(std::to_string(i)+"_decode.jpg",mat);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
2022-08-04 07:01:27 +00:00
|
|
|
|
else if(pid == 0x300 || pid == 0x400|| pid == 0x402)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-07-01 02:14:50 +00:00
|
|
|
|
cv::Mat back = mat(cv::Rect(0, 0, mat.cols / 2, mat.rows));
|
|
|
|
|
cv::Mat front = mat(cv::Rect(mat.cols / 2, 0, mat.cols / 2, mat.rows));
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
if(img_conf_.is_duplex)
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(img_conf_.is_switchfrontback ? back :front);
|
|
|
|
|
mats_.push_back(img_conf_.is_switchfrontback ? front :back);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(front);
|
|
|
|
|
}
|
|
|
|
|
back.release();
|
|
|
|
|
front.release();
|
|
|
|
|
}
|
2022-05-05 10:04:20 +00:00
|
|
|
|
//#ifndef mips64
|
|
|
|
|
buffer_.reset(new std::vector<char >());
|
|
|
|
|
//#endif
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
catch (const std::exception& e)
|
|
|
|
|
{
|
2022-05-30 03:04:26 +00:00
|
|
|
|
LOG_INFO(LOG_LEVEL_FATAL, e.what());
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
buffs.clear();
|
2022-05-30 03:04:26 +00:00
|
|
|
|
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Decode %u bytes to %u picture(s)\n", origin, mats_.size());
|
2022-05-03 03:56:07 +00:00
|
|
|
|
if(mats_.size() == 0)
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_NO_DATA;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
public:
|
|
|
|
|
int correct_text(void)
|
|
|
|
|
{
|
|
|
|
|
std::string sample(my_path_ + "/data/img/osd.traineddata");
|
|
|
|
|
CImageApplyRotation rot(CImageApplyRotation::RotationType::AutoTextOrientation, false, param_.dpi, sample.c_str());
|
|
|
|
|
|
|
|
|
|
rot.apply(mats_, img_conf_.is_duplex);
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-07-05 10:01:10 +00:00
|
|
|
|
|
2022-08-02 03:07:22 +00:00
|
|
|
|
int split(int multioutputtype,bool is_msplit,bool is_multiout_red,int colortype,bool is_duplex,int split3399,bool fpga_ver)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
CImageApplySplit split(multioutputtype, is_msplit, is_multiout_red, colortype);;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mats_.clear();
|
|
|
|
|
auto matexs = split.SplitMats(mats,is_duplex);
|
|
|
|
|
std::string filename ;
|
2022-07-06 08:19:14 +00:00
|
|
|
|
int rotation01_ = 1;
|
|
|
|
|
int rotation02_ = 1;
|
|
|
|
|
if((pid_ == 0x139 || pid_ == 0x239 || pid_ == 0x100 || pid_ == 0x200) && (split3399 % 2 ==0) && img_conf_.is_duplex)
|
2022-07-05 10:01:10 +00:00
|
|
|
|
{
|
|
|
|
|
rotation01_ = 0;
|
|
|
|
|
rotation02_ = 1;
|
|
|
|
|
}
|
2022-08-04 07:01:27 +00:00
|
|
|
|
int i = 0;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
for(auto &matex : matexs)
|
|
|
|
|
{
|
2022-08-04 07:01:27 +00:00
|
|
|
|
cv::flip(matex.mat,matex.mat,rotation01_);
|
|
|
|
|
cv::flip(matex.mat,matex.mat,rotation02_);
|
|
|
|
|
if(i > 1 && pid_ == 0x402) //G402 设备
|
|
|
|
|
{
|
|
|
|
|
cv::flip(matex.mat,matex.mat,-1);
|
|
|
|
|
}
|
2022-05-03 03:56:07 +00:00
|
|
|
|
if(!matex.mat.empty())
|
|
|
|
|
mats_.push_back(matex.mat);
|
2022-08-04 07:01:27 +00:00
|
|
|
|
i++;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
2022-08-04 07:01:27 +00:00
|
|
|
|
if(fpga_ver || pid_ == 0x402)
|
2022-08-02 03:07:22 +00:00
|
|
|
|
{
|
|
|
|
|
CImageApplyRotation Rotation(CImageApplyRotation::RotationType::Rotate_90_clockwise,img_conf_.is_backrotate180,img_conf_.resolution_native,"./tessdata");
|
|
|
|
|
Rotation.apply(mats_,img_conf_.is_duplex);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int fadeback(int range,bool is_duplex)
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyFadeBackGroudColor fade(100,0,range);
|
|
|
|
|
for(size_t i = 0; i < mats.size();i++)
|
|
|
|
|
{
|
|
|
|
|
fade.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
|
|
|
|
|
// std::string filename = "/home/huagao/Desktop/fadeback("+std::to_string(num++)+").jpg";
|
|
|
|
|
// cv::imwrite(filename,mats_[i]);
|
|
|
|
|
|
|
|
|
|
// printf("fadeback.size :%d ,filename is =%s\r\n",mats_.size(),filename.c_str());
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int multi_out(void)
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
|
|
|
|
|
mats_.clear();
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (mats[i].empty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
vector<cv::Mat> retmats;
|
|
|
|
|
std::vector<std::shared_ptr<IMulti>> m_multiprc_list;
|
|
|
|
|
int multiout = 1,
|
|
|
|
|
colormode = 1;
|
|
|
|
|
|
|
|
|
|
//if (m_param.imageProcess.filter == ColorFilter::FILTER_NONE)
|
|
|
|
|
//{
|
|
|
|
|
// colormode = m_param.pixelType;
|
|
|
|
|
//}
|
|
|
|
|
if (param_.channels > 1)
|
|
|
|
|
m_multiprc_list.push_back(shared_ptr<IMulti>(new ImageMultiOutputRed(2)));
|
|
|
|
|
m_multiprc_list.push_back(shared_ptr<IMulti>(new IMageMulti(multiout)));
|
|
|
|
|
for (int j = 0; j < m_multiprc_list.size(); j++)
|
|
|
|
|
{
|
|
|
|
|
retmats = m_multiprc_list[j]->apply(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CImageApplySplit isp(multiout, false, 1, colormode);
|
|
|
|
|
if (!retmats.size())
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> matse;
|
|
|
|
|
matse.push_back(mats[i]);
|
|
|
|
|
auto matexs = isp.SplitMats(matse, img_conf_.is_duplex);
|
|
|
|
|
for (auto& matex : matexs)
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(matex.mat);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
auto matexs = isp.SplitMats(retmats, img_conf_.is_duplex);
|
|
|
|
|
for (auto& matex : matexs)
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(matex.mat);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int multi_out(int out_type)
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
2022-05-16 09:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mat;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
IMageMulti output(out_type);
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0;i < mats.size();i++)
|
|
|
|
|
{
|
2022-05-16 09:56:07 +00:00
|
|
|
|
mat = output.apply(mats[i]);
|
|
|
|
|
for(size_t j = 0;j < mat.size();j++)
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(mat[j]);
|
|
|
|
|
// std::string filename = "multi_out("+std::to_string(num++)+").jpg";
|
|
|
|
|
// cv::imwrite(filename,mat[j]);
|
|
|
|
|
}
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int multi_out_red()
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
std::vector<cv::Mat> mat;
|
|
|
|
|
mats_.clear();
|
|
|
|
|
mat.clear();
|
|
|
|
|
|
|
|
|
|
ImageMultiOutputRed outred(2);
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0;i < mats.size();i++)
|
|
|
|
|
{
|
|
|
|
|
mat = outred.apply(mats[i]);
|
|
|
|
|
for(size_t j = 0;j < mat.size();j++)
|
|
|
|
|
{
|
|
|
|
|
mats_.push_back(mat[j]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// std::string filename = "/home/huagao/Desktop/multi_out_red("+std::to_string(num++)+").jpg";
|
|
|
|
|
// cv::imwrite(filename,mats_[i]);
|
|
|
|
|
// printf("fadeback.size :%d ,filename is =%s\r\n",mats_.size(),filename.c_str());
|
|
|
|
|
}
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int auto_matic_color(int color_type)
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
for(size_t i = 0;i < mats.size();i++)
|
|
|
|
|
{
|
|
|
|
|
CImageApplyColorRecognition ColorRecognition(color_type==1?
|
|
|
|
|
CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray :
|
|
|
|
|
CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono);
|
|
|
|
|
|
|
|
|
|
ColorRecognition.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
/*pixtype 0 colcor; 1 gray; 2 bw*/
|
|
|
|
|
int auto_crop()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
SIZE temp_Size = papersize_.GetPaperSize(img_conf_.papertype,200,img_conf_.paperAlign);
|
|
|
|
|
cv::Size cvSize(temp_Size.cx, temp_Size.cy);
|
2022-07-01 02:14:50 +00:00
|
|
|
|
CImageApplyAutoCrop crop(img_conf_.is_autocrop,img_conf_.autodescrew,img_conf_.fillbackground,cvSize,img_conf_.is_convex,img_conf_.isfillcolor);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
crop.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
mats_ = mats;
|
|
|
|
|
//cv::imwrite("/home/huagao/Desktop/mats_.jpg",mats_[0]);
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-09-11 15:56:27 +00:00
|
|
|
|
int fillhole(float top,float low,float l,float r)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
float scale = img_conf_.fillhole.fillholeratio / 100.0;
|
2022-08-02 08:46:30 +00:00
|
|
|
|
float val = img_conf_.resolution_dst / 10;
|
2022-09-11 15:56:27 +00:00
|
|
|
|
cv::Vec4f edgeScale;
|
|
|
|
|
edgeScale[0] = top;
|
|
|
|
|
edgeScale[1] = low;
|
|
|
|
|
edgeScale[2] = l;
|
|
|
|
|
edgeScale[3] = r;
|
|
|
|
|
CImageApplyOutHole outh(val, edgeScale,50);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
outh.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
mats_ = mats;
|
|
|
|
|
|
2022-08-02 08:46:30 +00:00
|
|
|
|
return ret;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int resolution_change()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyResize::ResizeType resizeType;
|
|
|
|
|
double ratio = 1.0;
|
|
|
|
|
SIZE reSize = papersize_.GetPaperSize(img_conf_.papertype, img_conf_.resolution_dst,img_conf_.paperAlign);
|
|
|
|
|
cv::Size cvSize(reSize.cx, reSize.cy);
|
|
|
|
|
if (img_conf_.is_autocrop || img_conf_.cropRect.enable)
|
|
|
|
|
{
|
|
|
|
|
resizeType = CImageApplyResize::ResizeType::RATIO;
|
|
|
|
|
ratio = img_conf_.resolution_dst / (float)img_conf_.resolution_native;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
resizeType = CImageApplyResize::ResizeType::DSIZE;
|
|
|
|
|
|
|
|
|
|
CImageApplyResize resize(resizeType,cvSize,ratio,ratio);
|
|
|
|
|
resize.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
if(!mats.empty())
|
|
|
|
|
mats_ = mats;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
int croprect()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyCustomCrop rect(cv::Rect(img_conf_.cropRect.x, img_conf_.cropRect.y, img_conf_.cropRect.width, img_conf_.cropRect.height));
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
rect.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
int channel()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyChannel chl((CImageApplyChannel::channel)(img_conf_.filter));
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < mats.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
chl.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-07-15 08:04:09 +00:00
|
|
|
|
int adjust_color(unsigned char* gamma_table = nullptr, int tableLength = 0)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
2022-07-15 09:04:27 +00:00
|
|
|
|
//VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "adjust_color: table len = %d, brightness = %f, contrast = %f, gamma = %f\n", tableLength
|
|
|
|
|
// , img_conf_.brightness, img_conf_.contrast, img_conf_.gamma);
|
2022-07-15 08:04:09 +00:00
|
|
|
|
if(gamma_table && tableLength)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-07-15 08:04:09 +00:00
|
|
|
|
CImageApplyCustomGamma gamme(gamma_table, tableLength);
|
|
|
|
|
|
|
|
|
|
gamme.apply(mats, img_conf_.is_duplex);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (img_conf_.brightness != 128 ||img_conf_.contrast != 4 || ((img_conf_.gamma < (1.0f - 1e-2)) || (img_conf_.gamma > (1.0f + 1e-2))) )
|
|
|
|
|
{
|
|
|
|
|
int temp_contrast = (img_conf_.contrast - 4) * 12;
|
|
|
|
|
CImageApplyAdjustColors justColors(img_conf_.brightness - 128, temp_contrast, img_conf_.gamma);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
justColors.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//cv::imwrite("/home/huagao/Desktop/customgamma2.jpg",mats_[0]);
|
|
|
|
|
}
|
2022-05-07 09:12:32 +00:00
|
|
|
|
mats_ = mats;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-05-07 09:12:32 +00:00
|
|
|
|
//防止渗<E6ADA2>?
|
2022-05-03 03:56:07 +00:00
|
|
|
|
int antiInflow(int permeate_lv)
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyRefuseInflow Inflow(permeate_lv);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Inflow.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//色彩校正
|
|
|
|
|
int colorCorrection()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyAutoContrast con;
|
|
|
|
|
con.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
mats_= mats;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//图像旋转
|
|
|
|
|
int orentation()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
2022-05-11 03:27:11 +00:00
|
|
|
|
mats_.resize(mats.size());
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
CImageApplyRotation::RotationType rotatetype = CImageApplyRotation::RotationType::Invalid;
|
2022-05-11 03:27:11 +00:00
|
|
|
|
|
|
|
|
|
switch ((CImageApplyRotation::RotationType)img_conf_.imageRotateDegree)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
|
|
|
|
case CImageApplyRotation::RotationType::Rotate_90_clockwise:
|
|
|
|
|
rotatetype = CImageApplyRotation::RotationType::Rotate_90_clockwise;
|
|
|
|
|
break;
|
|
|
|
|
case CImageApplyRotation::RotationType::Rotate_180:
|
|
|
|
|
rotatetype = CImageApplyRotation::RotationType::Rotate_180;
|
|
|
|
|
break;
|
|
|
|
|
case CImageApplyRotation::RotationType::Rotate_90_anti_clockwise:
|
|
|
|
|
rotatetype = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-11 03:27:11 +00:00
|
|
|
|
if (img_conf_.is_autotext)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
rotatetype = CImageApplyRotation::RotationType::AutoTextOrientation;
|
2022-08-12 02:49:21 +00:00
|
|
|
|
/*#if defined(WIN32) || defined(_WIN64)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
char szIniFile[MAX_PATH] = {0};
|
|
|
|
|
SHGetSpecialFolderPathA(NULL, szIniFile, CSIDL_WINDOWS, TRUE);
|
|
|
|
|
strcat(szIniFile, "\\twain_32\\HuaGoScan\\tessdata");
|
|
|
|
|
// m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyRotation(rotatetype, imgparams.BackRotate180, imgparams.DestResulution, szIniFile)));
|
2022-08-12 02:49:21 +00:00
|
|
|
|
#else // WIN32*/
|
2022-05-03 03:56:07 +00:00
|
|
|
|
CImageApplyRotation Rotation(rotatetype,img_conf_.is_backrotate180,img_conf_.resolution_native,"./tessdata");
|
|
|
|
|
|
|
|
|
|
Rotation.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
mats_ = mats;
|
|
|
|
|
|
2022-08-12 02:49:21 +00:00
|
|
|
|
//#endif
|
2022-05-03 03:56:07 +00:00
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-07-28 02:34:48 +00:00
|
|
|
|
//除网<E999A4>?
|
2022-05-03 03:56:07 +00:00
|
|
|
|
int textureRemove()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyTextureRemoval Removal;
|
|
|
|
|
|
|
|
|
|
Removal.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
mats_ = mats;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//锐化
|
|
|
|
|
int sharpenType()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyFilter::FilterMode sharpenType = (CImageApplyFilter::FilterMode)img_conf_.sharpen;
|
|
|
|
|
CImageApplyFilter Filte(sharpenType);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Filte.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//黑白降噪
|
|
|
|
|
int nosieDetach()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyDetachNoise Noise(img_conf_.detachnoise.detachnoise);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Noise.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//错误扩散
|
|
|
|
|
int errorextention()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyBWBinaray::ThresholdType thrtype;
|
|
|
|
|
if(img_conf_.errorExtention)
|
|
|
|
|
thrtype = CImageApplyBWBinaray::ThresholdType::ERROR_DIFFUSION;
|
|
|
|
|
else
|
|
|
|
|
thrtype = CImageApplyBWBinaray::ThresholdType::THRESH_BINARY;
|
|
|
|
|
|
|
|
|
|
CImageApplyBWBinaray BWBinaray(thrtype);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
BWBinaray.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int discardBlank()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
2022-07-06 08:19:14 +00:00
|
|
|
|
double threshold = 40;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
int edge = 150;
|
|
|
|
|
|
|
|
|
|
CImageApplyDiscardBlank(threshold,edge,img_conf_.discardblank_percent);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
bool b = CImageApplyDiscardBlank::apply(mats[i]);
|
|
|
|
|
|
|
|
|
|
if (b)
|
|
|
|
|
mats[i].release();
|
|
|
|
|
else
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-07-28 02:34:48 +00:00
|
|
|
|
//答题卡出<E58DA1>?
|
2022-05-03 03:56:07 +00:00
|
|
|
|
int answerSheetFilterRed()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyHSVCorrect correct((CImageApplyHSVCorrect::Red_Removal));
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
correct.apply(mats[i],img_conf_.is_duplex);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
//对折
|
|
|
|
|
int fold()
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
CImageApplyConcatenation fold(CImageApplyConcatenation::horizontal);
|
|
|
|
|
fold.apply(mats,img_conf_.is_duplex);
|
|
|
|
|
mats_= mats;
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2022-05-09 11:27:10 +00:00
|
|
|
|
|
|
|
|
|
//画质
|
|
|
|
|
int quality(int dpi_dst)
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-09 11:27:10 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
//mats_.resize(mats.size());
|
|
|
|
|
float xy = (float)dpi_dst/200.0;
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat out;
|
|
|
|
|
cv::resize(mats[i],out, cv::Size(),xy,xy);
|
|
|
|
|
mats_.push_back(out);
|
|
|
|
|
}
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-09 11:27:10 +00:00
|
|
|
|
}
|
2022-08-17 08:35:58 +00:00
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
|
|
#endif
|
2022-07-28 08:29:18 +00:00
|
|
|
|
#define test
|
2022-05-11 03:27:11 +00:00
|
|
|
|
int ocr_auto_txtdirect()
|
|
|
|
|
{
|
2022-08-17 08:35:58 +00:00
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
|
|
|
|
|
int pDirect = -1,
|
|
|
|
|
ret = SCANNER_ERR_OK;
|
|
|
|
|
void* pHanld = NULL;
|
|
|
|
|
|
|
|
|
|
typedef int (* SDKInitialize)(void** ppstOcrHandle);
|
|
|
|
|
typedef void(* SDKExit)(void* pstOcrHandle);
|
2022-08-17 08:38:27 +00:00
|
|
|
|
typedef int (* SDKGetFileDirectImage)(BYTE* pbImage, int nWidth, int nHeight, TColorType nColorType, void* pstHandle, int* pDirect);
|
2022-08-17 08:35:58 +00:00
|
|
|
|
|
|
|
|
|
SDKInitialize ocrinit = NULL;
|
|
|
|
|
SDKGetFileDirectImage ocrgetdirectimage = NULL;
|
|
|
|
|
SDKExit ocrexit = NULL;
|
|
|
|
|
|
|
|
|
|
#ifndef WIN32
|
2022-07-29 03:39:47 +00:00
|
|
|
|
#ifdef OEM_HANWANG
|
|
|
|
|
string libname = "libhwdriver.so";
|
2022-08-01 03:29:36 +00:00
|
|
|
|
#elif defined(OEM_LISICHENG)
|
2022-07-29 03:39:47 +00:00
|
|
|
|
string libname = "liblscdriver.so";
|
|
|
|
|
#else
|
|
|
|
|
string libname = "libhgdriver.so";
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
string scanner_path = hg_log::get_module_full_path(libname.c_str());
|
|
|
|
|
|
2022-07-29 02:11:38 +00:00
|
|
|
|
if(scanner_path.empty())
|
|
|
|
|
{
|
|
|
|
|
return SCANNER_ERR_OUT_OF_RANGE;
|
|
|
|
|
}
|
2022-07-29 03:39:47 +00:00
|
|
|
|
scanner_path = scanner_path.substr(0,scanner_path.size() - libname.size());
|
|
|
|
|
scanner_path+="libhwocrdetect.so";
|
|
|
|
|
printf("hwlib path:%s\r\n",scanner_path.c_str());
|
2022-08-17 08:35:58 +00:00
|
|
|
|
|
2022-07-29 03:39:47 +00:00
|
|
|
|
if(access(scanner_path.c_str(),F_OK) != 0)
|
|
|
|
|
{
|
|
|
|
|
return SCANNER_ERR_OUT_OF_RANGE;
|
|
|
|
|
}
|
2022-07-29 03:42:29 +00:00
|
|
|
|
#endif
|
2022-07-28 08:29:18 +00:00
|
|
|
|
#if ((!defined x86_64) && (!defined WIN32))
|
|
|
|
|
//linux x86_64 暂时没有OCR三方
|
2022-08-17 08:35:58 +00:00
|
|
|
|
|
2022-07-29 02:11:38 +00:00
|
|
|
|
void *hanlde = dlopen(scanner_path.c_str(),RTLD_LAZY);
|
2022-07-28 09:04:38 +00:00
|
|
|
|
if(!hanlde)
|
2022-07-28 02:34:48 +00:00
|
|
|
|
{
|
2022-07-29 02:11:38 +00:00
|
|
|
|
return SCANNER_ERR_OUT_OF_RANGE;
|
2022-07-28 02:34:48 +00:00
|
|
|
|
}
|
2022-08-17 08:35:58 +00:00
|
|
|
|
ocrinit = (SDKInitialize)dlsym(hanlde , "HWOCR_SDKInitialize");
|
|
|
|
|
ocrgetdirectimage = (SDKGetFileDirectImage)dlsym(hanlde , "HWOCR_GetFileDirectImage");
|
|
|
|
|
ocrexit= (SDKExit)dlsym(hanlde , "HWOCR_SDKExit");
|
2022-07-28 09:04:38 +00:00
|
|
|
|
|
2022-08-17 08:35:58 +00:00
|
|
|
|
#else
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
HINSTANCE handle = LoadLibrary(L"hanwangOCRdetect.dll");
|
|
|
|
|
if (handle)
|
2022-07-28 02:52:09 +00:00
|
|
|
|
{
|
2022-08-17 08:35:58 +00:00
|
|
|
|
ocrinit = (SDKInitialize)GetProcAddress(handle, "HWOCR_SDKInitialize");
|
|
|
|
|
ocrgetdirectimage = (SDKGetFileDirectImage)GetProcAddress(handle, "HWOCR_GetFileDirectImage");
|
|
|
|
|
ocrexit = (SDKExit)GetProcAddress(handle, "HWOCR_SDKExit");
|
|
|
|
|
}
|
|
|
|
|
#endif // WIN32 //暂时保留文本方向旋转
|
|
|
|
|
#endif
|
|
|
|
|
int r = ocrinit(&pHanld);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); i++)
|
|
|
|
|
{
|
|
|
|
|
r = ocrgetdirectimage(const_cast<uchar*>(mats[i].data), mats[i].cols, mats[i].rows, mats[i].channels() == 1 ? TColorType::EGray256 : TColorType::EColor16M, pHanld, &pDirect);
|
2022-07-28 09:04:38 +00:00
|
|
|
|
|
2022-08-17 08:35:58 +00:00
|
|
|
|
if (pDirect == 1)
|
|
|
|
|
pDirect = 3;
|
|
|
|
|
else if (pDirect == 3)
|
|
|
|
|
pDirect = 1;
|
2022-07-28 09:04:38 +00:00
|
|
|
|
|
2022-08-17 08:35:58 +00:00
|
|
|
|
CImageApplyRotation(CImageApplyRotation::RotationType(pDirect)).apply(mats[i], false);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
ocrexit(pHanld);
|
|
|
|
|
#if ((!defined x86_64) && (!defined WIN32))
|
|
|
|
|
dlclose(hanlde);
|
2022-08-13 08:28:40 +00:00
|
|
|
|
#else
|
2022-08-17 08:35:58 +00:00
|
|
|
|
|
2022-05-11 03:27:11 +00:00
|
|
|
|
#endif
|
|
|
|
|
return ret;
|
2022-07-28 02:34:48 +00:00
|
|
|
|
}
|
2022-05-19 06:35:38 +00:00
|
|
|
|
int size_detection()
|
|
|
|
|
{
|
|
|
|
|
int ret = SCANNER_ERR_OK;
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
mats_.clear();
|
|
|
|
|
CImageApplySizeDetection paper(img_conf_.papertype);
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
ret = paper.apply(mats[i]);
|
|
|
|
|
mats_.push_back(mats[i]);
|
|
|
|
|
}
|
|
|
|
|
if(ret == 1)
|
|
|
|
|
{
|
|
|
|
|
return SCANNER_ERR_DEVICE_SIZE_CHECK;
|
|
|
|
|
}
|
|
|
|
|
return SCANNER_ERR_OK;
|
|
|
|
|
|
|
|
|
|
}
|
2022-05-11 03:27:11 +00:00
|
|
|
|
// final
|
2022-05-03 03:56:07 +00:00
|
|
|
|
public:
|
|
|
|
|
int final(void)
|
|
|
|
|
{
|
|
|
|
|
std::vector<cv::Mat> mats(mats_);
|
|
|
|
|
|
|
|
|
|
mats_.clear();
|
|
|
|
|
for (size_t i = 0; i < mats.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (mats[i].empty())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
int bpp = param_.black_white ? 8 : param_.bits * param_.channels;
|
|
|
|
|
MatEx out(mats[i], bpp);
|
|
|
|
|
|
|
|
|
|
if (out.mat.channels() == 3)
|
|
|
|
|
swap_rgb(out.mat);
|
|
|
|
|
mats_.push_back(out.mat);
|
2022-05-16 09:56:07 +00:00
|
|
|
|
//cv::imwrite(std::to_string(i++)+"_final.jpg",out.mat);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int get_final_data(LPIMGHEAD pimh, void** buf, int index)
|
|
|
|
|
{
|
|
|
|
|
if ((index < 0 || index >= mats_.size()))
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_NO_DATA;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
pimh->width = mats_[index].cols;
|
|
|
|
|
pimh->height = mats_[index].rows;
|
|
|
|
|
pimh->bits = 8; //mats_[index].depth
|
|
|
|
|
pimh->channels = mats_[index].channels();
|
|
|
|
|
|
|
|
|
|
pimh->total_bytes = mats_[index].total() * pimh->channels;
|
|
|
|
|
pimh->line_bytes = pimh->height ? pimh->total_bytes / pimh->height : pimh->width * pimh->channels;
|
|
|
|
|
*buf = mats_[index].data;
|
2022-07-23 05:42:34 +00:00
|
|
|
|
pimh->statu = img_statu_;
|
2022-05-09 11:27:10 +00:00
|
|
|
|
|
2022-05-03 03:56:07 +00:00
|
|
|
|
//printf("pimh->channels = %d \r\n",pimh->channels);
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_final_data(LPIMGHEAD pimh, std::vector<unsigned char>* buf, int index)
|
|
|
|
|
{
|
|
|
|
|
if ((index < 0 || index >= mats_.size()))
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_NO_DATA;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
pimh->width = mats_[index].cols;
|
|
|
|
|
pimh->height = mats_[index].rows;
|
|
|
|
|
pimh->bits = 8; //mats_[index].depth
|
|
|
|
|
pimh->channels = mats_[index].channels();
|
2022-07-23 05:42:34 +00:00
|
|
|
|
pimh->statu = img_statu_;
|
|
|
|
|
|
2022-05-03 03:56:07 +00:00
|
|
|
|
if((pimh->width * pimh->channels) % 4)
|
|
|
|
|
{
|
|
|
|
|
int len = pimh->width * pimh->channels;
|
|
|
|
|
pimh->line_bytes = (len + 3) / 4 * 4;
|
|
|
|
|
pimh->total_bytes = pimh->line_bytes * pimh->height;
|
|
|
|
|
buf->resize(pimh->total_bytes);
|
|
|
|
|
|
|
|
|
|
//printf("pimh->total_bytes=%d pimh->line_bytes=%d\r\n",pimh->total_bytes,pimh->line_bytes);
|
|
|
|
|
unsigned char* src = mats_[index].data, *dst = buf->data();
|
|
|
|
|
for(int i = 0; i < pimh->height; ++i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dst, src, len);
|
|
|
|
|
dst += pimh->line_bytes;
|
|
|
|
|
src += len;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
pimh->total_bytes = mats_[index].total() * pimh->channels;
|
|
|
|
|
pimh->line_bytes = pimh->height ? pimh->total_bytes / pimh->height : pimh->width * pimh->channels;
|
|
|
|
|
buf->resize(pimh->total_bytes);
|
|
|
|
|
memcpy(buf->data(), mats_[index].data, pimh->total_bytes);
|
|
|
|
|
//cv::imwrite(to_string(index)+"_final.jpg",mats_[index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//printf("pimh->channels_01 = %d \r\n",pimh->channels);
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int imgtypechange(std::string img_type_,void *buf,std::vector<unsigned char> &bmpdata)
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
int ret = SCANNER_ERR_OK;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
if(!buf)
|
|
|
|
|
{
|
2022-05-17 07:04:55 +00:00
|
|
|
|
return SCANNER_ERR_NO_DATA;
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
cv::imencode(img_type_,*((cv::Mat*)buf),bmpdata);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
// api ...
|
2022-05-04 08:57:05 +00:00
|
|
|
|
HIMGPRC init(LPSCANCONF parameter,LPIMGPRCPARAM param,int pid)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-05-04 08:57:05 +00:00
|
|
|
|
imgproc* obj = new imgproc(parameter,param,pid);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
|
|
|
|
|
return (HIMGPRC)obj;
|
|
|
|
|
}
|
2022-06-01 03:04:10 +00:00
|
|
|
|
int load_buffer(HIMGPRC himg, std::shared_ptr<tiny_buffer> buff)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->load_raw_data(buff);
|
|
|
|
|
}
|
|
|
|
|
int load_file(HIMGPRC himg, const char* path_file)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->load_file(path_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int decode(HIMGPRC himg,int pid)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->decode(pid);
|
|
|
|
|
}
|
|
|
|
|
int correct_text(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->correct_text();
|
|
|
|
|
}
|
2022-08-02 03:07:22 +00:00
|
|
|
|
int split(HIMGPRC himg,int multioutputtype,bool is_msplit,bool is_multiout_red,int colortype,bool is_duplex,int split3399,bool fpga_ver)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-08-02 03:07:22 +00:00
|
|
|
|
return ((imgproc*)himg)->split( multioutputtype, is_msplit, is_multiout_red, colortype,is_duplex,split3399,fpga_ver);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int fadeback(HIMGPRC himg,int range,bool is_duplex)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->fadeback(range,is_duplex);
|
|
|
|
|
}
|
|
|
|
|
int multi_out(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->multi_out();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int multi_out(HIMGPRC himg,int out_type)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->multi_out(out_type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int multi_out_red(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->multi_out_red();
|
|
|
|
|
}
|
|
|
|
|
int auto_matic_color(HIMGPRC himg,int color_type)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->auto_matic_color(color_type);
|
|
|
|
|
}
|
|
|
|
|
int auto_crop(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->auto_crop();
|
|
|
|
|
}
|
2022-09-11 15:56:27 +00:00
|
|
|
|
int fillhole(HIMGPRC himg, float top, float low, float l, float r)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-09-11 15:56:27 +00:00
|
|
|
|
return ((imgproc*)himg)->fillhole(top, low, l,r);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int resolution_change(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->resolution_change();
|
|
|
|
|
}
|
|
|
|
|
int croprect(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->croprect();
|
|
|
|
|
}
|
|
|
|
|
int channel(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->channel();
|
|
|
|
|
}
|
2022-07-15 08:04:09 +00:00
|
|
|
|
int adjust_color(HIMGPRC himg, unsigned char* table, int tableLength)
|
2022-05-03 03:56:07 +00:00
|
|
|
|
{
|
2022-07-15 08:04:09 +00:00
|
|
|
|
return ((imgproc*)himg)->adjust_color(table, tableLength);
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
int antiInflow(HIMGPRC himg,int permeate_lv)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->antiInflow(permeate_lv);
|
|
|
|
|
}
|
|
|
|
|
int colorCorrection(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->colorCorrection();
|
|
|
|
|
}
|
|
|
|
|
int orentation(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->orentation();
|
|
|
|
|
}
|
|
|
|
|
int textureRemove(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->textureRemove();
|
|
|
|
|
}
|
|
|
|
|
int sharpenType(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->sharpenType();
|
|
|
|
|
}
|
|
|
|
|
int nosieDetach(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->nosieDetach();
|
|
|
|
|
}
|
|
|
|
|
int errorextention(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->errorextention();
|
|
|
|
|
}
|
|
|
|
|
int discardBlank(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->discardBlank();
|
|
|
|
|
}
|
|
|
|
|
int answerSheetFilterRed(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->answerSheetFilterRed();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//img_type_ = jpg png bmp
|
|
|
|
|
int imgtypechange(HIMGPRC himg,std::string img_type_,void *buf,std::vector<unsigned char> &bmpdata)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->imgtypechange(img_type_,buf,bmpdata);
|
|
|
|
|
}
|
|
|
|
|
int fold(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->fold();
|
|
|
|
|
}
|
2022-05-09 11:27:10 +00:00
|
|
|
|
int quality(HIMGPRC himg,int dpi)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->quality(dpi);
|
|
|
|
|
}
|
2022-05-11 03:27:11 +00:00
|
|
|
|
int ocr_auto_txtdirect(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->ocr_auto_txtdirect();
|
|
|
|
|
}
|
2022-05-19 06:35:38 +00:00
|
|
|
|
|
|
|
|
|
int size_detection(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->size_detection();
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-03 03:56:07 +00:00
|
|
|
|
int final(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->final();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_final_data(HIMGPRC himg, LPIMGHEAD pimh, void** buf, int index)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->get_final_data(pimh, buf, index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_final_data(HIMGPRC himg, LPIMGHEAD pimh, std::vector<unsigned char>* buf, int index)
|
|
|
|
|
{
|
|
|
|
|
return ((imgproc*)himg)->get_final_data(pimh, buf, index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void release(HIMGPRC himg)
|
|
|
|
|
{
|
|
|
|
|
imgproc* obj = (imgproc*)himg;
|
|
|
|
|
|
|
|
|
|
delete obj;
|
|
|
|
|
}
|
2022-06-28 09:16:03 +00:00
|
|
|
|
|
|
|
|
|
// seperate utilites ...
|
|
|
|
|
#include <opencv2/imgcodecs.hpp>
|
|
|
|
|
#define CV_MAT_DEPTH_SET(flags, depth) (((flags) & ~(CV_MAT_DEPTH_MASK)) | (depth & CV_MAT_DEPTH_MASK))
|
|
|
|
|
static cv::Mat from_bmp_file_bits(const BITMAPINFOHEADER& bih, unsigned char* data, bool tiff)
|
|
|
|
|
{
|
|
|
|
|
cv::Mat m;
|
|
|
|
|
int bytes = 0, align = 0;
|
|
|
|
|
unsigned char *dst = NULL;
|
|
|
|
|
|
|
|
|
|
m.create(bih.biHeight, bih.biWidth, bih.biBitCount > 8 ? CV_8UC3 : CV_8UC1);
|
|
|
|
|
dst = m.ptr();
|
|
|
|
|
bytes = (bih.biBitCount + 7) / 8;
|
|
|
|
|
bytes *= bih.biWidth;
|
|
|
|
|
align = (bytes + 3) / 4 * 4;
|
|
|
|
|
if (tiff)
|
|
|
|
|
{
|
|
|
|
|
data += align * (bih.biHeight - 1);
|
|
|
|
|
align *= -1;
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < bih.biHeight; ++i)
|
|
|
|
|
{
|
|
|
|
|
memcpy(dst, data, bytes);
|
|
|
|
|
dst += bytes;
|
|
|
|
|
data += align;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m;
|
|
|
|
|
}
|
|
|
|
|
int convert_image_file(SANE_ImageFormatConvert* conv)
|
|
|
|
|
{
|
|
|
|
|
if (conv->src.fmt.img_format != SANE_IMAGE_TYPE_BMP &&
|
|
|
|
|
conv->src.fmt.compress.compression != SANE_COMPRESSION_NONE)
|
|
|
|
|
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
|
|
|
|
if(conv->dst.fmt.img_format != SANE_IMAGE_TYPE_JFIF &&
|
|
|
|
|
conv->dst.fmt.img_format != SANE_IMAGE_TYPE_TIFF &&
|
|
|
|
|
conv->dst.fmt.compress.compression != SANE_COMPRESSION_NONE &&
|
|
|
|
|
conv->dst.fmt.compress.compression != SANE_COMPRESSION_GROUP4)
|
|
|
|
|
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
|
|
|
|
|
|
|
|
|
int fh = sizeof(BITMAPFILEHEADER);
|
|
|
|
|
BITMAPINFOHEADER bih = { 0 };
|
|
|
|
|
unsigned char *bits = NULL;
|
|
|
|
|
std::shared_ptr<std::vector<unsigned char>> data;
|
|
|
|
|
|
|
|
|
|
if (conv->src.is_file)
|
|
|
|
|
{
|
|
|
|
|
FILE* src = fopen(conv->src.data, "rb");
|
|
|
|
|
long len = 0;
|
|
|
|
|
if (!src)
|
|
|
|
|
return SCANNER_ERR_OPEN_FILE_FAILED;
|
|
|
|
|
|
|
|
|
|
fseek(src, 0, SEEK_END);
|
|
|
|
|
len = ftell(src) - fh;
|
|
|
|
|
if (len <= 0)
|
|
|
|
|
{
|
|
|
|
|
fclose(src);
|
|
|
|
|
|
|
|
|
|
return SCANNER_ERR_DATA_DAMAGED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fseek(src, fh, SEEK_SET);
|
|
|
|
|
fread(&bih, sizeof(bih), 1, src);
|
|
|
|
|
len -= sizeof(bih);
|
|
|
|
|
data.reset(new std::vector<unsigned char>(len));
|
|
|
|
|
fread(&(*data.get())[0], 1, len, src);
|
|
|
|
|
fclose(src);
|
|
|
|
|
bits = data.get()->data();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
memcpy(&bih, conv->src.data + fh, sizeof(bih));
|
|
|
|
|
bits = (unsigned char*)conv->src.data + fh + sizeof(bih);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool tiff = conv->dst.fmt.img_format == SANE_IMAGE_TYPE_TIFF;
|
|
|
|
|
int resolution = bih.biXPelsPerMeter / 39.37f + .5f,
|
|
|
|
|
threshold = (int)(long)conv->dst.fmt.compress.detail;
|
|
|
|
|
cv::Mat imsg = from_bmp_file_bits(bih, data->data(), tiff);
|
|
|
|
|
data.reset();
|
|
|
|
|
if (tiff)
|
|
|
|
|
{
|
|
|
|
|
if (bih.biBitCount == 24)
|
|
|
|
|
{
|
|
|
|
|
if (conv->dst.fmt.compress.compression == SANE_COMPRESSION_GROUP4)
|
|
|
|
|
cvtColor(imsg, imsg, cv::COLOR_RGB2GRAY);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for (int y = 0; y < bih.biHeight; ++y)
|
|
|
|
|
{
|
|
|
|
|
uint8_t* row = imsg.ptr(y);
|
|
|
|
|
for (int x = 0; x < bih.biWidth; ++x)
|
|
|
|
|
{
|
|
|
|
|
uint8_t t = row[x * 3 + 0];
|
|
|
|
|
row[x * 3 + 0] = row[x * 3 + 2];
|
|
|
|
|
row[x * 3 + 2] = t;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int compression = conv->dst.fmt.compress.compression == SANE_COMPRESSION_GROUP4 ? COMPRESSION_CCITT_T6 : COMPRESSION_NONE;
|
|
|
|
|
if (conv->dst.is_file)
|
|
|
|
|
{
|
|
|
|
|
G4Tiff tiff(imsg, G4Tiff::Mode::FileMode, conv->dst.data, threshold, resolution, compression);
|
|
|
|
|
tiff.SaveG4Tiff();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
G4Tiff tiff(imsg, G4Tiff::Mode::MemoryMode, "", threshold, resolution, compression);
|
|
|
|
|
size_t bytes = 0;
|
|
|
|
|
conv->dst.data = (SANE_String_Const)tiff.get_compressed_data(&bytes, allocate_memory);
|
|
|
|
|
conv->dst.data_len = bytes;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (conv->dst.fmt.img_format == SANE_IMAGE_TYPE_JFIF)
|
|
|
|
|
{
|
|
|
|
|
std::vector<int> cpr;
|
|
|
|
|
cpr.push_back(CV_IMWRITE_JPEG_QUALITY);
|
|
|
|
|
cpr.push_back((int)(long)conv->dst.fmt.detail);
|
|
|
|
|
if (conv->dst.is_file)
|
|
|
|
|
cv::imwrite(conv->dst.data, imsg, cpr);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::string tmpf(hg_log::temporary_path() + PATH_SEPARATOR + "imgtrans.tmp");
|
|
|
|
|
cv::imwrite(tmpf.c_str(), imsg, cpr);
|
|
|
|
|
size_t bytes = 0;
|
|
|
|
|
conv->dst.data = (SANE_String_Const)G4Tiff::load_mini_file(tmpf.c_str(), &bytes, allocate_memory);
|
|
|
|
|
conv->dst.data_len = bytes;
|
|
|
|
|
remove(tmpf.c_str());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (conv->dst.fmt.compress.compression == SANE_COMPRESSION_GROUP4)
|
|
|
|
|
{
|
|
|
|
|
std::vector<uchar> cmp;
|
|
|
|
|
|
|
|
|
|
if (bih.biBitCount == 24)
|
|
|
|
|
cvtColor(imsg, imsg, cv::COLOR_RGB2GRAY);
|
|
|
|
|
|
|
|
|
|
if (conv->dst.is_file)
|
|
|
|
|
{
|
|
|
|
|
G4Tiff tiff(imsg, G4Tiff::Mode::FileMode, conv->dst.data, threshold, resolution);
|
|
|
|
|
tiff.SaveG4Tiff();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
G4Tiff tiff(imsg, G4Tiff::Mode::MemoryMode, "", threshold, resolution);
|
|
|
|
|
size_t bytes = 0;
|
|
|
|
|
conv->dst.data = (SANE_String_Const)tiff.get_compressed_data(&bytes, allocate_memory);
|
|
|
|
|
conv->dst.data_len = bytes;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return SCANNER_ERR_OK;
|
|
|
|
|
}
|
2022-07-14 06:21:53 +00:00
|
|
|
|
int save_2_bmp_file(const char* bmp_file, LPIMGHEAD head, void* buf, int resolution)
|
|
|
|
|
{
|
|
|
|
|
BITMAPINFOHEADER bih = { 0 };
|
|
|
|
|
BITMAPFILEHEADER fh = { 0 };
|
|
|
|
|
int pal_size = 0, line_len = (head->channels * head->bits * head->width + 31) / 32 * 4;
|
|
|
|
|
FILE *dst = fopen(bmp_file, "wb");
|
|
|
|
|
|
|
|
|
|
if (!dst)
|
|
|
|
|
return errno;
|
|
|
|
|
|
|
|
|
|
bih.biSize = sizeof(bih);
|
|
|
|
|
bih.biWidth = head->width;
|
|
|
|
|
bih.biBitCount = head->channels * head->bits;
|
|
|
|
|
bih.biSizeImage = head->height * line_len;
|
|
|
|
|
bih.biPlanes = 1;
|
|
|
|
|
bih.biHeight = head->height;
|
|
|
|
|
bih.biCompression = BI_RGB;
|
|
|
|
|
bih.biXPelsPerMeter = bih.biYPelsPerMeter = resolution * 39.37f + .5f;
|
|
|
|
|
|
|
|
|
|
if (bih.biBitCount == 1)
|
|
|
|
|
pal_size = 2 * sizeof(int);
|
|
|
|
|
else if (bih.biBitCount == 8)
|
|
|
|
|
pal_size = 256 * sizeof(int);
|
|
|
|
|
|
|
|
|
|
fh.bfType = MAKEWORD('B', 'M');
|
|
|
|
|
fh.bfSize = sizeof(fh) + bih.biSizeImage + sizeof(bih);
|
|
|
|
|
fh.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size;
|
|
|
|
|
|
|
|
|
|
fwrite(&fh, sizeof(fh), 1, dst);
|
|
|
|
|
fwrite(&bih, sizeof(bih), 1, dst);
|
|
|
|
|
if (bih.biBitCount == 1)
|
|
|
|
|
{
|
|
|
|
|
int pal[] = { 0, 0x0ffffff };
|
|
|
|
|
fwrite(pal, sizeof(pal), 1, dst);
|
|
|
|
|
}
|
|
|
|
|
else if (bih.biBitCount == 8)
|
|
|
|
|
{
|
|
|
|
|
static unsigned int g_bmp8_pallete[256] = { 0 };
|
|
|
|
|
if (g_bmp8_pallete[1] == 0)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 1; i < _countof(g_bmp8_pallete); ++i)
|
|
|
|
|
g_bmp8_pallete[i] = MAKELONG(MAKEWORD(i, i), MAKEWORD(i, 0));
|
|
|
|
|
}
|
|
|
|
|
fwrite(g_bmp8_pallete, sizeof(g_bmp8_pallete), 1, dst);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (line_len == head->line_bytes)
|
|
|
|
|
fwrite(buf, 1, head->total_bytes, dst);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
unsigned char* ptr = (unsigned char*)buf;
|
|
|
|
|
unsigned int pad = 0;
|
|
|
|
|
int pad_l = 4 - (head->line_bytes % 4), step = head->line_bytes;
|
2022-06-28 09:16:03 +00:00
|
|
|
|
|
2022-07-14 06:21:53 +00:00
|
|
|
|
if (1)
|
|
|
|
|
{
|
|
|
|
|
ptr += head->total_bytes - head->line_bytes;
|
|
|
|
|
step *= -1;
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < head->height; ++i)
|
|
|
|
|
{
|
|
|
|
|
fwrite(ptr, head->line_bytes, 1, dst);
|
|
|
|
|
fwrite(&pad, 1, pad_l, dst);
|
|
|
|
|
ptr += step;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fclose(dst);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2022-05-03 03:56:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|