mirror of http://192.168.1.51:8099/lmh188/twain3.0
parent
d6b74c6807
commit
cc07cedfbf
|
@ -1,366 +1,5 @@
|
||||||
//#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 "ImageApplyDetachNoise.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)
|
||||||
|
@ -374,7 +13,7 @@ CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, in
|
||||||
}
|
}
|
||||||
|
|
||||||
CImageApplyBWBinaray::CImageApplyBWBinaray()
|
CImageApplyBWBinaray::CImageApplyBWBinaray()
|
||||||
: m_threshold(160)
|
: m_threshold(120)
|
||||||
, m_type(ThresholdType::THRESH_BINARY)
|
, m_type(ThresholdType::THRESH_BINARY)
|
||||||
, m_blockSize(25)
|
, m_blockSize(25)
|
||||||
, m_constant(5)
|
, m_constant(5)
|
||||||
|
@ -384,7 +23,6 @@ CImageApplyBWBinaray::CImageApplyBWBinaray()
|
||||||
memset(m_table, 0, static_cast<size_t>(m_threshold));
|
memset(m_table, 0, static_cast<size_t>(m_threshold));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
|
||||||
{
|
{
|
||||||
delete[] m_table;
|
delete[] m_table;
|
||||||
|
@ -398,42 +36,19 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
||||||
if (pDib.channels() == 3)
|
if (pDib.channels() == 3)
|
||||||
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
|
||||||
|
|
||||||
switch (m_type)
|
|
||||||
{
|
|
||||||
case ThresholdType::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::Mat integ;
|
||||||
cv::integral(pDib, integ, CV_32S);
|
|
||||||
|
|
||||||
int blockSize = 31;//ÁÚÓò³ß´ç
|
int blockSize = 31;//ÁÚÓò³ß´ç
|
||||||
int threshold = 21;
|
int threshold = 21;
|
||||||
int low = 110;
|
int low = 110;
|
||||||
int up = 220;
|
int up = 220;
|
||||||
int halfSize = blockSize / 2;
|
int halfSize = blockSize / 2;
|
||||||
int square_block = blockSize * blockSize;
|
int square_blockSize = blockSize * blockSize;
|
||||||
|
CImageApplyDetachNoise noise(6);
|
||||||
|
switch (m_type)
|
||||||
|
{
|
||||||
|
case ThresholdType::THRESH_BINARY:
|
||||||
|
cv::integral(pDib, integ, CV_32S);
|
||||||
|
|
||||||
for (int j = halfSize; j < integ.rows - halfSize - 1; j++)
|
for (int j = halfSize; j < integ.rows - halfSize - 1; j++)
|
||||||
{
|
{
|
||||||
uchar* data = pDib.ptr<uchar>(j);
|
uchar* data = pDib.ptr<uchar>(j);
|
||||||
|
@ -441,35 +56,19 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
|
||||||
int* idata2 = integ.ptr<int>(j + halfSize + 1);
|
int* idata2 = integ.ptr<int>(j + halfSize + 1);
|
||||||
for (int i = halfSize; i < integ.cols - halfSize - 1; i++)
|
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;
|
if (data[i] < low) data[i] = 0;
|
||||||
else if (data[i] > up) data[i] = 255;
|
else if (data[i] > up) data[i] = 255;
|
||||||
else
|
else
|
||||||
{
|
data[i] = data[i] < ((idata2[i + halfSize + 1] - idata2[i - halfSize] - idata1[i + halfSize + 1] + idata1[i - halfSize]) / square_blockSize - threshold) ? 0 : 255;
|
||||||
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(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(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, 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::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();
|
noise.apply(pDib, side);
|
||||||
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;
|
||||||
|
@ -538,9 +137,9 @@ void CImageApplyBWBinaray::errorDiffuse(cv::Mat& image)
|
||||||
error = dstPix;
|
error = dstPix;
|
||||||
}
|
}
|
||||||
|
|
||||||
pixels_dst[y][x + 1] += error * 7 / 16;
|
pixels_dst[y][x + 1] += error * 1 / 16;
|
||||||
pixels_dst[y + 1][x - 1] += error * 3 / 16;
|
pixels_dst[y + 1][x - 1] += error * 1 / 16;
|
||||||
pixels_dst[y + 1][x] += error * 5 / 16;
|
pixels_dst[y + 1][x] += error * 1 / 16;
|
||||||
pixels_dst[y + 1][x + 1] += error * 1 / 16;
|
pixels_dst[y + 1][x + 1] += error * 1 / 16;
|
||||||
}
|
}
|
||||||
image.release();
|
image.release();
|
||||||
|
|
|
@ -1,75 +1,13 @@
|
||||||
//#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
|
||||||
* 最近修改时间:2020/4/21
|
* 最近修改时间:2020/5/28 v1.1 修改传统二值化算法,改用自定义局部自适应阈值算法
|
||||||
* 版本号:v1.0
|
2020/5/29 v1.2 在传统二值化之前添加增强锐化效果,二值化之后增加除噪效果
|
||||||
|
2020/6/19 v1.3 编写自定义自适应阈值二值化;取消锐化处理;保留除噪效果
|
||||||
|
* 版本号:v1.3
|
||||||
|
|
||||||
* ====================================================
|
* ====================================================
|
||||||
*/
|
*/
|
||||||
|
@ -79,26 +17,26 @@
|
||||||
|
|
||||||
#include "ImageApply.h"
|
#include "ImageApply.h"
|
||||||
|
|
||||||
class CImageApplyBWBinaray :public CImageApply
|
class CImageApplyBWBinaray:public CImageApply
|
||||||
{
|
{
|
||||||
public:
|
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 //错误扩散
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* type [in]:二值化模式
|
* type [in]:二值化模式
|
||||||
* threshold [in]:阈值,当选择THRESH_OTSU时无效
|
* threshold [in]:阈值,当选择THRESH_OTSU时无效
|
||||||
* blockSize [in]:ADAPTIVE_GAUSSIAN和ADAPTIVE_MEAN模式有效,表示局部观察块的宽度
|
* blockSize [in]:ADAPTIVE_GAUSSIAN和ADAPTIVE_MEAN模式有效,表示局部观察块的宽度
|
||||||
* constant [in]:ADAPTIVE_GAUSSIAN和ADAPTIVE_MEAN模式有效,与blockSize形成比例关系,作为局部筛选阈值
|
* constant [in]:ADAPTIVE_GAUSSIAN和ADAPTIVE_MEAN模式有效,与blockSize形成比例关系,作为局部筛选阈值
|
||||||
*/
|
*/
|
||||||
CImageApplyBWBinaray(ThresholdType type, int threshold = 120, int blockSize = 25, int constant = 5);
|
CImageApplyBWBinaray(ThresholdType type, int threshold = 120, int blockSize = 25, int constant = 5);
|
||||||
|
|
||||||
|
@ -106,7 +44,7 @@ public:
|
||||||
|
|
||||||
virtual ~CImageApplyBWBinaray(void);
|
virtual ~CImageApplyBWBinaray(void);
|
||||||
|
|
||||||
virtual void apply(cv::Mat& pDib, int side);
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
|
||||||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
#include "ImageApplyDetachNoise.h"
|
||||||
|
#include "ImageProcess_Public.h"
|
||||||
|
|
||||||
|
CImageApplyDetachNoise::CImageApplyDetachNoise(int noise)
|
||||||
|
: m_noise(noise)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageApplyDetachNoise::~CImageApplyDetachNoise(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyDetachNoise::apply(cv::Mat& pDib, int side)
|
||||||
|
{
|
||||||
|
(void)side;
|
||||||
|
if (pDib.empty()||pDib.channels() != 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cv::Mat mask;
|
||||||
|
cv::threshold(pDib, mask, 127, 255, cv::THRESH_BINARY_INV);
|
||||||
|
|
||||||
|
std::vector<std::vector<cv::Point>> contours;
|
||||||
|
std::vector<cv::Vec4i> h;
|
||||||
|
hg::findContours(mask, contours, h);
|
||||||
|
|
||||||
|
for (const std::vector<cv::Point>& contour : contours)
|
||||||
|
if (contourArea(contour) < m_noise)
|
||||||
|
fillConvexPoly(pDib, contour, cv::Scalar(255));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyDetachNoise::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++;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
|
||||||
|
* 功能:除噪,消除3*3以内的像素点,主要针对黑白图
|
||||||
|
* 作者:刘丁维
|
||||||
|
* 生成时间:2020/4/21
|
||||||
|
* 最近修改时间:2020/4/21 v1.0
|
||||||
|
2020/5/29 v1.1 增加接口,使噪点大小阈值可调
|
||||||
|
* 版本号:v1.1
|
||||||
|
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IMAGE_APPLY_DETACH_NOISE_H
|
||||||
|
#define IMAGE_APPLY_DETACH_NOISE_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class CImageApplyDetachNoise : public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CImageApplyDetachNoise(int noise = 4);
|
||||||
|
|
||||||
|
inline int getNoise() { return m_noise; }
|
||||||
|
|
||||||
|
inline void setNoise(int noise) { m_noise = noise; }
|
||||||
|
|
||||||
|
virtual ~CImageApplyDetachNoise(void);
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib, int side);
|
||||||
|
|
||||||
|
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_noise;
|
||||||
|
};
|
||||||
|
#endif // !IMAGE_APPLY_DETACH_NOISE_H
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
#include "ImageApplyHSVCorrect.h"
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
|
CImageApplyHSVCorrect::CImageApplyHSVCorrect()
|
||||||
|
: m_table(new uint[256 * 256 * 256])
|
||||||
|
{
|
||||||
|
initLUT();
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode)
|
||||||
|
: m_table(new uint[256 * 256 * 256])
|
||||||
|
{
|
||||||
|
initLUT();
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case CImageApplyHSVCorrect::Red_Removal:
|
||||||
|
set_HSV_value(std::pair<uchar, uchar>(0, 63), std::pair<uchar, uchar>(20, 255), std::pair<uchar, uchar>(160, 255), 0x00FFFFFF);
|
||||||
|
set_HSV_value(std::pair<uchar, uchar>(191, 255), std::pair<uchar, uchar>(20, 255), std::pair<uchar, uchar>(160, 255), 0x00FFFFFF);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CImageApplyHSVCorrect::~CImageApplyHSVCorrect()
|
||||||
|
{
|
||||||
|
delete [] m_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyHSVCorrect::apply(cv::Mat &pDib, int side)
|
||||||
|
{
|
||||||
|
(void)side;
|
||||||
|
if (pDib.empty() || pDib.channels() != 3) return;
|
||||||
|
|
||||||
|
uchar* src = pDib.data;
|
||||||
|
cv::Mat z = cv::Mat::zeros(pDib.size(), CV_8UC3);
|
||||||
|
uchar* dst = z.data;
|
||||||
|
|
||||||
|
int total = pDib.total();
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (int i = 0; i < total; i++)
|
||||||
|
{
|
||||||
|
int offset = i * 3;
|
||||||
|
int index = *reinterpret_cast<uint*>(src + offset) & 0x00ffffff;
|
||||||
|
uint color = m_table[index];
|
||||||
|
*reinterpret_cast<uint*>(dst + offset) |= color;
|
||||||
|
}
|
||||||
|
pDib = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyHSVCorrect::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 CImageApplyHSVCorrect::initLUT()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
uchar h, s, v;
|
||||||
|
#endif
|
||||||
|
for (uint b = 0; b < 256; b++)
|
||||||
|
for (uint g = 0; g < 256; g++)
|
||||||
|
for (uint r = 0; r < 256; r++)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
RGB_2_HSV_full(r, g, b, h, s, v);
|
||||||
|
|
||||||
|
uint index = b | (g << 8) | (r << 16);
|
||||||
|
if (h < 12 || h > 245)
|
||||||
|
m_table[index] = index & 0x00ffffff;
|
||||||
|
else
|
||||||
|
m_table[index] = (v | (v << 8) | (v << 16)) & 0x00ffffff;
|
||||||
|
#else
|
||||||
|
m_table[b | (g << 8) | (r << 16)] = b | (g << 8) | (r << 16);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyHSVCorrect::set_single(const uint src_b, const uint src_g, const uint src_r,
|
||||||
|
const uint dst_b, const uint dst_g, const uint dst_r)
|
||||||
|
{
|
||||||
|
m_table[src_b | (src_g << 8) | (src_r << 16)] = dst_b | (dst_g << 8) | (dst_r << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyHSVCorrect::set_HSV_value(const std::pair<uchar, uchar>& range_h,
|
||||||
|
const std::pair<uchar, uchar>& range_s,
|
||||||
|
const std::pair<uchar, uchar>& range_v,
|
||||||
|
uint bgr)
|
||||||
|
{
|
||||||
|
uchar h, s, v;
|
||||||
|
for (int b = 0; b < 256; b++)
|
||||||
|
for (int g = 0; g < 256; g++)
|
||||||
|
for (int r = 0; r < 256; r++)
|
||||||
|
{
|
||||||
|
RGB_2_HSV_full(r, g, b, h, s, v);
|
||||||
|
if (contained(h, range_h) && contained(s, range_s) && contained(v, range_v))
|
||||||
|
m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = bgr & 0x00ffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyHSVCorrect::set_table(const uint* table)
|
||||||
|
{
|
||||||
|
memcpy(m_table, table, 256 * 256 * 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CImageApplyHSVCorrect::contained(uchar value, const std::pair<uchar, uchar> &range)
|
||||||
|
{
|
||||||
|
return value >= range.first && value <= range.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CImageApplyHSVCorrect::RGB_2_HSV_full(int r, int g, int b, uchar& h, uchar& s, uchar& v)
|
||||||
|
{
|
||||||
|
int minn = cv::min(r, cv::min(g, b));
|
||||||
|
int maxx = cv::max(r, cv::max(g, b));
|
||||||
|
v = static_cast<uchar>(maxx); //V
|
||||||
|
|
||||||
|
int delta = maxx - minn;
|
||||||
|
float _h;
|
||||||
|
if (maxx == 0)
|
||||||
|
{
|
||||||
|
h = s = v = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
s = static_cast<uchar>(delta * 255 / maxx);
|
||||||
|
|
||||||
|
if (r == maxx)
|
||||||
|
_h = static_cast<float>(g - b) / static_cast<float>(delta);
|
||||||
|
else if (g == maxx)
|
||||||
|
_h = 2 + static_cast<float>(b - r) / static_cast<float>(delta);
|
||||||
|
else
|
||||||
|
_h = 4 + static_cast<float>(r - g) / static_cast<float>(delta);
|
||||||
|
|
||||||
|
float __h = _h * 42.6666666667f;
|
||||||
|
h = (__h >= 0) ? static_cast<uchar>(__h) : static_cast<uchar>(__h + 256);
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* ====================================================
|
||||||
|
|
||||||
|
* 功能:彩色图像,色彩校正。基于LUT实现,预设BGR查值表(表达所有HVS),对BGR原图进行查值校正。
|
||||||
|
* 作者:刘丁维
|
||||||
|
* 生成时间:2020/3/21
|
||||||
|
* 最近修改时间:v1.0 2020/3/21
|
||||||
|
v1.1 2020/6/15 调整除红效果的HSV取值范围
|
||||||
|
* 版本号:v1.1
|
||||||
|
|
||||||
|
* ====================================================
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef IMAGE_APPLY_COLOR_CORRECT_H
|
||||||
|
#define IMAGE_APPLY_COLOR_CORRECT_H
|
||||||
|
|
||||||
|
#include "ImageApply.h"
|
||||||
|
|
||||||
|
class CImageApplyHSVCorrect : public CImageApply
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum CorrectOption
|
||||||
|
{
|
||||||
|
Red_Removal //除掉红色。红色定义H:[0, 85]∪[170, 255],S:[10, 255],V:[120,255]
|
||||||
|
};
|
||||||
|
public:
|
||||||
|
|
||||||
|
CImageApplyHSVCorrect();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mode [in]:预设初色模式
|
||||||
|
*/
|
||||||
|
CImageApplyHSVCorrect(CorrectOption mode);
|
||||||
|
|
||||||
|
virtual ~CImageApplyHSVCorrect();
|
||||||
|
|
||||||
|
virtual void apply(cv::Mat& pDib,int side);
|
||||||
|
|
||||||
|
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 函数功能:初始化查值表,按照RGB(R在高位,B在低位)的32位数据进行索引,值与索引一致。
|
||||||
|
表中索引范围[0,0x00FFFFFF]。在构造函数中会默认调用该函数。
|
||||||
|
*/
|
||||||
|
void initLUT();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 函数功能:将查值表指定RGB索引值设置为目标值。
|
||||||
|
索引 = src_b | (src_g << 8) | (src_r << 16)
|
||||||
|
值 = dst_b | (dst_g << 8) | (dst_r << 16)
|
||||||
|
* src_b:[in] 原查值表B通道索引
|
||||||
|
* src_g:[in] 原查值表G通道索引
|
||||||
|
* src_r:[in] 原查值表R通道索引
|
||||||
|
* dst_b:[in] 目标查值表B通道值
|
||||||
|
* dst_g:[in] 目标查值表G通道值
|
||||||
|
* dst_r:[in] 目标查值表R通道值
|
||||||
|
*/
|
||||||
|
void set_single(const uint src_b, const uint src_g, const uint src_r,
|
||||||
|
const uint dst_b, const uint dst_g, const uint dst_r);
|
||||||
|
/*
|
||||||
|
* 函数功能:按照HSV色彩空间描述色彩范围,将该范围对应的BGR索引设置为0x00FFFFFF(默认白色)
|
||||||
|
* range_h:[in] H分量范围,取值范围[0, 255]
|
||||||
|
* range_s:[in] S分量范围,取值范围[0, 255]
|
||||||
|
* range_v:[in] V分量范围,取值范围[0, 255]
|
||||||
|
* bgr:[in] 用uint表示BGR值,B在低位,R在高位
|
||||||
|
*/
|
||||||
|
void set_HSV_value(const std::pair<uchar, uchar>& range_h,
|
||||||
|
const std::pair<uchar, uchar>& range_s,
|
||||||
|
const std::pair<uchar, uchar>& range_v,
|
||||||
|
uint bgr = 0x00FFFFFF);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 函数功能:设置外部查值表,表默认长度为 256 * 256 * 256 * sizeof(uint)
|
||||||
|
* table:[in] 数组指针
|
||||||
|
*/
|
||||||
|
void set_table(const uint* table);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool contained(uchar value, const std::pair<uchar, uchar>& range);
|
||||||
|
|
||||||
|
static void RGB_2_HSV_full(int r, int g, int b, uchar& h, uchar& s, uchar& v);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint* m_table;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -13,5 +13,6 @@
|
||||||
#include "ImageApplyRotation.h"
|
#include "ImageApplyRotation.h"
|
||||||
#include "ImageApplySharpen.h"
|
#include "ImageApplySharpen.h"
|
||||||
#include "ImageApplyConcatenation.h"
|
#include "ImageApplyConcatenation.h"
|
||||||
|
#include "ImageApplyHSVCorrect.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue