mirror of http://192.168.1.51:8099/lmh188/uv-twain
534 lines
12 KiB
C++
534 lines
12 KiB
C++
//#include "ImageApplyBWBinaray.h"
|
||
//
|
||
//CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, int blockSize, int constant)
|
||
// : m_threshold(threshold)
|
||
// , m_type(type)
|
||
// , m_blockSize(blockSize)
|
||
// , m_constant(constant)
|
||
// , m_table(new uchar[256])
|
||
//{
|
||
// memset(m_table, 255, 256);
|
||
// memset(m_table, 0, static_cast<size_t>(m_threshold));
|
||
//}
|
||
//
|
||
//CImageApplyBWBinaray::CImageApplyBWBinaray()
|
||
// : m_threshold(180)
|
||
// , m_type(ThresholdType::THRESH_BINARY)
|
||
// , m_blockSize(25)
|
||
// , m_constant(5)
|
||
// , m_table(new uchar[256])
|
||
//{
|
||
// memset(m_table, 255, 256);
|
||
// memset(m_table, 0, static_cast<size_t>(m_threshold));
|
||
//}
|
||
//
|
||
//
|
||
//CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
||
//{
|
||
// delete[] m_table;
|
||
//}
|
||
//
|
||
//void CImageApplyBWBinaray::apply(cv::Mat& pDib,int side)
|
||
//{
|
||
//#ifdef LOG
|
||
// FileTools::write_log("imgprc.txt", "enter CImageApplyBWBinaray apply");
|
||
//#endif // LOG
|
||
// if (pDib.empty())
|
||
// {
|
||
//#ifdef LOG
|
||
// FileTools::write_log("imgprc.txt", "exit CImageApplyBWBinaray apply");
|
||
//#endif // LOG
|
||
// return;
|
||
// }
|
||
//
|
||
// if (pDib.channels() == 3)
|
||
// cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||
//
|
||
// switch (m_type)
|
||
// {
|
||
// case ThresholdType::THRESH_BINARY:
|
||
// //cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_BINARY);
|
||
// cv::adaptiveThreshold(pDib, pDib, 255.0, cv::ADAPTIVE_THRESH_GAUSSIAN_C, cv::THRESH_BINARY, 91, 41);
|
||
// break;
|
||
// case ThresholdType::THRESH_OTSU:
|
||
// cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
||
// break;
|
||
// case ThresholdType::ADAPTIVE_GAUSSIAN:
|
||
// cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||
// break;
|
||
// case ThresholdType::ADAPTIVE_MEAN:
|
||
// cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||
// break;
|
||
// case ThresholdType::ERROR_DIFFUSION:
|
||
// errorDiffuse(pDib);
|
||
// break;
|
||
// default:
|
||
// break;
|
||
// }
|
||
//
|
||
//#ifdef LOG
|
||
// FileTools::write_log("imgprc.txt", "exit CImageApplyBWBinaray apply");
|
||
//#endif // LOG
|
||
//}
|
||
//
|
||
//void CImageApplyBWBinaray::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||
//{
|
||
// if (mats.empty()) return;
|
||
//
|
||
// if (!mats[0].empty()) {
|
||
// apply(mats[0], 0);
|
||
// }
|
||
//
|
||
//
|
||
// if (isTwoSide && mats.size() > 1) {
|
||
// if (!mats[1].empty())
|
||
// apply(mats[1], 1);
|
||
// }
|
||
//}
|
||
//
|
||
//void CImageApplyBWBinaray::errorDiffuse(cv::Mat & image)
|
||
//{
|
||
// if (image.rows < 3 || image.cols < 3)
|
||
// {
|
||
// cv::threshold(image, image, m_threshold, 255, CV_THRESH_BINARY);
|
||
// return;
|
||
// }
|
||
//
|
||
// cv::Mat dst;
|
||
// image.convertTo(dst, CV_16S);
|
||
//
|
||
// size_t rows = static_cast<size_t>(image.rows) - 1;
|
||
// size_t cols = static_cast<size_t>(image.cols) - 1;
|
||
//
|
||
// short** pixels_dst = new short*[static_cast<size_t>(image.rows)];
|
||
// for (int i = 0; i < image.rows; i++)
|
||
// pixels_dst[i] = reinterpret_cast<short*>(dst.data + i * static_cast<int>(dst.step));
|
||
//
|
||
// short error;
|
||
// for (size_t y = 0; y < rows; y++)
|
||
// for (size_t x = 1; x < cols; x++)
|
||
// {
|
||
// short dstPix = pixels_dst[y][x];
|
||
// if (dstPix >= m_threshold)
|
||
// {
|
||
// pixels_dst[y][x] = 255;
|
||
// error = dstPix - 255;
|
||
// }
|
||
// else
|
||
// {
|
||
// pixels_dst[y][x] = 0;
|
||
// error = dstPix;
|
||
// }
|
||
//
|
||
// pixels_dst[y][x + 1] += error * 7 / 16;
|
||
// pixels_dst[y + 1][x - 1] += error * 3 / 16;
|
||
// pixels_dst[y + 1][x] += error * 5 / 16;
|
||
// pixels_dst[y + 1][x + 1] += error * 1 / 16;
|
||
// }
|
||
// image.release();
|
||
// dst.convertTo(image, CV_8U);
|
||
//
|
||
// rows++;
|
||
// uchar* ptr = image.data;
|
||
// size_t step = image.step;
|
||
// size_t offset;
|
||
// for (size_t y = 0; y < rows; y++)
|
||
// {
|
||
// offset = y * step;
|
||
// ptr[offset] = m_table[ptr[offset]];
|
||
// offset += cols;
|
||
// ptr[offset] = m_table[ptr[offset]];
|
||
// }
|
||
//
|
||
// cols++;
|
||
// ptr = image.data + step * (rows - 1);
|
||
// for (size_t x = 0; x < cols; x++)
|
||
// ptr[x] = m_table[ptr[x]];
|
||
//
|
||
// delete[] pixels_dst;
|
||
//}
|
||
#include "ImageApplyBWBinaray.h"
|
||
|
||
typedef struct image_info
|
||
{
|
||
int32_t width;
|
||
int32_t height;
|
||
uint8_t* data;
|
||
}ImageInfo;
|
||
|
||
void updataIntergralImg(const uint8_t* const imgData, uint32_t* integralImg, const int32_t& width, const int32_t& height)
|
||
{
|
||
// create the integral image
|
||
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><F1BDABB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>ɶ<EFBFBD><C9B6><EFBFBD>תΪ<D7AA><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>Խ<EFBFBD><D4BD><EFBFBD><EFBFBD>
|
||
|
||
uint32_t sum = 0;
|
||
int32_t i, j;
|
||
const uint32_t* img = (uint32_t*)imgData;
|
||
uint32_t* interImgTmp = integralImg;
|
||
uint32_t tmp = 0;
|
||
for (i = 0; i < width; i += 4)
|
||
{
|
||
tmp = *img;
|
||
sum += tmp & 0x000000ff;//unportble
|
||
interImgTmp[0] = sum;
|
||
interImgTmp++;
|
||
|
||
sum += (tmp >> 8) & 0x000000ff;
|
||
interImgTmp[0] = sum;
|
||
interImgTmp++;
|
||
|
||
sum += (tmp >> 16) & 0x000000ff;
|
||
interImgTmp[0] = sum;
|
||
interImgTmp++;
|
||
|
||
sum += (tmp >> 24) & 0x000000ff;
|
||
interImgTmp[0] = sum;
|
||
interImgTmp++;
|
||
img++;
|
||
}
|
||
for (i = 1; i < height; ++i)
|
||
{
|
||
sum = 0;
|
||
for (j = 0; j < width; j += 4)
|
||
{
|
||
tmp = *img;
|
||
sum += tmp & 0x000000ff;
|
||
interImgTmp[0] = sum + interImgTmp[-width];
|
||
interImgTmp++;
|
||
|
||
sum += (tmp >> 8) & 0x000000ff;
|
||
interImgTmp[0] = sum + interImgTmp[-width];
|
||
interImgTmp++;
|
||
|
||
sum += (tmp >> 16) & 0x000000ff;
|
||
interImgTmp[0] = sum + interImgTmp[-width];
|
||
interImgTmp++;
|
||
|
||
sum += (tmp >> 24) & 0x000000ff;
|
||
interImgTmp[0] = sum + interImgTmp[-width];
|
||
interImgTmp++;
|
||
img++;
|
||
}
|
||
}
|
||
}
|
||
|
||
void threshold(ImageInfo& image_src, uint8_t thre)
|
||
{
|
||
uint8_t table[256];
|
||
memset(table, 0, thre);
|
||
memset(table + thre, 255, 256 - thre);
|
||
|
||
int32_t size = image_src.width * image_src.height;
|
||
uint8_t* ptr = image_src.data;
|
||
|
||
for (int32_t i = 0; i < size; i++)
|
||
{
|
||
ptr[i] = table[ptr[i]];
|
||
}
|
||
}
|
||
|
||
void adaptivethresh(ImageInfo& image_src, const uint8_t& lowThr, const uint8_t& upThr, const uint8_t& init_threshold)
|
||
{
|
||
|
||
//<2F><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD>μ<EFBFBD>welner<65><72><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ֵ<EFBFBD>㷨<EFBFBD><E3B7A8><EFBFBD>IJ<DEB8><C4B2><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ĸ<EFBFBD><C4B8>߽<EFBFBD><DFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><C8BC>㣬<EFBFBD><E3A3AC><EFBFBD>IJ<EFBFBD><C4B2>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣬<EFBFBD><E3A3AC><EFBFBD><EFBFBD>ħ<EFBFBD><C4A7>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ֵ
|
||
const uint8_t thresh = __min(init_threshold, 100);
|
||
|
||
uint8_t S = 17;
|
||
unsigned short T = 100 - thresh;
|
||
T = (unsigned short)((float)T * 10.24);
|
||
|
||
unsigned short i, j;
|
||
uint32_t sum = 0;
|
||
unsigned short count = 0;
|
||
int16_t x1, y1, x2, y2;
|
||
const uint8_t s2 = S >> 1;
|
||
uint8_t* pointer = image_src.data;
|
||
//pointer = image_src;
|
||
|
||
const int32_t width = image_src.width;
|
||
const int32_t height = image_src.height;
|
||
uint32_t* integralImg = new uint32_t[width * height];//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ֵ<EFBFBD>㷨
|
||
|
||
updataIntergralImg(image_src.data, integralImg, width, height);
|
||
|
||
uint8_t t = 0;
|
||
|
||
ImageInfo img_up_dwon;
|
||
img_up_dwon.data = pointer;
|
||
img_up_dwon.width = width;
|
||
img_up_dwon.height = s2 + 1;
|
||
threshold(img_up_dwon, init_threshold);
|
||
|
||
pointer = image_src.data;
|
||
pointer += (height - s2) * width;
|
||
img_up_dwon.data = pointer;
|
||
img_up_dwon.width = width;
|
||
img_up_dwon.height = s2;
|
||
threshold(img_up_dwon, init_threshold);
|
||
|
||
pointer = image_src.data + (s2 + 1) * width;
|
||
for (i = 0; i <= s2; ++i)
|
||
{
|
||
for (j = s2 + 1; j < height - s2; ++j)
|
||
{
|
||
if (pointer[0] < init_threshold)
|
||
{
|
||
pointer[0] = 0;
|
||
}
|
||
else
|
||
{
|
||
pointer[0] = 255;
|
||
}
|
||
pointer += width;
|
||
}
|
||
pointer = image_src.data + (s2 + 1) * width + i + 1;
|
||
}
|
||
|
||
pointer = image_src.data + (s2 + 1) * width + (width - s2);
|
||
unsigned short ii = 1;
|
||
for (i = width - s2; i < width; ++i)
|
||
{
|
||
for (j = s2 + 1; j < height - s2; ++j)
|
||
{
|
||
if (pointer[0] < init_threshold)
|
||
{
|
||
pointer[0] = 0;
|
||
}
|
||
else
|
||
{
|
||
pointer[0] = 255;
|
||
}
|
||
pointer += width;
|
||
}
|
||
pointer = image_src.data + (s2 + 1) * width + (width - s2) + ii;
|
||
ii++;
|
||
}
|
||
///center part
|
||
unsigned short ww = width - s2 - s2 - 1;
|
||
unsigned short hh = height - s2 - s2 - 1;
|
||
uint8_t gap = width - ww;
|
||
count = (s2 << 1) + 1;
|
||
count *= count;
|
||
const uint32_t factor = count * 100 / (100 - 50);
|
||
|
||
uint32_t* plt;
|
||
uint32_t* prt;
|
||
uint32_t* plb;
|
||
uint32_t* prb;
|
||
plt = integralImg;
|
||
prt = plt + (s2 << 1) + 1;
|
||
plb = plt + ((s2 << 1) + 1) * width;
|
||
prb = prt + ((s2 << 1) + 1) * width;
|
||
pointer = image_src.data + (s2 + 1) * width + s2 + 1;
|
||
|
||
for (i = 0; i < hh; ++i)
|
||
{
|
||
for (j = 0; j < ww; j++)
|
||
{
|
||
|
||
if (/*expected_true(*/*pointer >= upThr/*)*/)
|
||
{
|
||
*pointer = 255;
|
||
}
|
||
else if (*pointer < lowThr)
|
||
{
|
||
*pointer = 0;
|
||
}
|
||
else
|
||
{
|
||
sum = *prb - *prt - *plb + *plt;
|
||
t = *pointer;
|
||
if (/*expected_false(*/t * factor <= sum/*)*/)
|
||
*pointer = 0;
|
||
else
|
||
*pointer = 255;
|
||
}
|
||
plt++;
|
||
prt++;
|
||
plb++;
|
||
prb++;
|
||
pointer++;
|
||
}
|
||
plt += gap;
|
||
prt += gap;
|
||
plb += gap;
|
||
prb += gap;
|
||
pointer += width - ww;
|
||
}
|
||
delete[]integralImg;
|
||
}
|
||
|
||
|
||
CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, int blockSize, int constant)
|
||
: m_threshold(threshold)
|
||
, m_type(type)
|
||
, m_blockSize(blockSize)
|
||
, m_constant(constant)
|
||
, m_table(new uchar[256])
|
||
{
|
||
memset(m_table, 255, 256);
|
||
memset(m_table, 0, static_cast<size_t>(m_threshold));
|
||
}
|
||
|
||
CImageApplyBWBinaray::CImageApplyBWBinaray()
|
||
: m_threshold(160)
|
||
, m_type(ThresholdType::THRESH_BINARY)
|
||
, m_blockSize(25)
|
||
, m_constant(5)
|
||
, m_table(new uchar[256])
|
||
{
|
||
memset(m_table, 255, 256);
|
||
memset(m_table, 0, static_cast<size_t>(m_threshold));
|
||
}
|
||
|
||
|
||
CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
||
{
|
||
delete[] m_table;
|
||
}
|
||
|
||
void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
||
{
|
||
(void)side;
|
||
if (pDib.empty()) return;
|
||
|
||
if (pDib.channels() == 3)
|
||
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||
|
||
switch (m_type)
|
||
{
|
||
case ThresholdType::THRESH_BINARY:
|
||
{
|
||
//ImageInfo info;
|
||
//info.data = pDib.data;
|
||
//info.width = pDib.step;
|
||
//info.height = pDib.rows;
|
||
|
||
//adaptivethresh(info, 80, 255, 127);
|
||
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_BINARY);
|
||
//cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 91, 21);
|
||
//cv::Mat integ;
|
||
//cv::integral(pDib, integ, CV_32S);
|
||
|
||
//int blockSize = 30;//<2F><><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD>
|
||
//int threshold = 4;
|
||
//int low = 115;
|
||
//int up = 200;
|
||
//int halfSize = blockSize / 2;
|
||
//for (int j = halfSize; j < integ.rows - halfSize - 1; j++)
|
||
//{
|
||
// uchar* data = pDib.ptr<uchar>(j);
|
||
// int* idata1 = integ.ptr<int>(j - halfSize);
|
||
// int* idata2 = integ.ptr<int>(j + halfSize + 1);
|
||
// for (int i = halfSize; i < integ.cols - halfSize - 1; i++)
|
||
// {
|
||
// int sum = (idata2[i + halfSize + 1] - idata2[i - halfSize] - idata1[i + halfSize + 1] + idata1[i - halfSize]) / (blockSize * blockSize);
|
||
// if (data[i] < low) data[i] = 0;
|
||
// else if (data[i] > up) data[i] = 255;
|
||
// else
|
||
// {
|
||
// if (data[i] < (sum - threshold))
|
||
// data[i] = 0;
|
||
// else
|
||
// data[i] = 255;
|
||
// }
|
||
// }
|
||
//}
|
||
break;
|
||
}
|
||
case ThresholdType::THRESH_OTSU:
|
||
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
||
break;
|
||
case ThresholdType::ADAPTIVE_GAUSSIAN:
|
||
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||
break;
|
||
case ThresholdType::ADAPTIVE_MEAN:
|
||
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, m_blockSize, m_constant);
|
||
break;
|
||
case ThresholdType::ERROR_DIFFUSION:
|
||
errorDiffuse(pDib);
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
#ifdef LOG
|
||
FileTools::write_log("imgprc.txt", "exit CImageApplyBWBinaray apply");
|
||
#endif // LOG
|
||
}
|
||
|
||
void CImageApplyBWBinaray::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||
{
|
||
(void)isTwoSide;
|
||
int i = 0;
|
||
for (cv::Mat& var : mats) {
|
||
if (i != 0 && isTwoSide == false)
|
||
break;
|
||
if (!var.empty())
|
||
apply(var, 0);
|
||
i++;
|
||
}
|
||
}
|
||
|
||
void CImageApplyBWBinaray::errorDiffuse(cv::Mat& image)
|
||
{
|
||
if (image.rows < 3 || image.cols < 3)
|
||
{
|
||
cv::threshold(image, image, m_threshold, 255, CV_THRESH_BINARY);
|
||
return;
|
||
}
|
||
|
||
cv::Mat dst;
|
||
image.convertTo(dst, CV_16S);
|
||
|
||
size_t rows = static_cast<size_t>(image.rows) - 1;
|
||
size_t cols = static_cast<size_t>(image.cols) - 1;
|
||
|
||
short** pixels_dst = new short* [static_cast<size_t>(image.rows)];
|
||
for (int i = 0; i < image.rows; i++)
|
||
pixels_dst[i] = reinterpret_cast<short*>(dst.data + i * static_cast<int>(dst.step));
|
||
|
||
short error;
|
||
for (size_t y = 0; y < rows; y++)
|
||
for (size_t x = 1; x < cols; x++)
|
||
{
|
||
short dstPix = pixels_dst[y][x];
|
||
if (dstPix >= m_threshold)
|
||
{
|
||
pixels_dst[y][x] = 255;
|
||
error = dstPix - 255;
|
||
}
|
||
else
|
||
{
|
||
pixels_dst[y][x] = 0;
|
||
error = dstPix;
|
||
}
|
||
|
||
pixels_dst[y][x + 1] += error * 7 / 16;
|
||
pixels_dst[y + 1][x - 1] += error * 3 / 16;
|
||
pixels_dst[y + 1][x] += error * 5 / 16;
|
||
pixels_dst[y + 1][x + 1] += error * 1 / 16;
|
||
}
|
||
image.release();
|
||
dst.convertTo(image, CV_8U);
|
||
|
||
rows++;
|
||
uchar* ptr = image.data;
|
||
size_t step = image.step;
|
||
size_t offset;
|
||
for (size_t y = 0; y < rows; y++)
|
||
{
|
||
offset = y * step;
|
||
ptr[offset] = m_table[ptr[offset]];
|
||
offset += cols;
|
||
ptr[offset] = m_table[ptr[offset]];
|
||
}
|
||
|
||
cols++;
|
||
ptr = image.data + step * (rows - 1);
|
||
for (size_t x = 0; x < cols; x++)
|
||
ptr[x] = m_table[ptr[x]];
|
||
|
||
delete[] pixels_dst;
|
||
}
|