#include "StdAfx.h" #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(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(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); 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& mats, bool isTwoSide) { if (mats.empty()) return; apply(mats[0], 0); if (isTwoSide && mats.size() > 1) 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(image.rows) - 1; size_t cols = static_cast(image.cols) - 1; short** pixels_dst = new short*[static_cast(image.rows)]; for (int i = 0; i < image.rows; i++) pixels_dst[i] = reinterpret_cast(dst.data + i * static_cast(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; }