mirror of http://192.168.1.51:8099/lmh188/twain3.0
优化图像二值化算法
This commit is contained in:
parent
a3af24ceab
commit
9d4a3a6e8f
|
@ -1,4 +1,366 @@
|
||||||
|
//#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"
|
#include "ImageApplyBWBinaray.h"
|
||||||
|
#include "ImageProcess_Public.h"
|
||||||
|
#include "StopWatch.h"
|
||||||
|
#include "filetools.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
|
||||||
|
//积分图像将窗口内像素值和计算时间由二阶转为常量,窗口越大,效果越明显
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
|
||||||
|
//基本原理参见welner自适应阈值算法,修改部分为将四个边界事先计算,中心部分单独计算,所有魔数为经验值
|
||||||
|
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];//积分图,用于自适应二值算法
|
||||||
|
|
||||||
|
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)
|
CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, int blockSize, int constant)
|
||||||
: m_threshold(threshold)
|
: m_threshold(threshold)
|
||||||
|
@ -12,7 +374,7 @@ CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, in
|
||||||
}
|
}
|
||||||
|
|
||||||
CImageApplyBWBinaray::CImageApplyBWBinaray()
|
CImageApplyBWBinaray::CImageApplyBWBinaray()
|
||||||
: m_threshold(180)
|
: m_threshold(160)
|
||||||
, m_type(ThresholdType::THRESH_BINARY)
|
, m_type(ThresholdType::THRESH_BINARY)
|
||||||
, m_blockSize(25)
|
, m_blockSize(25)
|
||||||
, m_constant(5)
|
, m_constant(5)
|
||||||
|
@ -30,16 +392,8 @@ CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
||||||
|
|
||||||
void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
||||||
{
|
{
|
||||||
#ifdef LOG
|
(void)side;
|
||||||
FileTools::write_log("imgprc.txt", "enter CImageApplyBWBinaray apply");
|
if (pDib.empty()) return;
|
||||||
#endif // LOG
|
|
||||||
if (pDib.empty())
|
|
||||||
{
|
|
||||||
#ifdef LOG
|
|
||||||
FileTools::write_log("imgprc.txt", "exit CImageApplyBWBinaray apply");
|
|
||||||
#endif // LOG
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pDib.channels() == 3)
|
if (pDib.channels() == 3)
|
||||||
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||||||
|
@ -47,8 +401,75 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib,int side)
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
case ThresholdType::THRESH_BINARY:
|
case ThresholdType::THRESH_BINARY:
|
||||||
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_BINARY);
|
{
|
||||||
|
#if 0
|
||||||
|
StopWatch sw;
|
||||||
|
float ksize = 9.0f;
|
||||||
|
float other = (1.0f - ksize) / 4.0f;
|
||||||
|
float kernel_data[] = { 0, other, 0, other, ksize, other, 0, other, 0 };
|
||||||
|
cv::Mat kernel(3, 3, CV_32FC1, kernel_data);
|
||||||
|
|
||||||
|
cv::filter2D(pDib, pDib, pDib.depth(), kernel);
|
||||||
|
FileTools::write_log("E:\\Users\\huago\\Desktop\\2.txt", "filter2D: " + std::to_string(sw.elapsed_ms()));
|
||||||
|
sw.reset();
|
||||||
|
cv::adaptiveThreshold(pDib, pDib, 255, cv::ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 91, 21);
|
||||||
|
FileTools::write_log("E:\\Users\\huago\\Desktop\\2.txt", "adaptiveThreshold: " + std::to_string(sw.elapsed_ms()));
|
||||||
|
//cv::Mat mask = pDib.clone();
|
||||||
|
//std::vector<std::vector<cv::Point>> contours;
|
||||||
|
//std::vector<cv::Vec4i> h;
|
||||||
|
//hg::findContours(mask, contours, h);
|
||||||
|
//mask.release();
|
||||||
|
|
||||||
|
//for (const std::vector<cv::Point>& contour : contours)
|
||||||
|
// if (contourArea(contour) < 6)
|
||||||
|
// fillConvexPoly(pDib, contour, cv::Scalar(255));
|
||||||
|
#endif
|
||||||
|
//StopWatch sw;
|
||||||
|
cv::Mat integ;
|
||||||
|
cv::integral(pDib, integ, CV_32S);
|
||||||
|
|
||||||
|
int blockSize = 31;//邻域尺寸
|
||||||
|
int threshold = 21;
|
||||||
|
int low = 110;
|
||||||
|
int up = 220;
|
||||||
|
int halfSize = blockSize / 2;
|
||||||
|
int square_block = blockSize * blockSize;
|
||||||
|
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]) / square_block;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cv::threshold(pDib(cv::Rect(0, 0, halfSize, pDib.rows)), pDib(cv::Rect(0, 0, halfSize, pDib.rows)), m_threshold, 255, cv::THRESH_BINARY);
|
||||||
|
cv::threshold(pDib(cv::Rect(pDib.cols - halfSize, 0, halfSize, pDib.rows)), pDib(cv::Rect(pDib.cols - halfSize, 0, halfSize, pDib.rows)), m_threshold, 255, cv::THRESH_BINARY);
|
||||||
|
cv::threshold(pDib(cv::Rect(0, 0, pDib.cols, halfSize)), pDib(cv::Rect(0, 0, pDib.cols, halfSize)), m_threshold, 255, cv::THRESH_BINARY);
|
||||||
|
cv::threshold(pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), pDib(cv::Rect(0, pDib.rows - halfSize, pDib.cols, halfSize)), m_threshold, 255, cv::THRESH_BINARY);
|
||||||
|
cv::Mat mask = pDib.clone();
|
||||||
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
std::vector<cv::Vec4i> h;
|
||||||
|
hg::findContours(mask, contours, h);
|
||||||
|
mask.release();
|
||||||
|
|
||||||
|
for (const std::vector<cv::Point>& contour : contours)
|
||||||
|
if (contourArea(contour) < 6)
|
||||||
|
fillConvexPoly(pDib, contour, cv::Scalar(255));
|
||||||
|
//FileTools::write_log("E:\\Users\\huago\\Desktop\\2.txt", "THRESH_BINARY eplsed: " + std::to_string(sw.elapsed_ms()));
|
||||||
|
//cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case ThresholdType::THRESH_OTSU:
|
case ThresholdType::THRESH_OTSU:
|
||||||
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
cv::threshold(pDib, pDib, m_threshold, 255, CV_THRESH_OTSU);
|
||||||
break;
|
break;
|
||||||
|
@ -72,16 +493,14 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib,int side)
|
||||||
|
|
||||||
void CImageApplyBWBinaray::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
void CImageApplyBWBinaray::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||||
{
|
{
|
||||||
if (mats.empty()) return;
|
(void)isTwoSide;
|
||||||
|
int i = 0;
|
||||||
if (!mats[0].empty()) {
|
for (cv::Mat& var : mats) {
|
||||||
apply(mats[0], 0);
|
if (i != 0 && isTwoSide == false)
|
||||||
}
|
break;
|
||||||
|
if (!var.empty())
|
||||||
|
apply(var, 0);
|
||||||
if (isTwoSide && mats.size() > 1) {
|
i++;
|
||||||
if (!mats[1].empty())
|
|
||||||
apply(mats[1], 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,79 @@
|
||||||
|
//#ifndef IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
//#define IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
//
|
||||||
|
//#include "ImageApply.h"
|
||||||
|
//
|
||||||
|
//class CImageApplyBWBinaray:public CImageApply
|
||||||
|
//{
|
||||||
|
//public:
|
||||||
|
//
|
||||||
|
// enum class ThresholdType
|
||||||
|
// {
|
||||||
|
// THRESH_BINARY = 0,
|
||||||
|
// THRESH_OTSU,
|
||||||
|
//
|
||||||
|
// ADAPTIVE_GAUSSIAN,
|
||||||
|
// ADAPTIVE_MEAN,
|
||||||
|
//
|
||||||
|
// ERROR_DIFFUSION
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// CImageApplyBWBinaray(ThresholdType type, int threshold = 180, int blockSize = 25, int constant = 5);
|
||||||
|
//
|
||||||
|
// CImageApplyBWBinaray();
|
||||||
|
//
|
||||||
|
// virtual ~CImageApplyBWBinaray(void);
|
||||||
|
//
|
||||||
|
// virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
//
|
||||||
|
// virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||||
|
//
|
||||||
|
// double getThreshold() { return m_threshold; }
|
||||||
|
//
|
||||||
|
// ThresholdType getThresholdType() { return m_type; }
|
||||||
|
//
|
||||||
|
// int getBlockSize() { return m_blockSize; }
|
||||||
|
//
|
||||||
|
// double getConstant() { return m_constant; }
|
||||||
|
//
|
||||||
|
// void setThreshold(double value) { m_threshold = value; }
|
||||||
|
//
|
||||||
|
// void setThresholdType(ThresholdType type) { m_type = type; }
|
||||||
|
//
|
||||||
|
// void setBlockSize(int value) { m_blockSize = value; }
|
||||||
|
//
|
||||||
|
// void setConstant(double value) { m_constant = value; }
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
//
|
||||||
|
// void errorDiffuse(cv::Mat& image);
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
// double m_threshold;
|
||||||
|
//
|
||||||
|
// ThresholdType m_type;
|
||||||
|
//
|
||||||
|
// int m_blockSize;
|
||||||
|
//
|
||||||
|
// double m_constant;
|
||||||
|
//
|
||||||
|
// uchar* m_table;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#endif //!IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
//
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
|
||||||
|
* 功能:二值化处理
|
||||||
|
* 作者:刘丁维
|
||||||
|
* 生成时间:2020/4/21
|
||||||
|
* 最近修改时间:2020/4/21
|
||||||
|
* 版本号:v1.0
|
||||||
|
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef IMAGE_APPLY_BW_BINARAY_H
|
#ifndef IMAGE_APPLY_BW_BINARAY_H
|
||||||
#define IMAGE_APPLY_BW_BINARAY_H
|
#define IMAGE_APPLY_BW_BINARAY_H
|
||||||
|
|
||||||
|
@ -9,16 +85,22 @@ public:
|
||||||
|
|
||||||
enum class ThresholdType
|
enum class ThresholdType
|
||||||
{
|
{
|
||||||
THRESH_BINARY = 0,
|
THRESH_BINARY = 0, //传统二值化
|
||||||
THRESH_OTSU,
|
THRESH_OTSU, //大津阈值
|
||||||
|
|
||||||
ADAPTIVE_GAUSSIAN,
|
ADAPTIVE_GAUSSIAN, //高斯局部自适应阈值
|
||||||
ADAPTIVE_MEAN,
|
ADAPTIVE_MEAN, //均值局部自适应阈值
|
||||||
|
|
||||||
ERROR_DIFFUSION
|
ERROR_DIFFUSION //错误扩散
|
||||||
};
|
};
|
||||||
|
|
||||||
CImageApplyBWBinaray(ThresholdType type, int threshold = 180, int blockSize = 25, int constant = 5);
|
/*
|
||||||
|
* type [in]:二值化模式
|
||||||
|
* threshold [in]:阈值,当选择THRESH_OTSU时无效
|
||||||
|
* blockSize [in]:ADAPTIVE_GAUSSIAN和ADAPTIVE_MEAN模式有效,表示局部观察块的宽度
|
||||||
|
* constant [in]:ADAPTIVE_GAUSSIAN和ADAPTIVE_MEAN模式有效,与blockSize形成比例关系,作为局部筛选阈值
|
||||||
|
*/
|
||||||
|
CImageApplyBWBinaray(ThresholdType type, int threshold = 120, int blockSize = 25, int constant = 5);
|
||||||
|
|
||||||
CImageApplyBWBinaray();
|
CImageApplyBWBinaray();
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,21 @@
|
||||||
#include "ImageApplyChannel.h"
|
#include "ImageApplyChannel.h"
|
||||||
|
//#include "ImageApplyAdjustColors.h"
|
||||||
CImageApplyChannel::CImageApplyChannel()
|
CImageApplyChannel::CImageApplyChannel()
|
||||||
: m_channel(Invalid)
|
: m_channel(Invalid)
|
||||||
|
//, colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CImageApplyChannel::CImageApplyChannel(Channel channel)
|
CImageApplyChannel::CImageApplyChannel(Channel channel)
|
||||||
: m_channel(channel)
|
: m_channel(channel)
|
||||||
|
//,colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CImageApplyChannel::~CImageApplyChannel(void)
|
CImageApplyChannel::~CImageApplyChannel(void)
|
||||||
{
|
{
|
||||||
|
//if (colors != NULL)
|
||||||
|
//delete colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CImageApplyChannel::apply(cv::Mat& pDib,int side)
|
void CImageApplyChannel::apply(cv::Mat& pDib,int side)
|
||||||
|
@ -33,6 +37,7 @@ void CImageApplyChannel::apply(cv::Mat& pDib,int side)
|
||||||
{
|
{
|
||||||
case Red:
|
case Red:
|
||||||
cv::extractChannel(pDib, dst, 2);
|
cv::extractChannel(pDib, dst, 2);
|
||||||
|
//colors->apply(pDib, side);
|
||||||
break;
|
break;
|
||||||
case Green:
|
case Green:
|
||||||
cv::extractChannel(pDib, dst, 1);
|
cv::extractChannel(pDib, dst, 1);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define IMAGE_APPLY_CHANNEL_H
|
#define IMAGE_APPLY_CHANNEL_H
|
||||||
|
|
||||||
#include "imageapply.h"
|
#include "imageapply.h"
|
||||||
|
//class CImageApplyAdjustColors;
|
||||||
class CImageApplyChannel : public CImageApply
|
class CImageApplyChannel : public CImageApply
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,6 +37,7 @@ private:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Channel m_channel;
|
Channel m_channel;
|
||||||
|
//CImageApplyAdjustColors* colors;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !IMAGE_APPLY_CHANNEL_H
|
#endif // !IMAGE_APPLY_CHANNEL_H
|
Loading…
Reference in New Issue