code_device/hgdriver/hgdev/image_process.cpp

1943 lines
51 KiB
C++
Raw Normal View History

#include "image_process.h"
#include "../wrapper/hg_log.h"
2022-05-03 03:56:07 +00:00
#include <vector>
#include <string.h>
#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)
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-11-01 09:29:54 +00:00
#include "imgproc/HGOCR.h"
#if defined(WIN32) || defined(_WIN64)
2022-05-03 03:56:07 +00:00
#include "scanner_manager.h"
#include "ocr/hanwangOCRdetect.h"
#else
#include <dlfcn.h>
extern "C"
{
#include "ocr/hanwangOCRdetect.h"
}
2022-05-03 03:56:07 +00:00
#endif
#include "hg_ipc.h"
#include "../ImageProcess/G4Tiff.h"
#include "base/HGImage.h"
#include <opencv2/imgcodecs.hpp>
#define CV_MAT_DEPTH_SET(flags, depth) (((flags) & ~(CV_MAT_DEPTH_MASK)) | (depth & CV_MAT_DEPTH_MASK))
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')
2022-11-02 01:21:36 +00:00
2022-11-02 03:09:06 +00:00
//动态打开库的命名
2022-11-02 01:21:36 +00:00
#ifdef OEM_HANWANG
2022-11-02 03:09:06 +00:00
#ifdef WIN32
2022-11-02 07:17:46 +00:00
#define IMGPRC_LIBNANE L"HwImgProc.dll"
#define HGBASE_LIBNAME L"HwBase.dll"
2022-11-02 03:09:06 +00:00
#else
2022-11-02 07:17:46 +00:00
#define IMGPRC_LIBNANE "libHwImgProc.so"
#define HGBASE_LIBNAME "libHwBase.so"
2022-11-02 03:09:06 +00:00
#endif
2022-11-02 01:21:36 +00:00
#elif defined(OEM_LISICHENG)
2022-11-02 03:09:06 +00:00
#ifdef WIN32
2022-11-02 07:17:46 +00:00
#define IMGPRC_LIBNANE L"LscImgProc.dll"
#define HGBASE_LIBNAME L"LscBase.dll"
2022-11-02 03:09:06 +00:00
#else
2022-11-02 07:17:46 +00:00
#define IMGPRC_LIBNANE "libLscImgProc.so"
#define HGBASE_LIBNAME "libLscBase.so"
2022-11-02 03:09:06 +00:00
#endif
2022-11-02 01:21:36 +00:00
#else
2022-11-02 03:09:06 +00:00
#ifdef WIN32
#define IMGPRC_LIBNANE L"HGImgProc.dll"
2022-11-02 03:17:19 +00:00
#define HGBASE_LIBNAME L"HGBase.dll"
2022-11-02 03:09:06 +00:00
#else
#define IMGPRC_LIBNANE "libHGImgProc.so"
#define HGBASE_LIBNAME "libHGBase.so"
#endif
2022-11-02 01:21:36 +00:00
#endif
2022-05-03 03:56:07 +00:00
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// functional ...
////////////////////////////////////////////////////////////////////////////////
//
static int num=0;
2022-05-03 03:56:07 +00:00
namespace hg_imgproc
{
typedef union
{
unsigned char ch;
struct
{
unsigned char bit0 : 1;
unsigned char bit1 : 1;
unsigned char bit2 : 1;
unsigned char bit3 : 1;
unsigned char bit4 : 1;
unsigned char bit5 : 1;
unsigned char bit6 : 1;
unsigned char bit7 : 1;
}bits;
}BITS;
class bit_stream
{
unsigned char* byte_stream_;
bool lsb_first_; // whether the Lowest_bit is first pop ...
int offset_;
public:
bit_stream(unsigned char* data, bool lsb_first = true) : byte_stream_(data), lsb_first_(lsb_first)
, offset_(0)
{}
~bit_stream()
{}
public:
void reset(int off = 0)
{
offset_ = off;
}
unsigned char get(void)
{
unsigned char ret = 0;
if (lsb_first_)
ret = (byte_stream_[offset_ / 8] >> (offset_ % 8)) & 1;
else
ret = (byte_stream_[offset_ / 8] >> (7 - (offset_ % 8))) & 1;
offset_++;
return ret;
}
};
2022-11-02 03:09:06 +00:00
typedef unsigned int (*SDKHGImgProc_InitOCR_)(unsigned int ocrtype, void** pstOcrHandle);
typedef unsigned int (*SDKHGImgProc_FreeImage_)(void* pstOcrHandle);
typedef unsigned int (*SDKHGImgProc_GetTextDir_)(void* pstOcrHandle, void* image, unsigned int* pDirect);
typedef unsigned int (*SDKHGBase_CreateImage_)(void* data, void* imageinfo, void* image);
typedef unsigned int (*SDKHGBase_FreeImage_)(void* image);
2022-05-03 03:56:07 +00:00
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_;
Device::PaperSize papersize_;
SANE_Image_Statu img_statu_;
2022-05-03 03:56:07 +00:00
2022-11-02 03:09:06 +00:00
SDKHGImgProc_InitOCR_ ocrinit_ = NULL;
SDKHGImgProc_GetTextDir_ ocrgetdirectimage_ = NULL;
SDKHGImgProc_FreeImage_ ocrexit_ = NULL;
SDKHGBase_CreateImage_ HGBase_CreatImg = NULL;
SDKHGBase_FreeImage_ HGBase_FreeImg = NULL;
void* Auto_Txt_pHanld = NULL;
#ifndef WIN32
2022-11-02 03:09:06 +00:00
void *Dynamicopen_HGBase_pHandle_;
void *Dynamicopen_HGImageprc_pHandle_;
#else
2022-11-02 03:09:06 +00:00
HINSTANCE Dynamicopen_HGBase_pHandle_;
HINSTANCE Dynamicopen_HGImageprc_pHandle_;
#endif
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:
imgproc(int pid) : pid_(pid),papersize_(pid_)
, img_statu_(SANE_Image_Statu_OK)
2022-05-03 03:56:07 +00:00
{
my_path_ = hg_log::pe_path();
}
~imgproc()
2022-11-02 03:09:06 +00:00
{
free_auto_txt_hanld();
}
2022-05-03 03:56:07 +00:00
// load data
public:
int load_raw_data(std::shared_ptr<tiny_buffer> buff)
2022-05-03 03:56:07 +00:00
{
int ret = SCANNER_ERR_INSUFFICIENT_MEMORY;
buffer_.reset(new std::vector<char>(buff->size()));
if (buffer_.get())
{
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();
img_statu_ = (SANE_Image_Statu)buff->get_image_statu();
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)
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);
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);
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
// image-processing
public:
int init_auto_txt_hanld()
{
int ret = 0;
#ifndef WIN32
2022-11-02 01:21:36 +00:00
#ifdef OEM_HANWANG
string libname = "libhwdriver.so";
#elif defined(OEM_LISICHENG)
string libname = "liblscdriver.so";
#else
string libname = "libhgdriver.so";
#endif
string scanner_path = hg_log::get_module_full_path(libname.c_str());
2022-11-02 01:21:36 +00:00
if (scanner_path.empty())
{
return SCANNER_ERR_OUT_OF_RANGE;
}
2022-11-02 01:21:36 +00:00
scanner_path = scanner_path.substr(0, scanner_path.size() - libname.size());
2022-11-02 03:09:06 +00:00
string HGImagePrclib_path = scanner_path + IMGPRC_LIBNANE;
string HGBaselib_path = scanner_path + HGBASE_LIBNAME;
printf("get auto txt path is:%s\r\n", scanner_path.c_str());
if (access(HGBaselib_path.c_str(), F_OK) != 0 && access(HGImagePrclib_path.c_str(), F_OK) != 0)
{
2022-11-02 03:09:06 +00:00
printf("111111111111111111111111111\r\n");
return SCANNER_ERR_OUT_OF_RANGE;
}
2022-11-02 03:09:06 +00:00
printf("HGBaselib_path%s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str());
Dynamicopen_HGImageprc_pHandle_ = dlopen(HGImagePrclib_path.c_str(), RTLD_LAZY);
Dynamicopen_HGBase_pHandle_ = dlopen(HGBaselib_path.c_str(), RTLD_LAZY);
2022-11-02 01:21:36 +00:00
2022-11-02 03:09:06 +00:00
if (!Dynamicopen_HGBase_pHandle_ && !Dynamicopen_HGImageprc_pHandle_)
{
return SCANNER_ERR_OUT_OF_RANGE;
}
2022-11-02 03:09:06 +00:00
ocrinit_ = (SDKHGImgProc_InitOCR_)dlsym(Dynamicopen_HGImageprc_pHandle_, "HGImgProc_CreateOCRMgr");
ocrgetdirectimage_ = (SDKHGImgProc_GetTextDir_)dlsym(Dynamicopen_HGImageprc_pHandle_, "HGImgProc_ImageTextDirectOCR");
ocrexit_ = (SDKHGImgProc_FreeImage_)dlsym(Dynamicopen_HGImageprc_pHandle_, "HGImgProc_DestroyOCRMgr");
HGBase_CreatImg = (SDKHGBase_CreateImage_)dlsym(Dynamicopen_HGBase_pHandle_,"HGBase_CreateImageWithData");
HGBase_FreeImg = (SDKHGBase_FreeImage_)dlsym(Dynamicopen_HGBase_pHandle_,"HGBase_DestroyImage");
#else
2022-11-02 03:09:06 +00:00
Dynamicopen_HGImageprc_pHandle_ = LoadLibrary(IMGPRC_LIBNANE);
Dynamicopen_HGBase_pHandle_ = LoadLibrary(HGBASE_LIBNAME);
if (Dynamicopen_HGImageprc_pHandle_ && Dynamicopen_HGBase_pHandle_)
{
2022-11-02 03:09:06 +00:00
ocrinit_ = (SDKHGImgProc_InitOCR_)GetProcAddress(Dynamicopen_HGImageprc_pHandle_, "HGImgProc_CreateOCRMgr");
2022-11-02 03:17:19 +00:00
ocrgetdirectimage_ = (SDKHGImgProc_GetTextDir_)GetProcAddress(Dynamicopen_HGImageprc_pHandle_, "HGImgProc_ImageTextDirectOCR");
2022-11-02 03:09:06 +00:00
ocrexit_ = (SDKHGImgProc_FreeImage_)GetProcAddress(Dynamicopen_HGImageprc_pHandle_, "HGImgProc_DestroyOCRMgr");
HGBase_CreatImg = (SDKHGBase_CreateImage_)GetProcAddress(Dynamicopen_HGBase_pHandle_,"HGBase_CreateImageWithData");
HGBase_FreeImg = (SDKHGBase_FreeImage_)GetProcAddress(Dynamicopen_HGBase_pHandle_,"HGBase_DestroyImage");
}
#endif
ret = ocrinit_(HGIMGPROC_OCRALGO_TESSERACT, &Auto_Txt_pHanld);
return ret;
}
int free_auto_txt_hanld()
{
2022-11-02 03:09:06 +00:00
printf("11111111111111111111111111111----释放hanld\r\n");
int ret = 0;
2022-11-02 03:09:06 +00:00
if (Dynamicopen_HGImageprc_pHandle_ != NULL)
{
#if (!defined WIN32)
ret = dlclose(Dynamicopen_HGImageprc_pHandle_);
#else
ret = FreeLibrary(Dynamicopen_HGImageprc_pHandle_);
#endif
Dynamicopen_HGImageprc_pHandle_ = NULL;
}
if (Dynamicopen_HGBase_pHandle_ != NULL)
{
#if (!defined WIN32)
2022-11-02 03:09:06 +00:00
ret = dlclose(Dynamicopen_HGBase_pHandle_);
#else
2022-11-02 03:09:06 +00:00
ret = FreeLibrary(Dynamicopen_HGBase_pHandle_);
#endif
2022-11-02 03:09:06 +00:00
Dynamicopen_HGBase_pHandle_ = NULL;
}
if (Auto_Txt_pHanld != NULL)
{
int ret = ocrexit_(Auto_Txt_pHanld);
Auto_Txt_pHanld = NULL;
}
return ret;
}
int decode(int pid, LPSCANCONF img_param, LPIMGPRCPARAM param)
2022-05-03 03:56:07 +00:00
{
if (!buffer_)
return SCANNER_ERR_NO_DATA;
img_conf_ = *img_param;
param_ = *param;
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;
buffer_.reset(new std::vector<char >());
int i=0;
2022-05-03 03:56:07 +00:00
for (auto& buf : buffs) {
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())
{
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);
//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
{
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
buffer_.reset(new std::vector<char >());
2022-05-03 03:56:07 +00:00
}
catch (const std::exception& e)
{
LOG_INFO(LOG_LEVEL_FATAL, e.what());
2022-05-03 03:56:07 +00:00
}
}
buffs.clear();
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Decode %u bytes to %u picture(s)\n", origin, mats_.size());
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
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);
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
2022-10-20 06:58:26 +00:00
int split(int split3399)
2022-05-03 03:56:07 +00:00
{
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-09-26 10:46:04 +00:00
2022-11-02 03:09:06 +00:00
int colormode = 1; //Ĭ<><C4AC>1
2022-10-20 06:58:26 +00:00
if (img_conf_.filter == 3)
colormode = img_conf_.pixtype;
CImageApplySplit split(img_conf_.multiOutput, img_conf_.splitImage, img_conf_.multi_output_red, colormode);
auto matexs = split.SplitMats(mats, img_conf_.is_duplex);
2022-09-26 10:46:04 +00:00
2022-05-03 03:56:07 +00:00
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-09-26 10:46:04 +00:00
cv::flip(matex.mat, matex.mat, rotation01_);
2022-08-04 07:01:27 +00:00
cv::flip(matex.mat,matex.mat,rotation02_);
2022-09-26 10:46:04 +00:00
if (i > 1 && ((pid_ == 0x402) || pid_ == 0x100 || pid_ == 0x400))
2022-08-04 07:01:27 +00:00
{
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-09-19 08:23:36 +00:00
CImageApplyRotation::RotationType rotatetype = CImageApplyRotation::RotationType::Invalid;
if (pid_ == 0x402 || pid_ == 0x400 || pid_ == 0x239)
2022-09-19 08:23:36 +00:00
rotatetype = CImageApplyRotation::RotationType::Rotate_90_clockwise;
else if(pid_ == 0x100)
rotatetype = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
2022-09-26 10:46:04 +00:00
CImageApplyRotation Rotation(rotatetype,false,img_conf_.resolution_native,"./tessdata");
2022-08-02 03:07:22 +00:00
Rotation.apply(mats_,img_conf_.is_duplex);
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
2022-10-20 06:58:26 +00:00
int fadeback()
2022-05-03 03:56:07 +00:00
{
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-10-20 06:58:26 +00:00
CImageApplyFadeBackGroudColor fade(100,0, img_conf_.fadebackrange);
2022-05-03 03:56:07 +00:00
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());
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
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);
}
}
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int multi_out(int out_type)
{
std::vector<cv::Mat> mats(mats_);
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++)
{
mat = output.apply(mats[i]);
for(size_t j = 0;j < mat.size();j++)
{
//if (out_type != MULTI_COLOR_AND_GRAY && i == mats.size() - 1)
// mats_.push_back(convert_8bit_2_1bit(mat[j], 127, false, false));
//else
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
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
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());
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int auto_matic_color(int color_type)
{
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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
/*pixtype 0 colcor; 1 gray; 2 bw*/
int auto_crop()
{
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);
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]);
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
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
{
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;
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int resolution_change()
{
int ret = SCANNER_ERR_OK;
CImageApplyFilter::FilterMode sharpenType = CImageApplyFilter::FilterMode::None;
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 (img_conf_.resolution_dst > 200 && img_conf_.sharpen == CImageApplyFilter::FilterMode::None)
{
if (img_conf_.resolution_dst <= 300)
sharpenType = CImageApplyFilter::FilterMode::Sharpen;
else if (img_conf_.resolution_dst > 300 && img_conf_.resolution_dst <= 600)
sharpenType = CImageApplyFilter::FilterMode::Sharpen_More;
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]);
}
}
else
{
if(!mats.empty())
mats_ = mats;
}
2022-05-03 03:56:07 +00:00
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int croprect()
{
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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int channel()
{
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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int adjust_color(unsigned char* gamma_table = nullptr, int tableLength = 0)
2022-05-03 03:56:07 +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);
if(gamma_table && tableLength)
2022-05-03 03:56:07 +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;
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int antiInflow(int permeate_lv)
2022-05-03 03:56:07 +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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int colorCorrection()
{
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;
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int orentation()
2022-05-03 03:56:07 +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-09-26 10:46:04 +00:00
unsigned char back180 = false;
if (img_conf_.splitImage)
unsigned char back180 = false;
else
back180 = img_conf_.is_backrotate180;
CImageApplyRotation Rotation(rotatetype, back180,img_conf_.resolution_native,"./tessdata");
2022-05-03 03:56:07 +00:00
Rotation.apply(mats,img_conf_.is_duplex);
mats_ = mats;
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int textureRemove()
{
int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-05-03 03:56:07 +00:00
CImageApplyTextureRemoval Removal;
2022-05-03 03:56:07 +00:00
Removal.apply(mats,img_conf_.is_duplex);
mats_ = mats;
2022-05-03 03:56:07 +00:00
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int sharpenType()
2022-05-03 03:56:07 +00:00
{
int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-05-03 03:56:07 +00:00
CImageApplyFilter::FilterMode sharpenType = (CImageApplyFilter::FilterMode)img_conf_.sharpen;
CImageApplyFilter Filte(sharpenType);
2022-05-03 03:56:07 +00:00
for (size_t i = 0; i < mats.size(); ++i)
{
Filte.apply(mats[i],img_conf_.is_duplex);
2022-05-03 03:56:07 +00:00
mats_.push_back(mats[i]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
}
int nosieDetach()
{
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);
2022-05-03 03:56:07 +00:00
for (size_t i = 0; i < mats.size(); ++i)
{
Noise.apply(mats[i],img_conf_.is_duplex);
2022-05-03 03:56:07 +00:00
mats_.push_back(mats[i]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
int errorextention()
{
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;
2022-05-03 03:56:07 +00:00
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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
int discardBlank()
{
int ret = SCANNER_ERR_OK;
2022-05-09 11:27:10 +00:00
std::vector<cv::Mat> mats(mats_);
mats_.clear();
double threshold = 40;
int edge = 150;
if (img_conf_.is_autodiscradblank_vince)
img_conf_.discardblank_percent *= 1.5;
CImageApplyDiscardBlank(threshold,edge,img_conf_.discardblank_percent);
2022-05-09 11:27:10 +00:00
for (size_t i = 0; i < mats.size(); ++i)
{
bool b = CImageApplyDiscardBlank::apply(mats[i]);
2022-08-17 08:35:58 +00:00
if (b)
mats[i].release();
else
mats_.push_back(mats[i]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
int answerSheetFilterRed()
{
int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-08-17 08:35:58 +00:00
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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
int fold()
{
int ret = SCANNER_ERR_OK;
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-07-29 03:39:47 +00:00
2022-10-28 10:42:22 +00:00
CImageApplyConcatenation fold((CImageApplyConcatenation::ConcatMode)img_conf_.fold_concatmode);
fold.apply(mats,img_conf_.is_duplex);
mats_= mats;
2022-07-29 03:39:47 +00:00
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-07-29 02:11:38 +00:00
}
int quality(int dpi_dst)
2022-07-29 03:39:47 +00:00
{
int ret = SCANNER_ERR_OK;
CImageApplyFilter::FilterMode sharpenType = CImageApplyFilter::FilterMode::None;
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);
}
if (img_conf_.resolution_dst <= 300)
sharpenType = CImageApplyFilter::FilterMode::Sharpen;
else if (img_conf_.resolution_dst > 300 && img_conf_.resolution_dst <= 600)
sharpenType = CImageApplyFilter::FilterMode::Sharpen_More;
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]);
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
2022-07-29 03:39:47 +00:00
}
#ifdef _WIN32
2022-08-17 08:35:58 +00:00
#endif
#define test
int ocr_auto_txtdirect()
2022-07-28 02:34:48 +00:00
{
std::vector<cv::Mat> mats(mats_);
mats_.clear();
2022-07-28 09:04:38 +00:00
int pDirect = -1,
ret = SCANNER_ERR_OK;
void* pHanld = NULL;
typedef int (* SDKInitialize)(void** ppstOcrHandle);
typedef void(* SDKExit)(void* pstOcrHandle);
typedef int (* SDKGetFileDirectImage)(BYTE* pbImage, int nWidth, int nHeight, TColorType nColorType, void* pstHandle, int* pDirect);
SDKInitialize ocrinit = NULL;
SDKGetFileDirectImage ocrgetdirectimage = NULL;
SDKExit ocrexit = NULL;
#ifndef WIN32
#ifdef OEM_HANWANG
string libname = "libhwdriver.so";
#elif defined(OEM_LISICHENG)
string libname = "liblscdriver.so";
#else
string libname = "libhgdriver.so";
#endif
string scanner_path = hg_log::get_module_full_path(libname.c_str());
if(scanner_path.empty())
2022-07-28 02:52:09 +00:00
{
return SCANNER_ERR_OUT_OF_RANGE;
2022-08-17 08:35:58 +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());
if(access(scanner_path.c_str(),F_OK) != 0)
{
return SCANNER_ERR_OUT_OF_RANGE;
}
#endif
#if ((!defined x86_64) && (!defined WIN32))
//linux x86_64
void *hanlde = dlopen(scanner_path.c_str(),RTLD_LAZY);
if(!hanlde)
2022-08-17 08:35:58 +00:00
{
return SCANNER_ERR_OUT_OF_RANGE;
}
ocrinit = (SDKInitialize)dlsym(hanlde , "HWOCR_SDKInitialize");
ocrgetdirectimage = (SDKGetFileDirectImage)dlsym(hanlde , "HWOCR_GetFileDirectImage");
ocrexit= (SDKExit)dlsym(hanlde , "HWOCR_SDKExit");
#else
#ifdef _WIN32
HINSTANCE handle = LoadLibrary(L"hanwangOCRdetect.dll");
if (handle)
{
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
if (pDirect == 1)
pDirect = 3;
else if (pDirect == 3)
pDirect = 1;
2022-07-28 09:04:38 +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);
#else
#endif
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
int tesseract_auto_txtdirect()
{
std::vector<cv::Mat> mats(mats_);
mats_.clear();
unsigned int pDirect = 0,
ret = SCANNER_ERR_OK;
HGImage image;
if (ocrinit_ && ocrgetdirectimage_ && ocrexit_)
{
for (size_t i = 0; i < mats.size(); i++)
{
HGImage b = opencv_to_hgbase_image(mats[i]);
ret = ocrgetdirectimage_(Auto_Txt_pHanld, b, &pDirect);
2022-11-02 03:09:06 +00:00
HGBase_FreeImg(b);
//HGBase_DestroyImage(b);
switch (pDirect)
{
case HGIMGPROC_OCRTEXTDIRECT_ORI:
2022-11-02 03:09:06 +00:00
pDirect = (unsigned int)CImageApplyRotation::RotationType::Invalid;
break;
case HGIMGPROC_OCRTEXTDIRECT_RIGHT:
2022-11-02 03:09:06 +00:00
pDirect = (unsigned int)CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
break;
case HGIMGPROC_OCRTEXTDIRECT_LEFT:
2022-11-02 03:09:06 +00:00
pDirect = (unsigned int)CImageApplyRotation::RotationType::Rotate_90_clockwise;
break;
case HGIMGPROC_OCRTEXTDIRECT_180:
2022-11-02 03:09:06 +00:00
pDirect = (unsigned int)CImageApplyRotation::RotationType::Rotate_180;
break;
default:
pDirect = (int)CImageApplyRotation::RotationType::Invalid;
break;
}
CImageApplyRotation(CImageApplyRotation::RotationType(pDirect)).apply(mats[i], false);
mats_.push_back(mats[i]);
}
}
if (mats_.empty())
{
return SCANNER_ERR_NO_DATA;
}
return SCANNER_ERR_OK;
}
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]);
2022-08-17 08:35:58 +00:00
mats_.push_back(mats[i]);
}
if(ret == 1)
{
return SCANNER_ERR_DEVICE_SIZE_CHECK;
}
return SCANNER_ERR_OK;
}
2022-08-17 08:35:58 +00:00
2022-11-02 03:09:06 +00:00
HGImage opencv_to_hgbase_image(const cv::Mat& mats)
{
HGImage image;
HGImageInfo info;
info.height = mats.rows;
info.width = mats.cols;
2022-11-02 03:09:06 +00:00
info.origin = HGBASE_IMGORIGIN_TOP;
int bits = mats.channels() == 1 ? 8 : 24;
info.widthStep = mats.step; //opencv原始值
info.type = mats.channels() == 1 ? HGBASE_IMGTYPE_GRAY : HGBASE_IMGTYPE_BGR;
2022-11-02 03:09:06 +00:00
int ret = HGBase_CreatImg(const_cast<uchar*>(mats.data), &info, &image);
//int ret = HGBase_CreateImageWithData(const_cast<uchar*>(mats.data), &info, &image);
return image;
}
2022-11-02 03:09:06 +00:00
/// <summary>
2022-11-02 03:09:06 +00:00
/// 8位图转1位图
/// </summary>
2022-11-02 03:09:06 +00:00
/// <param name="image">8bit图</param>
/// <param name="threshold">阈值建议默认127</param>
/// <param name="reverse">true为反色即黑0白1反之亦然</param>
/// <param name="align">true为四字节对齐</param>
/// <returns>1位图</returns>
///
static cv::Mat convert_8bit_2_1bit(const cv::Mat& image, uchar threshold, bool reverse, bool align)
2022-05-19 06:35:38 +00:00
{
if (image.channels() != 1)
return cv::Mat();
int cols = align ? (((image.cols + 7) / 8 + 3) / 4 * 4) : ((image.cols + 7) / 8);
int rows = image.rows;
uchar tableData[256];
memset(tableData, reverse ? 0 : 1, 256);
memset(tableData, reverse ? 1 : 0, threshold);
2022-09-29 01:34:39 +00:00
int* index_dst = new int[image.cols];
int* index_carry = new int[image.cols];
for (size_t i = 0; i < image.cols; i++)
{
index_dst[i] = i / 8;
index_carry[i] = 7 - (i % 8);
}
cv::Mat dst = cv::Mat::zeros(rows, cols, CV_8UC1);
uchar* ptr_src, * ptr_dst;
for (size_t y = 0; y < rows; y++)
{
ptr_dst = dst.ptr<uchar>(y);
ptr_src = const_cast<uchar*>(image.ptr<uchar>(y));
for (size_t x = 0; x < image.cols; x++)
2022-09-29 01:34:39 +00:00
ptr_dst[index_dst[x]] += tableData[ptr_src[x]] << index_carry[x];
}
2022-09-29 01:34:39 +00:00
delete[] index_dst;
delete[] index_carry;
return dst;
2022-05-19 06:35:38 +00:00
}
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);
//cv::imwrite(std::to_string(i++)+"_final.jpg",out.mat);
2022-05-03 03:56:07 +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()))
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;
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);
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()))
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->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);
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)
{
int ret = SCANNER_ERR_OK;
2022-05-03 03:56:07 +00:00
if(!buf)
{
return SCANNER_ERR_NO_DATA;
2022-05-03 03:56:07 +00:00
}
cv::imencode(img_type_,*((cv::Mat*)buf),bmpdata);
return ret;
}
void dump_2_file(const char* local_file)
{
if (mats_.size())
{
cv::imwrite(local_file, mats_[0]);
if (mats_.size() > 1)
{
std::string path(local_file), name(""), ext("");
size_t pos = path.rfind(PATH_SEPARATOR[0]);
char sn[20] = { 0 };
if (pos++ != std::string::npos)
{
name = path.substr(pos);
path.erase(pos);
pos = name.rfind('.');
if (pos != std::string::npos)
{
ext = name.substr(pos);
name.erase(pos);
}
}
for (size_t i = 1; i < mats_.size(); ++i)
{
sprintf(sn, "(%d)", i);
cv::imwrite((path + name + sn + ext).c_str(), mats_[i]);
}
}
}
else
{
LOG_INFO(LOG_LEVEL_ALL, "No image output in image_process!\n");
}
}
2022-05-03 03:56:07 +00:00
};
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// api ...
HIMGPRC init(int pid)
2022-05-03 03:56:07 +00:00
{
imgproc* obj = new imgproc(pid);
2022-05-03 03:56:07 +00:00
return (HIMGPRC)obj;
}
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, LPSCANCONF img_param, LPIMGPRCPARAM param)
{
return ((imgproc*)himg)->decode(pid, img_param, param);
}
int init_auto_txt_hanld(HIMGPRC himg)
2022-05-03 03:56:07 +00:00
{
return ((imgproc*)himg)->init_auto_txt_hanld();
}
int free_auto_txt_hanld(HIMGPRC himg)
{
return ((imgproc*)himg)->free_auto_txt_hanld();
2022-05-03 03:56:07 +00:00
}
int correct_text(HIMGPRC himg)
{
return ((imgproc*)himg)->correct_text();
}
2022-10-20 06:58:26 +00:00
int split(HIMGPRC himg,int split3399)
2022-05-03 03:56:07 +00:00
{
2022-10-20 06:58:26 +00:00
return ((imgproc*)himg)->split(split3399);
2022-05-03 03:56:07 +00:00
}
2022-10-20 06:58:26 +00:00
int fadeback(HIMGPRC himg)
2022-05-03 03:56:07 +00:00
{
2022-10-20 06:58:26 +00:00
return ((imgproc*)himg)->fadeback();
2022-05-03 03:56:07 +00:00
}
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();
}
int adjust_color(HIMGPRC himg, unsigned char* table, int tableLength)
2022-05-03 03:56:07 +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();
}
int tesseract_auto_txtdirect(HIMGPRC himg)
{
return ((imgproc*)himg)->tesseract_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 dump_2_file(HIMGPRC himg, const char* local_file)
{
((imgproc*)himg)->dump_2_file(local_file);
}
2022-05-03 03:56:07 +00:00
void release(HIMGPRC himg)
{
imgproc* obj = (imgproc*)himg;
delete obj;
}
// seperate utilites ...
static cv::Mat from_bmp_file_bits(const BITMAPINFOHEADER& bih, unsigned char* data, bool line_reverse, bool bw_reverse)
{
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 * bih.biWidth + 7) / 8;
align = (bytes + 3) / 4 * 4;
if (line_reverse)
{
data += align * (bih.biHeight - 1);
align *= -1;
}
if (bih.biBitCount >= 8)
{
if (bih.biBitCount == 8 && bw_reverse)
{
for (int i = 0; i < bih.biHeight; ++i)
{
for (int j = 0; j < bytes; ++j)
dst[j] = data[j] ^ 0x0ff;
dst += bytes;
data += align;
}
}
else
{
for (int i = 0; i < bih.biHeight; ++i)
{
memcpy(dst, data, bytes);
dst += bytes;
data += align;
}
}
}
else // if (bih.biBitCount == 1)
{
unsigned char bw[] = { !bw_reverse - 1, bw_reverse - 1};
bytes = bih.biWidth;
for (int i = 0; i < bih.biHeight; ++i)
{
bit_stream bs(data, false);
for (int j = 0; j < bih.biWidth; ++j)
dst[j] = bw[bs.get()];
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)
{
BITMAPFILEHEADER bfh = { 0 };
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, 0, SEEK_SET);
fread(&bfh, sizeof(bfh), 1, src);
fread(&bih, sizeof(bih), 1, src);
if (len < bfh.bfOffBits)
{
fclose(src);
return SCANNER_ERR_DATA_DAMAGED;
}
// we consider pallete as gray, discard pallete here ...
fseek(src, bfh.bfOffBits, SEEK_SET);
len -= bfh.bfOffBits;
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));
2022-09-15 06:37:29 +00:00
bits = (unsigned char*)conv->src.data + ((BITMAPFILEHEADER*)conv->src.data)->bfOffBits;
}
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 || conv->dst.fmt.img_format == SANE_IMAGE_TYPE_JFIF, tiff && conv->dst.fmt.compress.compression != SANE_COMPRESSION_GROUP4);
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)
{
2022-09-15 06:37:29 +00:00
// MSB word[7] and word[8] are x and y resolutions
std::vector<int> cpr;
2022-09-20 04:40:11 +00:00
unsigned short jpeg_r = (resolution << 8) | ((resolution >> 8) & 0x0ff);
2022-10-14 09:27:54 +00:00
int resolution_y = bih.biYPelsPerMeter / 39.37f + .5f;
cpr.push_back(CV_IMWRITE_JPEG_QUALITY);
cpr.push_back((int)(long)conv->dst.fmt.detail);
2022-10-14 09:27:54 +00:00
cpr.push_back(CV_IMWRITE_JPEG_RESOLUTION_UNIT);
cpr.push_back(1);
cpr.push_back(CV_IMWRITE_JPEG_RESOLUTION_X);
cpr.push_back(resolution);
cpr.push_back(CV_IMWRITE_JPEG_RESOLUTION_Y);
cpr.push_back(resolution_y);
if (conv->dst.is_file)
2022-09-20 04:40:11 +00:00
{
cv::imwrite(conv->dst.data, imsg, cpr);
2022-09-20 04:40:11 +00:00
//FILE* f = fopen(conv->dst.data, "rb+");
//if (f)
//{
// fseek(f, 0x0e, SEEK_SET);
// fwrite(&jpeg_r, sizeof(jpeg_r), 1, f);
// fwrite(&jpeg_r, sizeof(jpeg_r), 1, f);
// fclose(f);
//}
}
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());
2022-09-20 04:40:11 +00:00
//if (conv->dst.data_len > 0x20)
// ((unsigned short*)conv->dst.data)[7] = ((unsigned short*)conv->dst.data)[8] = jpeg_r;
}
}
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.bfOffBits = sizeof(fh) + sizeof(bih) + pal_size;
fh.bfSize = fh.bfOffBits + bih.biSizeImage;
2022-07-14 06:21:53 +00:00
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-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;
}
static unsigned char reverse_bit(unsigned char v)
{
unsigned char r = 0;
for (int i = 0; i < 8; ++i)
{
r <<= 1;
r |= v & 1;
v >>= 1;
}
return r;
}
std::string bmp8_2_1bit(const unsigned char* data, int w, int h, int line_len, int threshold, bool reverse, bool align)
{
cv::Mat m;
unsigned char* dst = NULL;
m.create(h, w, CV_8UC1);
dst = m.ptr();// +w * (h - 1);
for (int i = 0; i < h; ++i)
{
memcpy(dst, data, w);
dst += w;
data += line_len;
}
cv::Mat bw = imgproc::convert_8bit_2_1bit(m, threshold, reverse, align);
//std::string ret("");
2022-09-29 01:34:39 +00:00
//dst = bw.ptr();
//for (int i = 0; i < bw.total(); ++i)
// dst[i] = reverse_bit(dst[i]);
return std::string((char*)bw.ptr(), bw.total());
}
2022-05-03 03:56:07 +00:00
}