算法更新

This commit is contained in:
13038267101 2022-07-29 16:41:34 +08:00
parent 53174686f7
commit 186a2c3165
270 changed files with 28362 additions and 4901 deletions

View File

@ -3,7 +3,7 @@
#include <vector>
#include "imgprocdefs.h"
class IMulti
class GIMGPROC_LIBRARY_API IMulti
{
public:
IMulti(void);

View File

@ -1,11 +1,24 @@
#ifndef IMAGE_APPLY_H
/*
* ====================================================
*
*
* 2020/4/21
* 2020/4/21
* v1.0
* ====================================================
*/
#ifndef IMAGE_APPLY_H
#define IMAGE_APPLY_H
#include <vector>
#include <memory>
#include <vector>
#include <opencv2/opencv.hpp>
#include "imgprocdefs.h"
class CImageApply
class GIMGPROC_LIBRARY_API CImageApply
{
public:
CImageApply(void);

View File

@ -71,8 +71,8 @@ void CImageApplyAdjustColors::setGamma(float gamma)
void CImageApplyAdjustColors::update_lutData()
{
unsigned char* ptr = lut.data;
//update gamma
uchar buffer[256];
for (int i = 0; i < 256; i++)
{
//update brightness

View File

@ -1,18 +1,30 @@
/*
* ====================================================
* > >
*
* 2020/4/21
* 2020/4/21
* v1.0
* ====================================================
*/
#ifndef IMAGE_APPLY_ADJUST_COLOR_H
#define IMAGE_APPLY_ADJUST_COLOR_H
#include "ImageApply.h"
class CImageApplyAdjustColors : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyAdjustColors : public CImageApply
{
public:
CImageApplyAdjustColors(void);
/*
* brightness [in]: [-255, 255]
* constrast [in]: [-128 127]
* gamma [in]: [0.1, 5.0]
* brightness [in]: [-255, 255]
* constrast [in]: [-128 127]
* gamma [in]: [0.1, 5.0]
*/
CImageApplyAdjustColors(int brightness, int contrast, float gamma);

View File

@ -15,7 +15,7 @@
#include "ImageApply.h"
class CImageApplyAutoContrast : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyAutoContrast : public CImageApply
{
public:

View File

@ -1,5 +1,8 @@
#include "ImageApplyAutoCrop.h"
#include "ImageProcess_Public.h"
#include <iostream>
#include <opencv2/imgproc/hal/hal.hpp>
#include "ImageApplyDispersion.h"
CImageApplyAutoCrop::CImageApplyAutoCrop()
: m_isCrop(false)
@ -11,11 +14,12 @@ CImageApplyAutoCrop::CImageApplyAutoCrop()
, m_noise(8)
, m_indent(5)
, m_normalCrop(false)
, m_isDispersion(true)
{
}
CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex, bool isFillColor,
double threshold, int noise, int indent, bool normalCrop)
double threshold, int noise, int indent, bool normalCrop, bool dispersion)
: m_isCrop(isCrop)
, m_isDesaskew(isDesaskew)
, m_isFillBlank(isFillBlank)
@ -26,6 +30,7 @@ CImageApplyAutoCrop::CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFi
, m_indent(indent)
, m_fixedSize(fixedSize)
, m_normalCrop(normalCrop)
, m_isDispersion(dispersion)
{
}
@ -33,327 +38,63 @@ CImageApplyAutoCrop::~CImageApplyAutoCrop()
{
}
void matmul(double* mul1, double* mul2, double* dst)
{
dst[0] = mul1[0] * mul2[0] + mul1[1] * mul2[3] + mul1[2] * mul2[6];
dst[1] = mul1[0] * mul2[1] + mul1[1] * mul2[4] + mul1[2] * mul2[7];
dst[2] = mul1[0] * mul2[2] + mul1[1] * mul2[5] + mul1[2] * mul2[8];
dst[3] = mul1[3] * mul2[0] + mul1[4] * mul2[3] + mul1[5] * mul2[6];
dst[4] = mul1[3] * mul2[1] + mul1[4] * mul2[4] + mul1[5] * mul2[7];
dst[5] = mul1[3] * mul2[2] + mul1[4] * mul2[5] + mul1[5] * mul2[8];
dst[6] = mul1[6] * mul2[0] + mul1[7] * mul2[3] + mul1[8] * mul2[6];
dst[7] = mul1[6] * mul2[1] + mul1[7] * mul2[4] + mul1[8] * mul2[7];
dst[8] = mul1[6] * mul2[2] + mul1[7] * mul2[5] + mul1[8] * mul2[8];
}
cv::Mat concatenateMatrix(const cv::Mat& first, const cv::Mat& second)
{
double buffer1[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1} ;
double buffer2[] = { 1, 0, 0, 0, 1, 0, 0, 0, 1} ;
cv::Mat mul1(3, 3, CV_64FC1, buffer1); //cv::Mat::eye(3, 3, CV_64F);
cv::Mat mul2(3, 3, CV_64FC1, buffer2); //cv::Mat::eye(3, 3, CV_64F);
cv::Mat mul_r;
first.convertTo(mul_r, CV_64F);
mul_r.row(0).copyTo(mul1.row(0));
mul_r.row(1).copyTo(mul1.row(1));
second.convertTo(mul_r, CV_64F);
mul_r.row(0).copyTo(mul2.row(0));
mul_r.row(1).copyTo(mul2.row(1));
//mul1 = mul2 * mul1;
cv::Mat temp(3, 3, CV_64FC1);
matmul(buffer2, buffer1, (double*)temp.data);
mul1 = temp;
mul_r = first.clone();
mul1.row(0).copyTo(mul_r.row(0));
mul1.row(1).copyTo(mul_r.row(1));
return mul_r;
}
std::vector<cv::Mat> comMat()
{
std::vector<cv::Mat> mats;
cv::Point2f srcTri[3];
srcTri[0] = cv::Point2f(1, 1);
srcTri[1] = cv::Point2f(1, 0);
srcTri[2] = cv::Point2f(0, 1);
const float fact = 0.33f;
float pos[] = { 0, 2 * fact, fact };
cv::Point2f dstTri[3];
dstTri[0] = cv::Point2f(1, 1);
dstTri[1] = cv::Point2f(1, 0.5);
dstTri[2] = cv::Point2f(0, 1);
for (int i = 0; i < 3; i++)
{
dstTri[0] = cv::Point2f(1, 1 + pos[i]);
dstTri[1] = cv::Point2f(1, pos[i]);
dstTri[2] = cv::Point2f(0, 1 + pos[i]);
mats.push_back(cv::getAffineTransform(srcTri, dstTri));
}
return mats;
}
void brightSharp(cv::Mat& src)
{
const float a = -0.49f;
const float b = 3.0f;
//float kernel_data[] = {
// a, 0, 0, 0, a,
// 0, 0, a, 0, 0,
// 0, a, b, a, 0,
// 0, 0, a, 0, 0,
// a, 0, 0, 0, a };
float kernel_data[] = {
0, a, 0,
a, b, a,
0, a, 0
};
cv::Mat kernel(3, 3, CV_32FC1, kernel_data);
cv::filter2D(src, src, src.depth(), kernel);
}
void CImageApplyAutoCrop::apply(cv::Mat& pDib, int side)
{
(void)side;
if (pDib.empty()) return;
if (m_normalCrop)
{
cv::Rect roi = cv::Rect((pDib.cols - m_fixedSize.width) / 2, side == 0 ? 75 : 145, m_fixedSize.width, m_fixedSize.height) & cv::Rect(0, 0, pDib.cols, pDib.rows);
pDib = pDib(roi).clone();
m_rect = cv::RotatedRect(cv::Point2f(roi.x + roi.width / 2, roi.y + roi.height / 2), cv::Size2f(roi.width, roi.height), 0.0f);
return;
}
if (!m_isCrop && !m_isDesaskew && !m_isFillBlank && m_fixedSize.empty()) return;
cv::Mat src = pDib;
cv::Mat thre;
cv::Mat dst;
hg::threshold_Mat(src, thre, m_threshold);
if (m_noise > 0)
{
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(m_noise, 1));
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element);
}
if (m_indent > 0)
{
cv::Mat element = getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(m_indent, m_indent));
cv::morphologyEx(thre, thre, cv::MORPH_ERODE, element);
}
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
m_maxContour = hg::getMaxContour(contours, hierarchy);
if (m_maxContour.size() == 0)
{
thre.release();
//
if (!m_isCrop)
pDib = pDib(cv::Rect((pDib.cols - m_fixedSize.width) / 2, (pDib.rows - m_fixedSize.height) / 2, m_fixedSize.width, m_fixedSize.height) & cv::Rect(0, 0, pDib.cols, pDib.rows)).clone();
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply");
#endif // LOG
return;
}
thre.release();
dst.release();
cv::RotatedRect rect = hg::getBoundingRect(m_maxContour);
m_rect = rect;
cv::Rect boudingRect = cv::boundingRect(m_maxContour);
boudingRect.x -= 1;
boudingRect.y -= 1;
boudingRect.width += 2;
boudingRect.height += 2;
if (m_isDesaskew && rect.angle != 0)
{
cv::Point2f srcTri[4], srcTri_temp[3], dstTri[3];
rect.points(srcTri);
dstTri[0] = cv::Point2f(0, rect.size.height - 1);
dstTri[1] = cv::Point2f(0, 0);
dstTri[2] = cv::Point2f(rect.size.width - 1, 0);
srcTri_temp[0] = dstTri[0];
srcTri_temp[1] = dstTri[1];
srcTri_temp[2] = dstTri[2];
cv::Mat warp_mat;
warp_mat = cv::getAffineTransform(srcTri, dstTri);
if (src.channels() == 1)
{
cv::warpAffine(src, dst, warp_mat, rect.size, cv::INTER_LINEAR);
}
else
{
cv::Mat bgr[3];
cv::split(src, bgr);
auto mats = comMat();
warp_mat = cv::getAffineTransform(srcTri, dstTri);
warp_mat = concatenateMatrix(mats[0], warp_mat);
cv::warpAffine(bgr[0], bgr[0], warp_mat, rect.size, cv::INTER_LINEAR);
warp_mat = cv::getAffineTransform(srcTri, dstTri);
warp_mat = concatenateMatrix(mats[1], warp_mat);
cv::warpAffine(bgr[1], bgr[1], warp_mat, rect.size, cv::INTER_LINEAR);
warp_mat = cv::getAffineTransform(srcTri, dstTri);
warp_mat = concatenateMatrix(mats[2], warp_mat);
cv::warpAffine(bgr[2], bgr[2], warp_mat, rect.size, cv::INTER_LINEAR);
cv::merge(bgr, 3, dst);
}
double* ptr_m = reinterpret_cast<double*>(warp_mat.data);
double a = ptr_m[0];
double b = ptr_m[1];
double c = ptr_m[2];
double d = ptr_m[3];
double e = ptr_m[4];
double f = ptr_m[5];
for (cv::Point& p : m_maxContour)
{
p.x = static_cast<int>(a * p.x + b * p.y + c);
p.y = static_cast<int>(d * p.x + e * p.y + f);
}
for (std::vector<cv::Point>& sub : contours)
for (cv::Point& p : sub)
{
p.x = static_cast<int>(a * p.x + b * p.y + c);
p.y = static_cast<int>(d * p.x + e * p.y + f);
}
}
else
{
auto t_rect = boudingRect & cv::Rect(0, 0, src.cols, src.rows);
dst = src(t_rect);
if (dst.channels() == 3)
{
cv::Mat bgr[3];
cv::split(dst, bgr);
auto mats = comMat();
for (int i = 0; i < 3; i++)
cv::warpAffine(bgr[i], bgr[i], mats[i], t_rect.size(), cv::INTER_LINEAR);
cv::merge(bgr, 3, dst);
}
}
cv::Scalar autoBGColor;
if (m_isFillBlank)
{
if (m_isConvexHull)
{
if (m_maxContour.size() == 0)
{
thre.release();
//<2F><><EFBFBD><EFBFBD>ǹ̶<C7B9><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ز<EFBFBD><D8B2>к<EFBFBD>ijߴ<C4B3>
if (!m_isCrop)
pDib = pDib(cv::Rect((pDib.cols - m_fixedSize.width) / 2, (pDib.rows - m_fixedSize.height) / 2, m_fixedSize.width, m_fixedSize.height) & cv::Rect(0, 0, pDib.cols, pDib.rows)).clone();
return;
}
hg::convexHull(m_maxContour, m_maxContour);
contours.clear();
contours.push_back(m_maxContour);
}
contours.push_back(std::vector<cv::Point>());
contours[contours.size() - 1].push_back(cv::Point(-1, dst.rows - 1));
contours[contours.size() - 1].push_back(cv::Point(-1, -1));
contours[contours.size() - 1].push_back(cv::Point(dst.cols, -1));
contours[contours.size() - 1].push_back(cv::Point(dst.cols, dst.rows));
autoBGColor = m_isFillColor ? getBackGroudColor(pDib, rect.size.area()) : cv::Scalar(255, 255, 255);
hg::fillPolys(dst, contours, autoBGColor);
}
else
{
m_maxContour.clear();
m_maxContour.push_back(cv::Point(-1, dst.rows));
m_maxContour.push_back(cv::Point(-1, -1));
m_maxContour.push_back(cv::Point(dst.cols, -1));
m_maxContour.push_back(cv::Point(dst.cols, dst.rows));
}
pDib.release();
if (/*(m_isCrop && side == 0) || (side == 1 && m_fixedSize.width * m_fixedSize.height == 0)*/ m_isCrop)
pDib = dst.clone();
else
{
pDib = cv::Mat(m_fixedSize, dst.type(), m_isFillBlank ? autoBGColor : cv::Scalar(0, 0, 0));
cv::Rect roi;
roi.x = dst.cols > pDib.cols ? (dst.cols - pDib.cols) / 2 : 0;
roi.width = cv::min(pDib.cols, dst.cols);
roi.y = dst.rows > pDib.rows ? (dst.rows - pDib.rows) / 2 : 0;
roi.height = cv::min(pDib.rows, dst.rows);
cv::Rect rect((pDib.cols - roi.width) / 2, (pDib.rows - roi.height) / 2, roi.width, roi.height);
for (cv::Point& p : m_maxContour)
p += roi.tl();
dst(roi).copyTo(pDib(rect));
}
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyAutoCrop apply8");
#endif // LOG
autoCrop_desaskew_fillBlank(pDib, dst, m_isCrop, m_isDesaskew, m_isFillBlank, m_fixedSize.width, m_fixedSize.height,
m_isConvexHull, m_isFillColor, m_threshold, m_noise, m_indent, m_normalCrop, m_isDispersion);
pDib = dst;
}
void CImageApplyAutoCrop::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
if (mats.empty()) return;
if (!mats[0].empty()) {
apply(mats[0], 0);
m_rects.push_back(m_rect);
//brightSharp(mats[0]);
(void)isTwoSide;
int i = 0;
for (cv::Mat& var : mats) {
if (i != 0 && isTwoSide == false)
break;
if (!var.empty())
apply(var, 0);
i++;
}
}
if (isTwoSide && mats.size() > 1)
#define FRONT_TOP 70
#define FX_FY 0.5f
void myWarpAffine(cv::InputArray _src, cv::OutputArray _dst, cv::InputArray _M0, cv::Size dsize, int flags, int borderType, const cv::Scalar& borderValue)
{
cv::Size dSize = m_fixedSize;
if (!mats[0].empty())
m_fixedSize = mats[0].size();
if (!mats[1].empty()) {
apply(mats[1], 1);
m_rects.push_back(m_rect);
//brightSharp(mats[1]);
}
int interpolation = flags;
cv::Mat src = _src.getMat(), M0 = _M0.getMat();
cv::Mat dst = _dst.getMat();
if (!mats[0].empty())
m_fixedSize = dSize;
}
}
if (dst.data == src.data)
src = src.clone();
cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int total)
double M[6] = { 0 };
cv::Mat matM(2, 3, CV_64F, M);
if (interpolation == cv::INTER_AREA)
interpolation = cv::INTER_LINEAR;
M0.convertTo(matM, matM.type());
if (!(flags & cv::WARP_INVERSE_MAP))
{
if (image.channels() == 3)
{
cv::Mat image_bgr[3];
cv::split(image, image_bgr);
uchar bgr[3];
for (size_t i = 0; i < 3; i++)
bgr[i] = getBackGroudChannelMean(image_bgr[i], total);
return cv::Scalar(bgr[0], bgr[1], bgr[2]);
}
else
return cv::Scalar::all(getBackGroudChannelMean(image, total));
double D = M[0] * M[4] - M[1] * M[3];
D = D != 0 ? 1. / D : 0;
double A11 = M[4] * D, A22 = M[0] * D;
M[0] = A11; M[1] *= -D;
M[3] *= -D; M[4] = A22;
double b1 = -M[0] * M[2] - M[1] * M[5];
double b2 = -M[3] * M[2] - M[4] * M[5];
M[2] = b1; M[5] = b2;
}
uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int total)
cv::hal::warpAffine(src.type(), src.data, src.step, src.cols, src.rows, dst.data, dst.step, dst.cols, dst.rows,
M, interpolation, borderType, borderValue.val);
}
uchar getBackGroudChannelMean(const cv::Mat& gray, int total, int threshold)
{
cv::Mat image_clone;
cv::resize(gray, image_clone, cv::Size(), 0.25, 0.25);
@ -371,10 +112,10 @@ uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int tota
hist_array[i] = hist.at<float>(i, 0);
int length = 1;
const int length_max = 255 - m_threshold;
const int length_max = 255 - threshold;
while (length < length_max)
{
for (size_t i = m_threshold + 1; i < 256 - length; i++)
for (size_t i = threshold + 1; i < 256 - length; i++)
{
int count = 0;
uint pixSum = 0;
@ -391,3 +132,199 @@ uchar CImageApplyAutoCrop::getBackGroudChannelMean(const cv::Mat& gray, int tota
}
return 255;
}
cv::Scalar getBackGroudColor(const cv::Mat& image, int total, int threshold)
{
if (image.channels() == 3)
{
cv::Mat image_bgr[3];
cv::split(image, image_bgr);
uchar bgr[3];
for (size_t i = 0; i < 3; i++)
bgr[i] = getBackGroudChannelMean(image_bgr[i], total, threshold);
return cv::Scalar(bgr[0], bgr[1], bgr[2]);
}
else
return cv::Scalar::all(getBackGroudChannelMean(image, total, threshold));
}
CImageApplyDispersion dispersion_apply;
#define COLOR_SCALE_THRE 0.5
void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight,
bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, bool dispersion)
{
if (src.empty()) return;
if (isNormalCrop)
{
cv::Rect roi = cv::Rect((src.cols - dWidth) / 2, FRONT_TOP, dWidth, dHeight) & cv::Rect(0, 0, src.cols, src.rows);
dst = src(roi).clone();
return;
}
if (!isAutoCrop && !isDesaskew && !isFillBlank && (dWidth <= 0 || dHeight <= 0))
{
dst = src.clone();
return;
}
cv::Mat resizeMat;
cv::Mat thre;
cv::resize(src, resizeMat, cv::Size(), FX_FY, FX_FY, cv::INTER_NEAREST);
hg::threshold_Mat(resizeMat, thre, threshold);
if (noise > 0)
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, getStructuringElement(cv::MORPH_RECT, cv::Size(noise * FX_FY, 1)),
cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
for (std::vector<cv::Point>& sub : contours)
for (cv::Point& p : sub)
p /= FX_FY;
std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
if (maxContour.empty())
{
if (isAutoCrop)
dst = src.clone();
else
{
cv::Rect roi = cv::Rect((src.cols - dWidth) / 2, FRONT_TOP, dWidth, dHeight) & cv::Rect(0, 0, src.cols, src.rows);
dst = src(roi).clone();
}
return;
}
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
if (dispersion)
{
cv::Mat mat_dispersion = src(cv::boundingRect(maxContour));
dispersion_apply.apply(mat_dispersion, 0);
}
cv::Scalar blankColor;
if (isFillBlank)
if (isColorBlank)
blankColor = getBackGroudColor(resizeMat, rect.size.area() * FX_FY * FX_FY, COLOR_SCALE_THRE);
else
blankColor = cv::Scalar::all(255);
else
blankColor = cv::Scalar::all(0);
if (isAutoCrop)
if (isDesaskew)
dst = cv::Mat(cv::Size(rect.size), src.type(), blankColor);
else
dst = cv::Mat(rect.boundingRect().size(), src.type(), blankColor);
else
dst = cv::Mat(dHeight, dWidth, src.type(), blankColor);
cv::Mat dstROI;
if (isDesaskew && rect.angle != 0)
{
cv::Point2f srcTri[4], dstTri[3];
rect.points(srcTri);
srcTri[0].x -= 1;
srcTri[1].x -= 1;
srcTri[2].x -= 1;
int w = rect.size.width;
int h = rect.size.height;
int x = (dst.cols - w) / 2;
int y = (dst.rows - h) / 2;
dstTri[0] = cv::Point2f(0, h);
dstTri[1] = cv::Point2f(0, 0);
dstTri[2] = cv::Point2f(w, 0);
dstROI = dst(cv::Rect(x, y, w, h) & cv::Rect(0, 0, dst.cols, dst.rows));
myWarpAffine(src, dstROI, cv::getAffineTransform(srcTri, dstTri), dstROI.size(), cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar::all(0));
}
else
{
cv::Rect bounding = cv::boundingRect(maxContour);
if (bounding.width > dst.cols)
{
bounding.x += (bounding.width - dst.cols) / 2;
bounding.width = dst.cols;
}
if (bounding.height > dst.rows)
{
bounding.y += (bounding.height - dst.rows) / 2;
bounding.height = dst.rows;
}
dstROI = dst(cv::Rect((dst.cols - bounding.width) / 2, (dst.rows - bounding.height) / 2, bounding.width, bounding.height));
src(bounding).copyTo(dstROI);
}
if (isFillBlank)
{
if (isConvex)
{
hg::convexHull(maxContour, maxContour);
contours.clear();
contours.push_back(maxContour);
}
cv::Point2f srcTri[4], dstTri[3];
int w, h;
if (isDesaskew && rect.angle != 0)
{
rect.points(srcTri);
srcTri[0].x -= 1;
srcTri[1].x -= 1;
srcTri[2].x -= 1;
w = rect.size.width;
h = rect.size.height;
}
else
{
cv::Rect bounding = rect.boundingRect();
srcTri[0] = cv::Point(bounding.x, bounding.br().y - 1);
srcTri[1] = cv::Point(bounding.x, bounding.y);
srcTri[2] = cv::Point(bounding.br().x - 1, bounding.y);
w = bounding.width;
h = bounding.height;
}
dstTri[0] = cv::Point2f((dstROI.cols - w) / 2 + indent, (dstROI.rows - h) / 2 + h - indent);
dstTri[1] = cv::Point2f((dstROI.cols - w) / 2 + indent, (dstROI.rows - h) / 2 + indent);
dstTri[2] = cv::Point2f((dstROI.cols - w) / 2 - indent + w, (dstROI.rows - h) / 2 + indent);
cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri);
double* ptr_m = reinterpret_cast<double*>(warp_mat.data);
double a = ptr_m[0];
double b = ptr_m[1];
double c = ptr_m[2];
double d = ptr_m[3];
double e = ptr_m[4];
double f = ptr_m[5];
int x, y;
for (std::vector<cv::Point>& sub : contours)
for (cv::Point& p : sub)
{
x = p.x;
y = p.y;
p.x = static_cast<int>(a * x + b * y + c);
p.y = static_cast<int>(d * x + e * y + f);
}
contours.push_back(std::vector<cv::Point>());
contours[contours.size() - 1].push_back(cv::Point(-1, dstROI.rows - 1));
contours[contours.size() - 1].push_back(cv::Point(-1, -1));
contours[contours.size() - 1].push_back(cv::Point(dstROI.cols, -1));
contours[contours.size() - 1].push_back(cv::Point(dstROI.cols, dst.rows));
hg::fillPolys(dstROI, contours, blankColor);
}
}

View File

@ -1,17 +1,32 @@
/*
/*
* ====================================================
*
*
* 2020/4/21
* 绿
* _020/4/21
* 2020/4/21 v1.0
2020/7/22 v1.1 maxContourPC端暂时无需使用
2020/10/16 v1.2 BUG
2020/10/28 v1.2.1 BUG
2020/10/28 v1.2.2 BUG
2020/10/29 v1.2.3 0°
2020/11/30 v1.3.0 稿
* v1.3.0
2020/7/22 v1.1 maxContourPC端暂时无需使用_
2020/10/16 v1.2 BUG
2020/10/28 v1.2.1 BUG
2020/10/28 v1.2.2 BUG
2020/10/29 v1.2.3 0°_
2020/11/30 v1.3.0 稿
2021/06/18 v1.3.1 noise
2021/07/01 v1.3.2 BUG
2021/07/08 v1.3.3
2021/07/08 v1.3.4
2021/07/09 v1.3.5 normalCrop机制m_isCrop m_isDesaskew m_isFillBlank均为false时可选用
2021/07/13 v1.3.6 normalCrop逻辑normalCrop为true时m_isCrop m_isDesaskew m_isFillBlank失效
2021/07/19 v1.3.7 仿INTER_LINEAR
2021/07/22 v1.3.8 BUG
2021/08/02 v1.3.9
2021/10/08 v1.3.10
2021/10/19 v1.3.11 0
2021/10/19 v1.3.12
2022/04/24 v1.4
2022/05/03 v1.4.1
2022/06/09 v1.4.2 稿threshold值0.5
* v1.4.2
* ====================================================
*/
@ -21,26 +36,26 @@
#include "ImageApply.h"
class CImageApplyAutoCrop : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyAutoCrop : public CImageApply
{
public:
CImageApplyAutoCrop();
/*
* isCrop [in]:使true自动裁剪false为固定裁
* isCrop [in]:使true自动裁剪false为固定裁
* isDesaskew [in]:使true自动纠偏false为不纠偏
* isFillBlank [in]:使true为填充false为不填充
* fixedSize [in]:isCrop为false时生效fixedSize大小输出
* fixedSize [in]:isCrop为false时生效fixedSize大小输出紿
* isConvex [in]:,true为凸多边形填充false为凹多边形填充true
* isFillColor [in]:false为白色填充true为自适应文稿底色填充false
* threshold [in]:(0, 255)40
* noise [in]:noise宽度的背景竖条纹干扰2
* indent [in]:indent像素5
* normalCrop [in]:true且m_isCrop m_isDesaskew m_isFillBlank均为false时生效false
* threshold [in]:0, 255)访0
* noise [in]:noise宽度的背景竖条纹干扰访
* indent [in]:indent像素访
* normalCrop [in]:true时m_isCrop m_isDesaskew m_isFillBlank失效false
* dispersion [in]:true时false时不除色散true
*/
CImageApplyAutoCrop(bool isCrop, bool isDesaskew, bool isFillBlank, const cv::Size& fixedSize, bool isConvex = true,
bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false);
bool isFillColor = false, double threshold = 40, int noise = 8, int indent = 5, bool normalCrop = false, bool dispersion = true);
virtual ~CImageApplyAutoCrop();
@ -56,12 +71,10 @@ public:
bool isConvexHull() { return m_isConvexHull; }
cv::RotatedRect getROI() { return m_rect; }
double threshold() { return m_threshold; }
const cv::RotatedRect& rotatedROI() { return m_rect; }
const std::vector<cv::RotatedRect>& rotatedROIs() { return m_rects; }
int noise() { return m_noise; }
int indent() { return m_indent; }
@ -86,10 +99,7 @@ public:
void setFixedSize(cv::Size size) { m_fixedSize = size; }
private:
cv::Scalar getBackGroudColor(const cv::Mat& image, int total);
uchar getBackGroudChannelMean(const cv::Mat& gray, int total);
void setDispersion(bool enable) { m_isDispersion = enable; }
private:
bool m_isCrop;
@ -97,16 +107,19 @@ private:
bool m_isFillBlank;
bool m_isConvexHull;
bool m_isFillColor;
bool m_isDispersion;
double m_threshold;
int m_noise;
int m_indent;
bool m_normalCrop; //为true且m_isCrop m_isDesaskew m_isFillBlank均为false时生效固定裁切采用最传统的裁切方
bool m_normalCrop; //为true且m_isCrop m_isDesaskew m_isFillBlank均为false时生效固定裁切采用最传统的裁切方弿
cv::Size m_fixedSize;
cv::RotatedRect m_rect;
std::vector<cv::Point> m_maxContour;
std::vector<cv::RotatedRect> m_rects;
std::vector<cv::Point> m_maxContour;
};
#endif // !IMAGE_APPLY_AUTO_CROP_H
void autoCrop_desaskew_fillBlank(const cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight,
bool isConvex = true, bool isColorBlank = false, double threshold = 40, int noise = 8, int indent = 5, bool isNormalCrop = false, bool dispersion = true);
#endif // !IMAGE_APPLY_AUTO_CROP_H

View File

@ -14,8 +14,8 @@ CImageApplyBWBinaray::CImageApplyBWBinaray(ThresholdType type, int threshold, in
CImageApplyBWBinaray::CImageApplyBWBinaray()
: m_threshold(120)
, m_type(ThresholdType::THRESH_BINARY)
, m_blockSize(25)
, m_constant(5)
, m_blockSize(51)
, m_constant(41)
, m_table(new uchar[256])
{
memset(m_table, 255, 256);
@ -27,6 +27,8 @@ CImageApplyBWBinaray::~CImageApplyBWBinaray(void)
delete[] m_table;
}
#define THRESHOLD_LOW 30
#define THRESHOLD_UP 245
void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
{
(void)side;
@ -35,14 +37,11 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
if (pDib.channels() == 3)
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
//20.12.29 修改参数为51 10 30 235
//20.12.30 修改参数为51 20 30 235
// 修改参数为17 20 110 235
cv::Mat integ;
int blockSize = 17;//邻域尺寸
int threshold = 20;
int low = 110;
int up = 235;
int blockSize = m_blockSize;//邻域尺寸
int threshold = m_constant;
int low = THRESHOLD_LOW;
int up = THRESHOLD_UP;
int halfSize = blockSize / 2;
int square_blockSize = blockSize * blockSize;
switch (m_type)
@ -86,6 +85,10 @@ void CImageApplyBWBinaray::apply(cv::Mat& pDib, int side)
default:
break;
}
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyBWBinaray apply");
#endif // LOG
}
void CImageApplyBWBinaray::apply(std::vector<cv::Mat>& mats, bool isTwoSide)

View File

@ -1,4 +1,4 @@
/*
/*
* ====================================================
*
@ -9,7 +9,8 @@
2020/6/19 v1.3
2020/12/21 v1.3.1
2020/12/21 v1.3.2 blockSize,5125
* v1.3.2
2022/05/25 v1.3.3 blockSize和constantTHRESH_BINARY同样有效
* v1.3.3
* ====================================================
*/
@ -19,7 +20,7 @@
#include "ImageApply.h"
class CImageApplyBWBinaray:public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyBWBinaray:public CImageApply
{
public:
@ -40,7 +41,7 @@ public:
* 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(ThresholdType type, int threshold = 120, int blockSize = 51, int constant = 41);
CImageApplyBWBinaray();

View File

@ -1,4 +1,4 @@
/*
/*
* ====================================================
* BGR图像中的单个通道
@ -19,7 +19,7 @@
#include "ImageApply.h"
class CImageApplyAdjustColors;
class CImageApplyChannel : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyChannel : public CImageApply
{
public:

View File

@ -14,41 +14,61 @@ bool isColor(const cv::Mat& image)
if (image.channels() != 3) return false;
cv::Mat pDib_resize;
cv::resize(image, pDib_resize, cv::Size(image.cols / 9, image.rows / 9), 0, 0, cv::INTER_AREA);
cv::resize(image, pDib_resize, cv::Size(image.cols / 4, image.rows / 4), 0, 0, cv::INTER_NEAREST);
cv::Mat hsv;
cv::cvtColor(pDib_resize, hsv, cv::COLOR_BGR2HSV_FULL);
std::vector<cv::Mat> hsv_channels;
cv::split(hsv, hsv_channels);
cv::Mat range_h1, range_h2, range_s, range_v;
cv::inRange(hsv_channels[0], 0, 85, range_h1);
cv::inRange(hsv_channels[0], 170, 255, range_h2);
cv::inRange(hsv_channels[1], 60, 255, range_s);
cv::inRange(hsv_channels[2], 100, 255, range_v);
cv::Mat range_s1, range_s2;
cv::inRange(hsv_channels[1], 220, 255, range_s1); //饱和度在[220, 255]的像素
cv::inRange(hsv_channels[1], 50, 220, range_s2); //饱和度在[50, 220]的像素
#if 0
cv::imwrite("range_s1.bmp", range_s1);
cv::imwrite("range_s2.bmp", range_s2);
#endif
double sum = cv::sum(range_s1)[0] / 255;
double total = range_s1.total();
cv::Mat thre = (range_h1 | range_h2) & range_s & range_v;
return (cv::sum(thre)[0] / 255)> 4;
// if (sum / total > 0.0001)
if (sum / total > 0.001)
return true;
sum += cv::sum(range_s2)[0] / 255;
// if (sum / total > 0.001)
if (sum / total > 0.03)
return true;
return false;
}
bool isGray(const cv::Mat& image)
{
if (image.channels() == 3) return true;
//if (image.channels() == 3) return true;
cv::Mat image_clone;
cv::resize(image, image_clone, cv::Size(), 0.25, 0.25);
int channels[] = { 0 };
int histsize[] = { 256 };
float range[] = { 0, 256 };
const float* histRanges[] = { range };
cv::Mat hist;
cv::calcHist(&image_clone, 1, channels, cv::Mat(), hist, 1, histsize, histRanges, true, false);
//cv::Mat image_clone;
//cv::resize(image, image_clone, cv::Size(), 0.25, 0.25);
//int channels[] = { 0 };
//int histsize[] = { 256 };
//float range[] = { 0, 256 };
//const float* histRanges[] = { range };
//cv::Mat hist;
//cv::calcHist(&image_clone, 1, channels, cv::Mat(), hist, 1, histsize, histRanges, true, false);
//float pixels[256] = { 0 };
//for (size_t i = 0; i < 256; i++)
// pixels[i] = hist.at<float>(i, 0);
float pixel_count0 = hist.at<float>(0, 0);
float pixel_count255 = hist.at<float>(255, 0);
float total = image_clone.total();
return ((pixel_count0 + pixel_count255) / total) > 0.95;
//float sum = 0;
//for (size_t i = 0; i < 40; i++)
//{
//}
//float pixel_count0 = hist.at<float>(0, 0);
//float pixel_count255 = hist.at<float>(255, 0);
//float total = image_clone.total();
//return ((pixel_count0 + pixel_count255) / total) > 0.95;
return false;
}
CImageApplyColorRecognition::CImageApplyColorRecognition(ColorRecognitionMode mode)
@ -62,40 +82,49 @@ CImageApplyColorRecognition::~CImageApplyColorRecognition(void)
void CImageApplyColorRecognition::apply(cv::Mat& pDib, int side)
{
//先判断是否需要判断是彩色
if (m_mode == AllColor || m_mode == Color_Gray || m_mode == Color_Mono)
if (pDib.channels() != 3)
{
//如果是彩色,直接退出
if (isColor(pDib))
{
m_result = Color;
m_result = Gray;
return;
}
}
if (pDib.channels() == 3)
m_result = isColor(pDib) ? Color : Gray;
if (m_result == Gray && pDib.channels() == 3)
cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
if (m_mode == Color_Gray)
{
m_result = Gray;
return;
}
//先判断是否需要判断是彩色
//if (m_mode == AllColor || m_mode == Color_Gray || m_mode == Color_Mono)
//{
// //如果是彩色,直接退出
// if (isColor(pDib))
// {
// m_result = Color;
// return;
// }
//}
if (m_mode == Color_Mono)
{
m_bw.apply(pDib, side);
m_result = Mono;
return;
}
//if (pDib.channels() == 3)
// cv::cvtColor(pDib, pDib, cv::COLOR_BGR2GRAY);
if (isGray(pDib))
m_result = Gray;
else
{
m_bw.apply(pDib, side);
m_result = Mono;
}
//if (m_mode == Color_Gray)
//{
// m_result = Gray;
// return;
//}
//if (m_mode == Color_Mono)
//{
// m_bw.apply(pDib, side);
// m_result = Mono;
// return;
//}
//if (isGray(pDib))
// m_result = Gray;
//else
//{
// m_bw.apply(pDib, side);
// m_result = Mono;
//}
}
void CImageApplyColorRecognition::apply(std::vector<cv::Mat>& mats, bool isTwoSide)

View File

@ -1,15 +1,15 @@
/*
/*
* ====================================================
* 242568 8
*
* 2020/7/17
* 2021/04/19
* v1.0 2020/7/17
* v1.1 2020/12/15
* v1.2 2020/12/16 访
* v1.3 2021/04/19 1
* v1.4 2021/06/18 [90, 200][50, 200]
* 242568 8
*
* 2020/7/17
* 2021/04/19
* v1.0 2020/7/17
* v1.1 2020/12/15
* v1.2 2020/12/16 访
* v1.3 2021/04/19 1
* v1.4 2021/06/18 [90, 200][50, 200]
* ====================================================
*/
@ -18,25 +18,25 @@
#include "ImageApply.h"
class CImageApplyColorRecognition : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyColorRecognition : public CImageApply
{
public:
//色彩识别模式
//色彩识别模式
enum ColorRecognitionMode
{
AllColor, //全色模式 识别结果可能会是彩色、灰度、黑白
Color_Gray, //彩色灰度模式 识别结果只会是彩色或者灰度
Color_Mono, //彩色黑白模式 识别结果只会是彩色或者黑白
Gray_Mono //灰度黑白模式 识别结果只会是灰度或者黑白
AllColor, //全色模式 识别结果可能会是彩色、灰度、黑白
Color_Gray, //彩色灰度模式 识别结果只会是彩色或者灰度
Color_Mono, //彩色黑白模式 识别结果只会是彩色或者黑白
Gray_Mono //灰度黑白模式 识别结果只会是灰度或者黑白
};
//色彩类型
//色彩类型
enum ColorType
{
Color, //彩色
Gray, //灰度
Mono //黑白
Color, //彩色
Gray, //灰度
Mono //黑白
};
public:
CImageApplyColorRecognition(ColorRecognitionMode mode = AllColor);
@ -48,15 +48,15 @@ public:
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
/// <summary>
/// 获取图片色彩类型。配合void apply(cv::Mat&, int)接口使用
/// 获取图片色彩类型。配合void apply(cv::Mat&, int)接口使用
/// </summary>
/// <returns>色彩类型</returns>
/// <returns>色彩类型</returns>
ColorType getResult();
/// <summary>
/// 获取图片色彩类型。配合void apply(std::vector<cv::Mat>&, int)接口使用
/// 获取图片色彩类型。配合void apply(std::vector<cv::Mat>&, int)接口使用
/// </summary>
/// <returns>色彩类型数组</returns>
/// <returns>色彩类型数组</returns>
std::vector<ColorType> getResults();
private:

View File

@ -15,7 +15,7 @@
#include "ImageApply.h"
class CImageApplyConcatenation : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyConcatenation : public CImageApply
{
public:
//对折方向
@ -24,7 +24,6 @@ public:
horizontal = 0, //左右拼接 吅
vertical, //上下拼接 吕
autoDirection
};
public:
CImageApplyConcatenation(); //默认m_direction = autoDirection;

View File

@ -15,7 +15,7 @@
#include "ImageApply.h"
class CImageApplyCustomCrop : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyCustomCrop : public CImageApply
{
public:

View File

@ -1,11 +1,11 @@
/*
/*
* ====================================================
*
*
* 2020/4/21
* 2020/4/21
* v1.0
*
*
* 2020/4/21
* 2020/4/21
* v1.0
* ====================================================
*/
@ -15,12 +15,12 @@
#include "ImageApply.h"
class CImageApplyCustomGamma : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyCustomGamma : public CImageApply
{
public:
/*
* table [in]:
* length [in]:256768
* table [in]:
* length [in]:256768
* */
CImageApplyCustomGamma(unsigned char* table,int length);

View File

@ -16,7 +16,7 @@
#include "ImageApply.h"
class CImageApplyCvtColor : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyCvtColor : public CImageApply
{
public:

View File

@ -24,8 +24,12 @@ void CImageApplyDetachNoise::apply(cv::Mat& pDib, int side)
hg::findContours(mask, contours, h);
for (const std::vector<cv::Point>& contour : contours)
if (contourArea(contour) < m_noise)
{
cv::Rect rect = cv::boundingRect(contour);
if (rect.width <= m_noise && rect.height <= m_noise)
fillConvexPoly(pDib, contour, cv::Scalar(255));
}
}
void CImageApplyDetachNoise::apply(std::vector<cv::Mat> &mats, bool isTwoSide)

View File

@ -5,8 +5,9 @@
*
* 2020/4/21
* 2020/4/21 v1.0
2020/5/29 v1.1 使
* v1.1
2020/05/29 v1.1 使
2021/08/03 v1.2 noise尺寸为33*3block尺寸
* v1.2
* ====================================================
*/
@ -16,18 +17,10 @@
#include "ImageApply.h"
class CImageApplyDetachNoise : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyDetachNoise : public CImageApply
{
public:
CImageApplyDetachNoise(int
= 1);
CImageApplyDetachNoise(int noise = 3);
inline int getNoise() { return m_noise; }

View File

@ -101,13 +101,13 @@ bool CImageApplyDiscardBlank::apply(const cv::Mat& pDib, double threshold, int e
/*
if (b)
{
cv::imwrite("<EFBFBD>հ<EFBFBD>ҳ/img1/" + std::to_string(index) + ".bmp", img_resize);
cv::imwrite("<EFBFBD>հ<EFBFBD>ҳ/mask1/" + std::to_string(index) + ".bmp", mask);
cv::imwrite("¿Õ°×Ò³/img1/" + std::to_string(index) + ".bmp", img_resize);
cv::imwrite("¿Õ°×Ò³/mask1/" + std::to_string(index) + ".bmp", mask);
}
else
{
cv::imwrite("<EFBFBD>հ<EFBFBD>ҳ/img2/" + std::to_string(index) + ".bmp", img_resize);
cv::imwrite("<EFBFBD>հ<EFBFBD>ҳ/mask2/" + std::to_string(index) + ".bmp", mask);
cv::imwrite("¿Õ°×Ò³/img2/" + std::to_string(index) + ".bmp", img_resize);
cv::imwrite("¿Õ°×Ò³/mask2/" + std::to_string(index) + ".bmp", mask);
}*/
return b;

View File

@ -1,20 +1,20 @@
/*
/*
* ====================================================
*
*
* 2020/4/21
* 2020/4/21 v1.0
2020/8/12 v1.1 setIntensity和setMinAreaisNormal标识位setIntensity的设置范围[2, 20][1, 100]
2020/8/25 v1.1.1 10020
2020/10/16 v1.2 便
2020/10/19 v1.2.1 BUG
2021/04/13 v1.3.0 /
2021/08/12 v1.3.1 opencv版本导致计算结果存在差异的代码
2021/12/14 v1.3.2
2021/12/15 v1.3.3
2021/12/17 v1.3.4
* v1.3.4
*
*
* 2020/4/21
* 2020/4/21 v1.0
2020/8/12 v1.1 setIntensity和setMinAreaisNormal标识位setIntensity的设置范围[2, 20][1, 100]
2020/8/25 v1.1.1 10020
2020/10/16 v1.2 便
2020/10/19 v1.2.1 BUG
2021/04/13 v1.3.0 /
2021/08/12 v1.3.1 opencv版本导致计算结果存在差异的代码
2021/12/14 v1.3.2
2021/12/15 v1.3.3
2021/12/17 v1.3.4
* v1.3.4
* ====================================================
*/
@ -24,7 +24,7 @@
#include "ImageApply.h"
class CImageApplyDiscardBlank : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyDiscardBlank : public CImageApply
{
public:

View File

@ -0,0 +1,44 @@
#include "ImageApplyDispersion.h"
CImageApplyDispersion::CImageApplyDispersion(float a, float b, float c, float sharpen)
: CImageApply()
, m_kernal_b(3, 1, CV_32FC1)
, m_kernal_g(3, 1, CV_32FC1)
, m_kernal_r(3, 1, CV_32FC1)
{
m_kernal_b.at<float>(0, 0) = a;
m_kernal_b.at<float>(1, 0) = 1.0f + sharpen - a;
m_kernal_b.at<float>(2, 0) = -sharpen;
m_kernal_g.at<float>(0, 0) = b;
m_kernal_g.at<float>(1, 0) = 1.0f + sharpen - b;
m_kernal_g.at<float>(2, 0) = -sharpen;
m_kernal_r.at<float>(0, 0) = c;
m_kernal_r.at<float>(1, 0) = 1.0f + sharpen - c;
m_kernal_r.at<float>(2, 0) = -sharpen;
}
CImageApplyDispersion::~CImageApplyDispersion()
{
}
void CImageApplyDispersion::apply(cv::Mat& pDib, int side)
{
(void)side;
if (pDib.channels() != 3) return;
cv::Mat bgr[3];
cv::split(pDib, bgr);
cv::filter2D(bgr[0], bgr[0], bgr[0].depth(), m_kernal_b);
cv::filter2D(bgr[1], bgr[1], bgr[1].depth(), m_kernal_g);
cv::filter2D(bgr[2], bgr[2], bgr[2].depth(), m_kernal_r);
cv::merge(bgr, 3, pDib);
}
void CImageApplyDispersion::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
}

View File

@ -0,0 +1,36 @@
/*
* ====================================================
*
*
* 2021/09/24
* 2021/11/12 v1.1.0
* 2022/04/21 v1.2.0
* 2022/07/20 v1.3.0
* v1.3.0
* ====================================================
*/
#ifndef IMAGE_APPLY_DISPERSION_COLOR_H
#define IMAGE_APPLY_DISPERSION_COLOR_H
#include "ImageApply.h"
class GIMGPROC_LIBRARY_API CImageApplyDispersion : public CImageApply
{
public:
CImageApplyDispersion(float a = 0.15f, float b = 0.806f, float c = 0.484f, float sharpen = 0.3f);
virtual ~CImageApplyDispersion();
virtual void apply(cv::Mat& pDib, int side);
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
private:
cv::Mat m_kernal_b;
cv::Mat m_kernal_g;
cv::Mat m_kernal_r;
};
#endif

View File

@ -3,18 +3,22 @@
CImageApplyDogEarDetection::CImageApplyDogEarDetection()
: m_threshold(40)
, m_zoom(1.0)
, m_distance(50)
, m_result(false)
, m_zoom_x(1.0)
, m_zoom_y(1.0)
, m_distance1(50)
, m_distance2(50)
, m_result(0)
{
}
CImageApplyDogEarDetection::CImageApplyDogEarDetection(double threshlod, double zoom, double distance)
CImageApplyDogEarDetection::CImageApplyDogEarDetection(double threshlod, double zoom_x, double zoom_y, double distance1, double distance2)
: m_threshold(threshlod)
, m_zoom(zoom)
, m_distance(distance)
, m_result(false)
, m_zoom_x(zoom_x)
, m_zoom_y(zoom_y)
, m_distance1(distance1)
, m_distance2(distance2)
, m_result(0)
{
}
@ -24,19 +28,24 @@ CImageApplyDogEarDetection::~CImageApplyDogEarDetection()
}
#define EDGE_ABS 4
void CImageApplyDogEarDetection::apply(cv::Mat& pDib, int side)
{
m_result = false;
m_result = 0;
(void)side;
if (pDib.empty()) return;
cv::Mat src;
if (m_zoom != 1.0)
cv::resize(pDib, src, cv::Size(), m_zoom, m_zoom, cv::INTER_NEAREST);
if (m_zoom_x != 1.0 && m_zoom_y != 1.0)
cv::resize(pDib, src, cv::Size(), m_zoom_x, m_zoom_y, cv::INTER_NEAREST);
else
src = pDib;
cv::Mat thre;
hg::threshold_Mat(src, thre, m_threshold);
cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(5, 1));
cv::morphologyEx(thre, thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
@ -52,11 +61,41 @@ void CImageApplyDogEarDetection::apply(cv::Mat &pDib, int side)
cv::Point2f vertexes[4];
rect.points(vertexes);
double distance;
for (int i = 0; i < 4; i++)
if ((-cv::pointPolygonTest(maxContour, vertexes[i], true)) > (m_distance * m_zoom))
{
m_result = true;
distance = -cv::pointPolygonTest(maxContour, vertexes[i], true);
//判断是否为普通折角
if (distance > (m_distance1 / m_zoom_x))
{
if (cv::Rect(0, 0, src.cols, src.rows).contains(vertexes[i]))
m_result = 1;
else if (vertexes[i].x < 0 && cv::abs(distance + vertexes[i].x) > EDGE_ABS) //如果是越界折角修改m_result值但是需要继续判断防止漏掉普通折角
m_result = 1;
else if (vertexes[i].y < 0 && cv::abs(distance + vertexes[i].y) > EDGE_ABS)
m_result = 1;
else if (vertexes[i].x > src.cols && cv::abs(distance + src.cols - vertexes[i].x) > EDGE_ABS)
m_result = 1;
else if (vertexes[i].y > src.rows && cv::abs(distance + src.rows - vertexes[i].y) > EDGE_ABS)
m_result = 1;
}
if (m_result == 1)
return;
//判断是否为扫描越界导致的折角
if (distance > (m_distance2 / m_zoom_x))
{
if (vertexes[i].x < 0 && cv::abs(distance + vertexes[i].x) < EDGE_ABS) //如果是越界折角修改m_result值但是需要继续判断防止漏掉普通折角
m_result = 2;
else if (vertexes[i].y < 0 && cv::abs(distance + vertexes[i].y) < EDGE_ABS)
m_result = 2;
else if (vertexes[i].x > src.cols && cv::abs(distance + src.cols - vertexes[i].x) < EDGE_ABS)
m_result = 2;
else if (vertexes[i].y > src.rows && cv::abs(distance + src.rows - vertexes[i].y) < EDGE_ABS)
m_result = 2;
}
}
}

View File

@ -1,11 +1,16 @@
/*
/*
* ====================================================
*
*
* 2020/10/30
* 2020/10/30
* v1.0
* 2020/10/30 v1.0
* 2021/11/04 v1.1 5
* 2022/07/15 v1.2
* 2022/07/21 v1.3 21
* 2022/07/21 v1.3.1 12
* 2022/07/22 v1.4 zoom_x,zoom_yXY轴DPI不一致的问题
* v1.4
* ====================================================
*/
@ -15,7 +20,7 @@
#include "ImageApply.h"
class CImageApplyDogEarDetection :public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyDogEarDetection : public CImageApply
{
public:
@ -28,17 +33,18 @@ public:
/// 折角检测构造函数
/// </summary>
/// <param name="threshlod">二值化阈值</param>
/// <param name="zoom">原图缩放比例对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放)</param>
/// <param name="zoom_x">原图X轴缩放比例对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放)</param>
/// <param name="zoom_y">原图Y轴缩放比例对于大尺寸图像而言通过zoom缩小图像可减少计算量。默认值1.0(不缩放)</param>
/// <param name="distance">理论顶点到实际轮廓最小距离的阈值大于该阈值则判定为折角默认值50像素</param>
CImageApplyDogEarDetection(double threshlod, double zoom = 1.0, double distance = 50);
CImageApplyDogEarDetection(double threshlod, double zoom_x = 1.0, double zoom_y = 1.0, double distance1 = 50, double distance2 = 50);
virtual ~CImageApplyDogEarDetection(void);
/// <summary>
/// 获取检测结果。该函数须在调用apply之后使用。
/// </summary>
/// <returns>true为折角false为不折角</returns>
inline bool getResult() { return m_result; }
/// <returns>0为非折角1为普通折角2为可能是扫描不完整造成的折角</returns>
inline int getResult() { return m_result; }
virtual void apply(cv::Mat& pDib, int side);
@ -47,10 +53,12 @@ private:
private:
double m_threshold;
double m_zoom;
double m_distance;
double m_zoom_x;
double m_zoom_y;
double m_distance1;
double m_distance2;
bool m_result;
int m_result;
};
#endif // IMAGE_APPLY_DOGEAR_DETECTION_H

View File

@ -80,7 +80,7 @@ void CImageApplyFadeBackGroudColor::fadeBackground(unsigned char* data, int byte
//ͳ¼Æ±³¾°É«
int max_vals[3] = { 0 };
int max_indexes[3];
int max_indexes[3] = { 0 };
for (size_t i = 1; i < 256; i++)
for (size_t j = 0; j < 3; j++)

View File

@ -12,7 +12,8 @@
* 2021/10/26 v3.1
* 2021/10/28 v3.2 C++
* 2021/10/29 v3.3 range参数
* v3.2
* 2022/03/08 v3.4 BUG
* v3.4
* ====================================================
*/
@ -24,7 +25,7 @@
#include "ImageApply.h"
class CImageApplyAdjustColors;
class CImageApplyFadeBackGroudColor : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyFadeBackGroudColor : public CImageApply
{
public:
/// <summary>

View File

@ -20,7 +20,7 @@
#include "ImageApply.h"
class CImageApplyFilter : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyFilter : public CImageApply
{
public:
enum FilterMode

View File

@ -1,21 +1,18 @@
#include "ImageApplyHSVCorrect.h"
#include <omp.h>
CImageApplyHSVCorrect::CImageApplyHSVCorrect()
: m_table(new uint[256 * 256 * 256])
{
initLUT();
}
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode)
CImageApplyHSVCorrect::CImageApplyHSVCorrect(CorrectOption mode, bool cvtColor, uint bgr)
: 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);
set_HSV_value(std::pair<uchar, uchar>(0, 63), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
set_HSV_value(std::pair<uchar, uchar>(200, 255), std::pair<uchar, uchar>(30, 255), std::pair<uchar, uchar>(120, 255), bgr, cvtColor);
break;
case CImageApplyHSVCorrect::LowSaturation_Removal:
set_HSV_value(std::pair<uchar, uchar>(0, 255), std::pair<uchar, uchar>(0, 30), std::pair<uchar, uchar>(0, 255), bgr, cvtColor);
break;
default:
break;
@ -31,21 +28,35 @@ void CImageApplyHSVCorrect::apply(cv::Mat &pDib, int side)
{
(void)side;
if (pDib.empty() || pDib.channels() != 3) return;
#if 0
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 bytesPerLine = pDib.cols * pDib.channels();
for (size_t i = 0, rows = pDib.rows; i < rows; i++)
{
uchar* ptr = pDib.ptr(i);
for (size_t j = 0, cols = pDib.cols; j < cols; j++)
{
int offset = i * 3;
int index = *reinterpret_cast<uint*>(src + offset) & 0x00ffffff;
int index = *reinterpret_cast<uint*>(ptr + offset) & 0x00ffffff;
uint color = m_table[index];
*reinterpret_cast<uint*>(dst + offset) |= color;
}
}
pDib = z;
#else
cv::Mat bgra;
cv::cvtColor(pDib, bgra, cv::COLOR_BGR2BGRA);
long total = bgra.total();
uint* ptr = bgra.ptr<uint>();
for (long i = 0; i < total; i++)
ptr[i] = m_table[ptr[i] & 0x00FFFFFF];
cv::cvtColor(bgra, pDib, cv::COLOR_BGRA2BGR);
#endif
}
void CImageApplyHSVCorrect::apply(std::vector<cv::Mat> &mats, bool isTwoSide)
@ -93,7 +104,7 @@ void CImageApplyHSVCorrect::set_single(const uint src_b, const uint src_g, const
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)
uint bgr, bool cvtGray)
{
uchar h, s, v;
for (int b = 0; b < 256; b++)
@ -102,13 +113,21 @@ void CImageApplyHSVCorrect::set_HSV_value(const std::pair<uchar, uchar>& range_h
{
RGB_2_HSV_full(r, g, b, h, s, v);
if (contained(h, range_h) && contained(s, range_s) && contained(v, range_v))
{
if (cvtGray)
{
int a = (b + g + r) / 3 * 0x00010101;
m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = (b + g + r) / 3 * 0x00010101;
}
else
m_table[(b | (g << 8) | (r << 16)) & 0x00ffffff] = bgr & 0x00ffffff;
}
}
}
void CImageApplyHSVCorrect::set_table(const uint* table)
{
memcpy(m_table, table, 256 * 256 * 256);
memcpy(m_table, table, 256 * 256 * 256 * sizeof(uint));
}
bool CImageApplyHSVCorrect::contained(uchar value, const std::pair<uchar, uchar> &range)

View File

@ -1,13 +1,18 @@
/*
* ====================================================
*
* LUT实现BGR查值表HVSBGR原图进行查值校正
*
* 2020/3/21
* v1.0 2020/3/21
v1.1 2020/6/15 HSV取值范围
* v1.1
* v1.0 2020/03/21
v1.1 2020/06/15 HSV取值范围
v1.2 2021/08/02 ROI图像的内存偏移
v1.3 2021/08/26 Red_Removal实现方案
v1.4 2022/04/22 Deafault和LowSaturation_Removal
v1.4.1 2022/04/25 访
v1.4.2 2022/06/09
* v1.4.2
*
* ====================================================
*/
@ -16,21 +21,22 @@
#include "ImageApply.h"
class CImageApplyHSVCorrect : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyHSVCorrect : public CImageApply
{
public:
enum CorrectOption
{
Deafault, //默认,无任何除色效果
LowSaturation_Removal, //除掉低饱和度像素
Red_Removal //除掉红色。红色定义H:[0, 85][170, 255],S:[10, 255],V:[120,255]
};
public:
CImageApplyHSVCorrect();
/*
* mode [in]:
* cvtColor [in]:使使true为灰度值false为默认值
* bgr:[in] uint表示BGR值B在低位R在高位cvtGray false时生效)
*/
CImageApplyHSVCorrect(CorrectOption mode);
CImageApplyHSVCorrect(CorrectOption mode = CorrectOption::Deafault, bool cvtColor = false, uint bgr = 0x00FFFFFF);
virtual ~CImageApplyHSVCorrect();
@ -57,17 +63,19 @@ public:
*/
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在高位
* bgr:[in] uint表示BGR值B在低位R在高位cvtGray false时生效)
* cvtGray:[in] true时RGB值转换为灰度值
*/
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);
uint bgr = 0x00FFFFFF, bool cvtGray = false);
/*
* 256 * 256 * 256 * sizeof(uint

View File

@ -3,32 +3,31 @@
#include "ImageApply.h"
#include "ImageApplyAdjustColors.h"
#include "ImageApplyAutoContrast.h"
#include "ImageApplyAutoCrop.h"
//#include "ImageApplyBarCodeRecognition.h"
#include "ImageApplyBWBinaray.h"
#include "ImageApplyChannel.h"
#include "ImageApplyCrop.h"
#include "ImageApplyDiscardBlank.h"
#include "ImageApplyOutHole.h"
#include "ImageApplyDogEarDetection.h"
#include "ImageApplyResize.h"
#include "ImageApplyRotation.h"
#include "ImageApplySharpen.h"
#include "ImageApplyConcatenation.h"
#include "ImageApplyHSVCorrect.h"
#include "ImageApplyDetachNoise.h"
#include "ImageApplyColorRecognition.h"
#include "ImageApplyUV.h"
#include "ImageApplyAutoContrast.h"
#include "ImageApplyConcatenation.h"
#include "ImageApplyCustomCrop.h"
#include "ImageApplyCustomGamma.h"
#include "ImageApplyCvtColor.h"
#include "ImageApplyDetachNoise.h"
#include "ImageApplyDiscardBlank.h"
#include "ImageApplyDispersion.h"
#include "ImageApplyDogEarDetection.h"
#include "ImageApplyFadeBackGroundColor.h"
#include "ImageApplyFilter.h"
#include "ImageApplyHSVCorrect.h"
#include "ImageApplyOutHole.h"
#include "ImageApplyRefuseInflow.h"
#include "ImageApplyResize.h"
#include "ImageApplyRotation.h"
#include "ImageApplySplit.h"
#include "ImageApplySizeDetection.h"
#include "ImageApplyTextureRemoval.h"
#include "ImageMulti.h"
#include "ImageMultiOutputRed.h"
#include "ImageApplySplit.h"
#include "ImageApplySizeDetection.h"
#endif

View File

@ -0,0 +1,310 @@
#include "ImageApplyMarkCrop.h"
#include "ImageProcess_Public.h"
#define RE 2
//#define DRAW
CImageApplyMarkCrop::CImageApplyMarkCrop(CImageApplyMarkCrop::DeviceModel device, bool isCropped, double threshold, int noise, CImageApplyMarkCrop::DPI dpi, DirectionMethod direction)
: m_device(device)
, m_b_isCropped(isCropped)
, m_threshold(120)
, m_noise(noise)
, m_dpi(dpi)
, m_range(30, 55)
, m_direction(direction)
{
}
int CImageApplyMarkCrop::apply(const cv::Mat& src, cv::Mat& dst, Orientation markOri, bool barCode, int& angle)
{
if (src.empty()) return -1;
cv::Mat src_resize;
if (m_device == DeviceModel::G400)
cv::resize(src, src_resize, cv::Size(src.cols / RE, src.rows / RE));
else
cv::resize(src, src_resize, cv::Size(src.cols / 3, src.rows / RE));
cv::Mat scale_mat;
cv::Mat thre(src_resize.size(), CV_8UC1);
hg::threshold_Mat(src_resize, thre, m_threshold);
#ifdef DRAW
cv::imwrite("thre.bmp", thre);
#endif
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
std::vector<cv::Point> maxContour = hg::getMaxContour(contours, hierarchy);
float scale = m_device == DeviceModel::G300 ? 3 : RE;
if (maxContour.size() == 0)
{
thre.release();
return -1;
}
//thre.release();
//dst.release();
cv::RotatedRect rect = hg::getBoundingRect(maxContour);
cv::Point2f vertex[4];
rect.points(vertex);
std::vector<std::vector<cv::Point>> marks;
std::vector<cv::RotatedRect> rrects;
hg::threshold_Mat(src_resize, thre, m_threshold);
cv::bitwise_not(thre, thre);
contours.clear();
hierarchy.clear();
hg::findContours(thre, contours, hierarchy, cv::RETR_LIST);
findMarks(contours, rect, cv::Range(m_range.start / RE, m_range.end / RE), marks, rrects);
if (marks.size() < 3) return -2;
#ifdef DRAW
for (int i = 0; i < marks.size(); i++)
cv::circle(thre, marks[i][0], 30, cv::Scalar(255));
cv::imwrite("contour.bmp", thre);
#endif
maxContour.clear();
for (const std::vector<cv::Point>& mark : marks)
for (const cv::Point& p : mark)
maxContour.push_back(p);
if (rrects.size() == 3)
{
double distance1 = hg::distanceP2P(rrects[0].center, rrects[1].center);
double distance2 = hg::distanceP2P(rrects[1].center, rrects[2].center);
double distance3 = hg::distanceP2P(rrects[2].center, rrects[0].center);
if (distance1 > distance2 && distance1 > distance3)
maxContour.push_back(((rrects[0].center + rrects[1].center) / 2 * 3 - rrects[2].center) / 2);
else if (distance2 > distance1 && distance2 > distance3)
maxContour.push_back(((rrects[1].center + rrects[2].center) / 2 * 3 - rrects[0].center) / 2);
else
maxContour.push_back(((rrects[2].center + rrects[0].center) / 2 * 3 - rrects[1].center) / 2);
}
for (cv::Point& item : maxContour)
item *= scale;
rect = hg::getBoundingRect(maxContour);
rect.points(vertex);
cv::Point2f focus;
Orientation ori;
for (size_t i = 0; i < rrects.size(); i++)
for (size_t j = i + 1; j < rrects.size(); j++)
if (rrects[i].size.area() < rrects[j].size.area())
{
cv::RotatedRect rect_remp = rrects[j];
rrects[j] = rrects[i];
rrects[i] = rect_remp;
}
for (cv::RotatedRect& item : rrects)
item.center *= scale;
if (m_direction == DirectionMethod::Multilateral)
{
if (rrects.size() < 4) return -3;
for (int i = 0; i < 5; i++)
focus += rrects[i].center;
focus /= 5;
float dis_top = hg::distanceP2L(focus, vertex[1], vertex[2]);
float dis_bottom = hg::distanceP2L(focus, vertex[0], vertex[3]);
float dis_left = hg::distanceP2L(focus, vertex[0], vertex[1]);
float dis_right = hg::distanceP2L(focus, vertex[2], vertex[3]);
float dis_min = cv::min(dis_top, cv::min(dis_bottom, cv::min(dis_left, dis_right)));
if (dis_top == dis_min)
ori = Top_RB;
else if (dis_bottom == dis_min)
ori = Bottom_LT;
else if (dis_left == dis_min)
ori = Left_RT;
else
ori = Right_LB;
}
else if (m_direction == DirectionMethod::Trilateral_7Net)
{
for (int i = 0; i < 3; i++)
focus += rrects[i].center;
focus /= 3;
float dis_top = hg::distanceP2L(focus, vertex[1], vertex[2]);
float dis_bottom = hg::distanceP2L(focus, vertex[0], vertex[3]);
float dis_left = hg::distanceP2L(focus, vertex[0], vertex[1]);
float dis_right = hg::distanceP2L(focus, vertex[2], vertex[3]);
float dis_min_lr = cv::min(dis_left, dis_right);
float dis_min_tb = cv::min(dis_top, dis_bottom);
if (dis_min_lr == dis_right && dis_min_tb == dis_bottom)
ori = Bottom_LT;
else if (dis_min_lr == dis_left && dis_min_tb == dis_top)
ori = Top_RB;
else if (dis_min_lr == dis_right && dis_min_tb == dis_top)
ori = Right_LB;
else
ori = Left_RT;
}
cv::Point2f srcTri[4];
cv::Point2f dstTri[3];
rect.points(srcTri);
if (m_device == DeviceModel::G300)
for (cv::Point2f& p : srcTri)
p.y = p.y * RE / m_device;
cv::Size temp_size;
float width = rect.size.width;
float height = hg::distanceP2P(srcTri[0], srcTri[1]);
if (markOri == Default || markOri == ori)
{
dstTri[0] = cv::Point2f(0, height - 1);
dstTri[1] = cv::Point2f(0, 0);
dstTri[2] = cv::Point2f(width - 1, 0);
temp_size.width = width;
temp_size.height = height;
angle = 0;
}
else if (markOri - ori == -3 || markOri - ori == 1)
{
dstTri[0] = cv::Point2f(0, 0);
dstTri[1] = cv::Point2f(height - 1, 0);
dstTri[2] = cv::Point2f(height - 1, width - 1);
temp_size.width = height;
temp_size.height = width;
angle = -90;
}
else if (markOri - ori == -2 || markOri - ori == 2)
{
dstTri[0] = cv::Point2f(width - 1, 0);
dstTri[1] = cv::Point2f(width - 1, height - 1);
dstTri[2] = cv::Point2f(0, height - 1);
temp_size.width = width;
temp_size.height = height;
angle = 180;
}
else if (markOri - ori == -1 || markOri - ori == 3)
{
dstTri[0] = cv::Point2f(height - 1, width - 1);
dstTri[1] = cv::Point2f(0, width - 1);
dstTri[2] = cv::Point2f(0, 0);
temp_size.width = height;
temp_size.height = width;
angle = 90;
}
if (m_b_isCropped)
{
cv::Mat warp_mat;
warp_mat = cv::getAffineTransform(srcTri, dstTri);
cv::warpAffine(src, dst, warp_mat, temp_size);
}
else
{
if (angle == 0)
dst = src.clone();
else if (angle == 90)
{
cv::transpose(src, dst);
cv::flip(dst, dst, 0);
}
else if (angle == -90)
{
cv::transpose(src, dst);
cv::flip(dst, dst, 1);
}
else
{
cv::flip(src, dst, 0);
cv::flip(dst, dst, 1);
}
}
//Èç¹ûÐèÒªÅжÏÌõÂë
if (barCode)
{
//cv::imwrite("dst.bmp", dst);
if (dst.cols < 600 || dst.rows < 400)
return -4;
if (!isContainBarCode(dst(cv::Rect(0, 0, 600, 400))))
return -5;
}
return 0;
#ifdef DRAW
cv::imwrite("dst.bmp", dst);
#endif
}
void CImageApplyMarkCrop::findMarks(const std::vector<std::vector<cv::Point>>& contours, const cv::RotatedRect& region,
const cv::Range& range, std::vector<std::vector<cv::Point>>& marks, std::vector<cv::RotatedRect>& rrect)
{
cv::RotatedRect region_outside = region;
cv::RotatedRect region_inside = region;
region_inside.size = cv::Size2f(region.size.width * 0.9, region.size.height * 0.9);
cv::Point2f outside[4], inside[4];
region_outside.points(outside);
region_inside.points(inside);
std::vector<cv::Point> v_outside, v_inside;
for (size_t i = 0; i < 4; i++)
{
v_outside.push_back(cv::Point(outside[i].x, outside[i].y));
v_inside.push_back(cv::Point(inside[i].x, inside[i].y));
}
for (size_t i = 0, length = contours.size(); i < length; i++)
{
std::vector<cv::Point> contour = contours[i];
cv::RotatedRect rect = cv::minAreaRect(contour);
double area = cv::contourArea(contour);
if (rect.size.width < range.start || rect.size.height < range.start || rect.size.width > range.end || rect.size.height > range.end)
continue;
if (rect.size.width * rect.size.height < 40 / RE)
continue;
if (cv::pointPolygonTest(v_outside, rect.center, true) > 0 && cv::pointPolygonTest(v_inside, rect.center, true) < 0)
{
marks.push_back(contour);
rrect.push_back(rect);
}
}
}
bool CImageApplyMarkCrop::isContainBarCode(const cv::Mat& image)
{
cv::Mat thre;
hg::threshold_Mat(image, thre, 127);
cv::bitwise_not(thre, thre);
cv::Mat element = cv::getStructuringElement(cv::MorphShapes::MORPH_RECT, cv::Size(20, 1));
cv::morphologyEx(thre, thre, cv::MorphTypes::MORPH_DILATE, element);
//cv::imwrite("barCode.bmp", thre);
std::vector<cv::Vec4i> hierarchy;
std::vector<std::vector<cv::Point>> contours;
hg::findContours(thre, contours, hierarchy, cv::RETR_EXTERNAL);
for (size_t i = 0; i < contours.size(); i++)
{
cv::Rect rect = cv::boundingRect(contours[i]);
if (rect.width > 250 && rect.height > 50)
return true;
}
return false;
}

View File

@ -0,0 +1,116 @@
/*
* ====================================================
* Mark点定位裁剪mark点使
*
* 2020/5/22
* 2020/5/22 v1.0
2020/7/29 v1.1 Mark点识别稿
2020/7/30 v1.1.1 Mark点识别稿
2020/8/3 v1.2 Mark点识别文稿方向稿
2020/8/12 v1.3
apply接口增加barCode参数
2020/8/12 v1.4
* v1.4
* ====================================================
*/
#ifndef IMAGEMARKCROPAPPLY_H
#define IMAGEMARKCROPAPPLY_H
#include "ImageApply.h"
class GIMGPROC_LIBRARY_API CImageApplyMarkCrop
{
public:
//识别文稿方向方式
enum DirectionMethod
{
Trilateral_7Net, //三边定位文稿方向(针对七天需求)
Multilateral //多边定位文稿方向
};
enum DPI : ushort
{
DPI_200 = 200,
DPI_300 = 300
};
enum DeviceModel
{
G400 = 2,
G300 = 3
};
enum Orientation
{
Default = 0,
Left_RT, //多边文稿方向识别时靠左为正7天3mark识别时缺角在右上为正
Top_RB, //多边文稿方向识别时靠上为正7天3mark识别时缺角在右下为正
Right_LB, //多边文稿方向识别时靠右为正7天3mark识别时缺角在左下为正
Bottom_LT //多边文稿方向识别时靠下为正7天3mark识别时缺角在左上为正
};
public:
CImageApplyMarkCrop(DeviceModel device, bool isCropped = true, double threshold = 20, int noise = 40, DPI dpi = DPI::DPI_200, DirectionMethod direction = DirectionMethod::Multilateral);
/*
* src [in]:
* dst [out]:
* markOri [in]: 稿
* barCode [in]: Trilateral_7Net模式
* angle [out]:稿090180270
* 0
-1
-2mark小于3个
-3Multilateral模式时mark点小于4个
-4
-5
*/
int apply(const cv::Mat& src, cv::Mat& dst, Orientation markOri, bool barCode, int& angle);
inline DeviceModel getDeviceModel() { return m_device; }
inline void setDeviceModel(DeviceModel device) { m_device = device; }
inline bool isCropped() { return m_b_isCropped; }
inline void setCropped(bool cropped) { m_b_isCropped = cropped; }
inline double getThreshold() { return m_threshold; }
inline void setThreshold(double threshold) { m_threshold = threshold; }
inline int getNoise() { return m_noise; }
inline void setNoise(int noise) { m_noise = noise; }
inline DPI getDPI() { return m_dpi; }
inline void setDPI(DPI dpi) { m_dpi = dpi; }
inline const cv::Range getSizeRange() { return m_range; }
inline void setSizeRange(const cv::Range& range) { m_range = range; }
inline void setSizeRange(int low, int up) { m_range = cv::Range(low, up); }
private:
void findMarks(const std::vector<std::vector<cv::Point>>& contours, const cv::RotatedRect& region, const cv::Range& range,
std::vector<std::vector<cv::Point>>& marks, std::vector<cv::RotatedRect>& rrect);
bool isContainBarCode(const cv::Mat& image);
private:
DeviceModel m_device;
bool m_b_isCropped;
double m_threshold;
int m_noise;
DPI m_dpi;
cv::Range m_range;
DirectionMethod m_direction;
};
#endif // IMAGEMARKCROPAPPLY_H

View File

@ -1,4 +1,4 @@
#include "ImageApplyOutHole.h"
#include "ImageApplyOutHole.h"
#include "ImageProcess_Public.h"
#ifdef LOG
@ -53,7 +53,7 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
return;
}
//二值化正反面图像
//二值化正反面图像
cv::Mat front = mats[0];
cv::Mat back = mats[1];
cv::Mat front_thre, back_thre;
@ -64,60 +64,64 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
cv::morphologyEx(front_thre, front_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
cv::morphologyEx(back_thre, back_thre, cv::MORPH_OPEN, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar::all(0));
//反面二值化图像水平翻转
//反面二值化图像水平翻转
cv::flip(back_thre, back_thre, 1); //1:Horizontal
//正反面图像寻边
//正反面图像寻边
std::vector<std::vector<cv::Point>> contours_front, contours_back;
std::vector<cv::Vec4i> b1_front, b1_back;
hg::findContours(front_thre.clone(), contours_front, b1_front, cv::RETR_EXTERNAL);
hg::findContours(back_thre.clone(), contours_back, b1_back, cv::RETR_EXTERNAL);
//提取正反面图像最大轮廓
//提取正反面图像最大轮廓
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
if (maxContour_front.empty() || maxContour_back.empty())
return;
//如果正反面图像尺寸差异超过20个像素直接放弃处理
cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
//如果正反面图像尺寸差异超过20个像素直接放弃处理
if (cv::abs(rrect_front.size.width - rrect_back.size.width) > 20 ||
cv::abs(rrect_front.size.height - rrect_back.size.height) > 20)
return;
//提取正反面图像重叠部分区域
//提取正反面图像重叠部分区域
cv::Rect roi_front, roi_back;
cv::RotatedRect mask_rotatedRect;
getRoi(rrect_front, rrect_back, cv::Size(front.cols, front.rows), roi_front, roi_back, mask_rotatedRect);
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
//正反面二值图像做或运算真正镂空区域保留0其他地方填充为255
cv::Mat mask;
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
getRoi(rrect_front, rrect_back, front.size(), back.size(), roi_front, roi_back, mask_rotatedRect);
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
//cv::imwrite("roiMat_front.jpg", roiMat_front);
//cv::imwrite("roiMat_back.jpg", roiMat_back);
//二值图像重叠图像颜色取反,膨胀,提取轮廓
cv::bitwise_not(mask, mask); //反色
//正反面二值图像做或运算真正镂空区域保留0其他地方填充为255
cv::Mat mask;
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
//cv::imwrite("mask1.jpg", mask);
//二值图像重叠图像颜色取反,膨胀,提取轮廓
cv::bitwise_not(mask, mask);
//cv::imwrite("mask2.jpg", mask); //反色
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10));
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积
//cv::imwrite("mask3.jpg", mask);
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), 15); //绘制纸张矩形边缘
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(255), 15); //绘制纸张矩形边缘
//cv::imwrite("mask4.jpg", mask);
std::vector<std::vector<cv::Point>> contours_mask;
std::vector<cv::Vec4i> b1_mask;
hg::findContours(mask, contours_mask, b1_mask, cv::RETR_TREE); //提取重叠图像轮廓
hg::findContours(mask, contours_mask, b1_mask, cv::RETR_TREE); //提取重叠图像轮廓
//过滤非孔洞的联通区域
//过滤非孔洞的联通区域
std::vector<std::vector<cv::Point>> hole_contours = filterPoly(contours_mask, b1_mask, mask_rotatedRect, m_edgeScale, m_borderSize);
//for (size_t i = 0; i < hole_contours.size(); i++)
// cv::drawContours(mask, hole_contours, static_cast<int>(i), cv::Scalar(127), 2);
//cv::imwrite("mask.jpg", mask);
cv::Scalar color = getBackGroudColor(front(roi_front), rrect_front.size.area());
for (size_t i = 0; i < hole_contours.size(); i++)
{
@ -130,7 +134,7 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
if (isTwoSide)
{
int width_ = roi_back.width;
roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转所以现在ROI也要进行相应翻转
roi_back.x = back.cols - roi_back.width - roi_back.x; //因为之前反面图像翻转所以现在ROI也要进行相应翻转
color = getBackGroudColor(back(roi_back), rrect_front.size.area());
for (size_t i = 0; i < hole_contours.size(); i++)
{
@ -149,62 +153,73 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
#endif // LOG
}
void CImageApplyOutHole::getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize,
cv::Rect& roi_front, cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect)
void CImageApplyOutHole::getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, const cv::Size& srcSize_front, const cv::Size& srcSize_back, cv::Rect& roi_front,
cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect)
{
cv::Size size(static_cast<int>(rrect_front.size.width + rrect_back.size.width) / 2, static_cast<int>(rrect_front.size.height + rrect_back.size.height) / 2);
float angle = (rrect_front.angle + rrect_back.angle) / 2;
cv::Rect roi_front_ = rrect_front.boundingRect();
cv::Rect roi_back_ = rrect_back.boundingRect();
rrect_front.size = rrect_back.size = size;
rrect_front.angle = rrect_back.angle = angle;
cv::Size meanSize = (roi_front_.size() + roi_back_.size()) / 2;
roi_front_.x += (roi_front_.width - meanSize.width) / 2;
roi_front_.width = meanSize.width;
roi_front_.y += (roi_front_.height - meanSize.height) / 2;
roi_front_.height = meanSize.height;
roi_back_.x += (roi_back_.width - meanSize.width) / 2;
roi_back_.width = meanSize.width;
roi_back_.y += (roi_back_.height - meanSize.height) / 2;
roi_back_.height = meanSize.height;
roi_front = rrect_front.boundingRect();
roi_back = rrect_back.boundingRect();
mask_rotatedRect.angle = (rrect_front.angle + rrect_back.angle) / 2;
mask_rotatedRect.size = (rrect_front.size + rrect_back.size) / 2.0f;
mask_rotatedRect.center = cv::Point2f(roi_front_.size().width + roi_back_.size().width, roi_front_.size().height + roi_back_.size().height) / 4.0f;
if (roi_front.width != roi_back.width || roi_front.height != roi_back.height)
roi_front = roi_front_ & cv::Rect(cv::Point(0, 0), srcSize_front);
roi_back = roi_back_ & cv::Rect(cv::Point(0, 0), srcSize_back);
int offset_left_f = roi_front.x - roi_front_.x;
int offset_left_b = roi_back.x - roi_back_.x;
int offset_top_f = roi_front.y - roi_front_.y;
int offset_top_b = roi_back.y - roi_back_.y;
int offset_right_f = roi_front_.br().x - roi_front.br().x;
int offset_right_b = roi_back_.br().x - roi_back.br().x;
int offset_bottom_f = roi_front_.br().y - roi_front.br().y;
int offset_bottom_b = roi_back_.br().y - roi_back.br().y;
if (offset_left_f > offset_left_b)
{
roi_front.height = roi_back.height;
roi_front.width = roi_back.width;
roi_back.x += offset_left_f - offset_left_b;
roi_back.width -= offset_left_f - offset_left_b;
mask_rotatedRect.center.x -= offset_left_f - offset_left_b;
}
else
{
roi_front.x += offset_left_b - offset_left_f;
roi_front.width -= offset_left_b - offset_left_f;
mask_rotatedRect.center.x -= offset_left_b - offset_left_f;
}
cv::Point offset(0, 0);
int top = std::min(roi_front.y, roi_back.y);
if (top < 0)
if (offset_top_f > offset_top_b)
{
roi_front.y -= top;
roi_back.y -= top;
roi_front.height += top;
roi_back.height += top;
offset.y += top;
roi_back.y += offset_top_f - offset_top_b;
roi_back.height -= offset_top_f - offset_top_b;
mask_rotatedRect.center.y -= offset_top_f - offset_top_b;
}
else
{
roi_front.y += offset_top_b - offset_top_f;
roi_front.height -= offset_top_b - offset_top_f;
mask_rotatedRect.center.y -= offset_top_b - offset_top_f;
}
int left = std::min(roi_front.x, roi_back.x);
if (left < 0)
{
roi_front.x -= left;
roi_back.x -= left;
roi_front.width += left;
roi_back.width += left;
offset.x += left;
}
if (offset_right_f > offset_right_b)
roi_back.width -= offset_right_f - offset_right_b;
else
roi_front.width -= offset_right_b - offset_right_f;
int right = std::max(roi_front.x + roi_front.width, roi_back.x + roi_back.width);
if (right >= srcSize.width)
{
roi_front.width -= (right - srcSize.width + 1);
roi_back.width -= (right - srcSize.width + 1);
}
int bottom = std::max(roi_front.y + roi_front.height, roi_back.y + roi_back.height);
if (bottom >= srcSize.height)
{
roi_front.height -= (bottom - srcSize.height + 1);
roi_back.height -= (bottom - srcSize.height + 1);
}
mask_rotatedRect.center = cv::Point((roi_front.width + offset.x) / 2, (roi_front.height + offset.y) / 2);
mask_rotatedRect.size = size;
mask_rotatedRect.angle = angle;
if (offset_bottom_f > offset_bottom_b)
roi_back.height -= offset_bottom_f - offset_bottom_b;
else
roi_front.height -= offset_bottom_b - offset_bottom_f;
}
std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& m,
@ -223,15 +238,19 @@ std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<s
if (m[i][2] != -1) continue;
cv::RotatedRect rrect = hg::getBoundingRect(contours[i]);
if (rrect.size.area() < areaThreshold) continue;
if (rrect.size.width < areaThreshold ||
rrect.size.height < areaThreshold ||
rrect.size.width > areaThreshold * 6 ||
rrect.size.height > areaThreshold * 6)
continue;
bool enabled = true;
for (size_t j = 0, count = contours[i].size(); j < count; j++)
{
cv::Point p(contours[i][j]);
double temp1 = pointPolygonTest(vertices_roi1, p, false); //判断是否在纸张内 10-1
double temp2 = pointPolygonTest(vertices_roi2, p, false); //判断是否在边缘区域内 10-1
//如果在纸张外,或者边缘内,视为非孔洞
double temp1 = pointPolygonTest(vertices_roi1, p, false); //判断是否在纸张内 10-1
double temp2 = pointPolygonTest(vertices_roi2, p, false); //判断是否在边缘区域内 10-1
//如果在纸张外,或者边缘内,视为非孔洞
if (temp1 < 0 || temp2 > 0)
{
enabled = false;
@ -301,10 +320,10 @@ uchar CImageApplyOutHole::getBackGroudChannelMean(const cv::Mat& gray, int total
hist_array[i] = hist.at<float>(i, 0);
int length = 1;
const int length_max = 255 - m_threshold;
const int length_max = 255;
while (length < length_max)
{
for (size_t i = m_threshold + 1; i < 256 - length; i++)
for (size_t i = 1; i < 256 - length; i++)
{
int count = 0;
uint pixSum = 0;

View File

@ -1,16 +1,22 @@
/*
/*
* ====================================================
*
*
* 2020/11/21
* 2020/05/12 v1.0
*
*
* 2020/11/21
* 2020/05/12 v1.0
* 2020/11/17 v1.1
* 2021/09/06 v1.2 50100
* 2021/11/03 v1.3 10穿
* 2021/11/04 v1.4 5
* 2021/11/17 v1.5 opencv版本导致的BUG
* v1.5
* 2021/09/06 v1.2 50100
* 2021/11/03 v1.3 10穿
* 2021/11/04 v1.4 5
* 2021/11/17 v1.5 opencv版本导致的BUG
* 2022/04/18 v1.6 BUG
* 2022/05/04 v1.6.1
* 2022/07/16 v1.6.2 BUG
* 2022/07/18 v1.6.3 mask的一些逻辑错误
* 2022/07/18 v1.7 BUGborderSize逻辑,穿[borderSize, borderSize * 6]
* 2022/07/22 v1.7.1 BUG
* v1.7.1
* ====================================================
*/
@ -20,16 +26,16 @@
#include "ImageApply.h"
class CImageApplyOutHole : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyOutHole : public CImageApply
{
public:
CImageApplyOutHole();
/*
* borderSize [in]:
* edgeScale [in]:(0,0.5),0.1
* threshold [in]:
* borderSize [in]:
* edgeScale [in]:(0,0.5),0.1
* threshold [in]:
*/
CImageApplyOutHole(float borderSize, float edgeScale, double threshold);
@ -53,7 +59,7 @@ private:
virtual void apply(cv::Mat& pDib, int side);
void getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, cv::Size srcSize, cv::Rect& roi_front,
void getRoi(cv::RotatedRect rrect_front, cv::RotatedRect rrect_back, const cv::Size& srcSize_front, const cv::Size& srcSize_back, cv::Rect& roi_front,
cv::Rect& roi_back, cv::RotatedRect& mask_rotatedRect);
std::vector<std::vector<cv::Point> > filterPoly(std::vector<std::vector<cv::Point>>& contours, const std::vector<cv::Vec4i>& m, cv::RotatedRect roi,

View File

@ -17,7 +17,7 @@
#include "ImageApply.h"
class CImageApplyAdjustColors;
class CImageApplyRefuseInflow : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyRefuseInflow : public CImageApply
{
public:
CImageApplyRefuseInflow(int constrast = 15);

View File

@ -25,6 +25,7 @@ void CImageApplyResize::apply(cv::Mat& pDib,int side)
{
(void)side;
if (pDib.empty()) return;
if (m_type == ResizeType::RATIO)
cv::resize(pDib, pDib, cv::Size(0, 0), m_fx, m_fy);
else
@ -34,6 +35,7 @@ void CImageApplyResize::apply(cv::Mat& pDib,int side)
void CImageApplyResize::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
(void)isTwoSide;
int i = 0;
for (cv::Mat& var : mats) {
if (i != 0 && isTwoSide == false)

View File

@ -1,11 +1,11 @@
/*
/*
* ====================================================
*
*
* 2020/4/21
* 2020/4/21
* v1.0
*
*
* 2020/4/21
* 2020/4/21
* v1.0
* ====================================================
*/
@ -15,24 +15,24 @@
#include "ImageApply.h"
class CImageApplyResize : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyResize : public CImageApply
{
public:
enum class ResizeType
{
RATIO, //比例缩放
DSIZE //尺寸缩放
RATIO, //比例缩放
DSIZE //尺寸缩放
};
public:
CImageApplyResize();
/*
* type [in]:
* size [in]:type为DSIZE时生效
* fx [in]:type为RATIO时生效
* fy [in]:type为RATIO时生效
* type [in]:
* size [in]:type为DSIZE时生效
* fx [in]:type为RATIO时生效
* fy [in]:type为RATIO时生效
*/
CImageApplyResize(ResizeType type, const cv::Size& size, double fx, double fy);

View File

@ -1,39 +1,53 @@
#include "ImageApplyRotation.h"
//#define USE_TESSERCAT
//#define USE_HANWANG
//#define HG_GPDF_API_BUILD
#include "hg_ocr.h"
#ifdef _WIN32
#ifdef USE_HANWANG
#include<sstream>
#endif
#endif
CImageApplyRotation::CImageApplyRotation(RotationType rotation, bool isBackTransposed, int dpi, const char* tessdataPath)
: m_rotation(rotation)
, m_backTranspose(isBackTransposed)
, m_dpi(dpi)
, osd(nullptr)
{
if (rotation == RotationType::AutoTextOrientation)
{
#ifdef USE_TESSERCAT
osd = new HG_OCR();
std::string strpath(tessdataPath);
reinterpret_cast<HG_OCR*>(osd)->init(strpath.c_str(), HG_OCR::PSM_TYPE::Orientation);
#ifdef _WIN32
#ifdef USE_HANWANG
, m_ocr(nullptr)
#endif
#endif
{
#ifdef _WIN32
#ifdef USE_HANWANG
if (tessdataPath != nullptr)
{
std::wstringstream wss;
wss << tessdataPath;
m_ocr = new HG_OCR(wss.str().c_str());
}
#endif
#endif
}
CImageApplyRotation::~CImageApplyRotation()
{
#ifdef USE_TESSERCAT
if (osd) delete reinterpret_cast<HG_OCR*>(osd);
#ifdef _WIN32
#ifdef USE_HANWANG
if (m_ocr)
delete m_ocr;
#endif
#endif
}
void CImageApplyRotation::apply(cv::Mat& pDib, int side)
{
m_angleResult = 0;
#ifdef LOG
FileTools::write_log("imgprc.txt", "enter CImageApplyRotation apply");
#endif // LOG
if (pDib.empty())
{
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyRotation apply");
#endif // LOG
return;
}
@ -55,7 +69,9 @@ void CImageApplyRotation::apply(cv::Mat& pDib, int side)
cv::cvtColor(temp, temp, cv::COLOR_BGR2GRAY);
cv::threshold(temp, temp, 180, 255, cv::THRESH_OTSU);
int orientation = HG_OCR::orientation(temp.data, temp.cols, temp.rows, temp.channels());
int orientation = 0;
if (m_ocr)
orientation = m_ocr->orientation(temp.data, temp.cols, temp.rows, temp.channels());
switch (orientation)
{
@ -74,52 +90,6 @@ void CImageApplyRotation::apply(cv::Mat& pDib, int side)
default:
break;
}
#endif
#ifdef USE_TESSERCAT
if (osd)
{
cv::Mat temp;
if (m_dpi != 200)
{
double scale = 200 / static_cast<double>(m_dpi);
int new_w = (static_cast<int>(pDib.cols * scale) + 3) / 4 * 4;
int new_h = pDib.rows * scale;
cv::resize(pDib, temp, cv::Size(new_w, new_h));
}
else
temp = pDib(cv::Rect(0, 0, pDib.cols / 4 * 4, pDib.rows)).clone();
HG_OCR* ptr_osd = reinterpret_cast<HG_OCR*>(osd);
int ori = -1;
int direction = -1;
int order = -1;
float angle = -1;
ptr_osd->getOrientation(temp.data, temp.cols, temp.rows, temp.channels(), temp.step1(),
ori, direction, order, angle);
switch (ori)
{
case 1:
cv::transpose(pDib, pDib);
cv::flip(pDib, pDib, 0);
m_angleResult = 90;
break;
case 2:
cv::flip(pDib, pDib, 0);
cv::flip(pDib, pDib, 1);
m_angleResult = 180;
break;
case 3:
cv::transpose(pDib, pDib);
cv::flip(pDib, pDib, 1);
m_angleResult = 270;
break;
default:
m_angleResult = 0;
break;
}
}
#endif
}
else if (m_backTranspose && side == 1) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת180
@ -130,13 +100,11 @@ void CImageApplyRotation::apply(cv::Mat& pDib, int side)
{
transpose(pDib, pDib);
flip(pDib, pDib, m_rotation == RotationType::Rotate_90_clockwise ? 0 : 1);
m_angleResult = m_rotation == RotationType::Rotate_90_clockwise ? 270 : 90;
}
else
{
flip(pDib, pDib, 0);
flip(pDib, pDib, 1);
m_angleResult = 180;
}
}
}
@ -146,26 +114,25 @@ void CImageApplyRotation::apply(cv::Mat& pDib, int side)
{
transpose(pDib, pDib);
flip(pDib, pDib, m_rotation == RotationType::Rotate_90_clockwise ? 1 : 0);
m_angleResult = m_rotation == RotationType::Rotate_90_clockwise ? 90 : 270;
}
else if (m_rotation == RotationType::Rotate_180)
{
flip(pDib, pDib, 0);
flip(pDib, pDib, 1);
m_angleResult = 180;
}
}
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyRotation apply");
#endif // LOG
}
void CImageApplyRotation::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
(void)isTwoSide;
m_angleResults.clear();
int i = 0;
for (cv::Mat& var : mats) {
if (!var.empty()) {
apply(var, i);
m_angleResults.push_back(m_angleResult);
i++;
}
}

View File

@ -1,23 +1,52 @@
/*
* ====================================================
*
*
* 2020/4/21
* v1.0 2020/04/21
v1.1 2020/08/12 稿BUG
v1.2 2021/10/15 稿
v1.2.1 2022/04/25
* v1.2.1
* ====================================================
*/
#ifndef IMAGE_APPLY_ROTATION_H
#define IMAGE_APPLY_ROTATION_H
#include "ImageApply.h"
class CImageApplyRotation : public CImageApply
#ifdef _WIN32
//#define USE_HANWANG
#ifdef USE_HANWANG
#define HG_GPDF_API_BUILD
#include <hg_gpdf.h>
#endif
#endif
class GIMGPROC_LIBRARY_API CImageApplyRotation : public CImageApply
{
public:
enum class RotationType
{
Invalid,
Rotate_90_clockwise,
Rotate_180,
Rotate_90_anti_clockwise,
Invalid, //无效
Rotate_90_clockwise, //顺时针90°
Rotate_180, //180°
Rotate_90_anti_clockwise, //逆时针90°即270°
AutoTextOrientation
AutoTextOrientation //自动文稿方向识别旋转
};
public:
/*
* rotation [in]:
* isBackTransposed [in]:true为背面180°
* dpi [in]:DPIrotation为AutoTextOrientation时生效稿200DPI进行识别
* tessadataPath [in]:rotation为AutoTextOrientation时生效
*/
CImageApplyRotation(RotationType rotation, bool isBackTransposed = false, int dpi = 200, const char* tessdataPath = nullptr);
virtual ~CImageApplyRotation();
@ -30,10 +59,6 @@ public:
int getDPI() { return m_dpi; }
int angleResult() { return m_angleResult; }
const std::vector<int>& angleResults() { return m_angleResults; }
RotationType getRotationType() { return m_rotation; }
void setBackTransposed(bool enabled) { m_backTranspose = enabled; }
@ -47,10 +72,11 @@ private:
bool m_backTranspose;
int m_dpi;
void* osd;
int m_angleResult;
std::vector<int> m_angleResults;
#ifdef _WIN32
#ifdef USE_HANWANG
HG_OCR* m_ocr;
#endif
#endif
};
#endif // !IMAGE_APPLY_ROTATION_H

View File

@ -1,4 +1,4 @@
#include "ImageApplySizeDetection.h"
#include "ImageApplySizeDetection.h"
#include "ImageProcess_Public.h"
CImageApplySizeDetection::CImageApplySizeDetection(int paperType, int thre_x, int thre_y)
@ -6,7 +6,6 @@ CImageApplySizeDetection::CImageApplySizeDetection(int paperType, int thre_x, in
, m_thre_x(thre_x)
, m_thre_y(thre_y)
{
printf("\n paperType =%d \r\n", paperType);
}
CImageApplySizeDetection::~CImageApplySizeDetection()
@ -34,7 +33,7 @@ int CImageApplySizeDetection::apply(const cv::Mat& pDib)
printf("\n width =%f ,height = %f ", width, height);
HGSize dstSize;
if (m_supportPaper.count((PaperSize)m_paperType) > 0)//包含设置的幅面
if (m_supportPaper.count((PaperSize)m_paperType) > 0)//包含设置的幅面
{
dstSize = m_supportPaper[(PaperSize)m_paperType];
if ((width > (dstSize.width + m_thre_x)) ||

View File

@ -1,11 +1,11 @@
/*
* ====================================================
*
*
* 2022/05/11
* 2022/05/11
* v1.0
*
*
* 2022/05/11
* 2022/05/11
* v1.0
* ====================================================
*/
@ -15,8 +15,7 @@
#include "ImageApply.h"
#include<map>
class CImageApplySizeDetection
class GIMGPROC_LIBRARY_API CImageApplySizeDetection
{
public:
enum PaperSize

View File

@ -21,8 +21,8 @@ std::vector<MatEx> CImageApplySplit::SplitMats(std::vector<cv::Mat>& mats, bool
{
if (mats[i].empty())
continue;
// if (i != 0 && isTwoSide == false)
// break;
if (i != 0 && isTwoSide == false)
break;
int bpp = getBpp(i);
if (m_split)//²ð·Ö
@ -39,8 +39,6 @@ std::vector<MatEx> CImageApplySplit::SplitMats(std::vector<cv::Mat>& mats, bool
for (size_t j = 0; j < retmats.size(); j++)
{
if (!retmats[j].empty()) {
cv::transpose(retmats[j],retmats[j]);
cv::flip(retmats[j],retmats[j],i==0?1:0);
MatEx matex(retmats[j], bpp);
rets.push_back(matex);
}

View File

@ -16,18 +16,16 @@
#include <vector>
#include "imgprocdefs.h"
class CImageApplySplit
class GIMGPROC_LIBRARY_API CImageApplySplit
{
public:
CImageApplySplit(int multitype=-1,bool split=false,bool ismulti_filter_red=false,int colormode=1);//默认不多流输出 不多流除红 灰度
~CImageApplySplit(void);
std::vector<MatEx> SplitMats(std::vector<cv::Mat>& mats, bool isTwoSide);
//private:
private:
std::vector<cv::Mat> apply(cv::Mat& pDib);
int getBpp(int matIndex);
private://field
bool m_bmulti_filter_red;
int m_multitype;

View File

@ -56,17 +56,22 @@ cv::Mat createFilter(const cv::Mat& spectrum, int dilateSize, int erodeSize)
{
cv::Mat temp;
spectrum.convertTo(temp, CV_8UC1, 255);
//cv::imwrite("filter/temp.bmp", temp);
cv::threshold(temp, temp, 0, 255, CV_THRESH_OTSU);
//imshow("二值化", temp);
//cv::imwrite("filter/temp1.bmp", temp);
cv::Mat element1 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(dilateSize, dilateSize));
cv::Mat element2 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(erodeSize, erodeSize));
cv::line(temp, cv::Point(0, temp.rows / 2), cv::Point(temp.cols - 1, temp.rows / 2), cv::Scalar(255));
cv::line(temp, cv::Point(temp.cols / 2, 0), cv::Point(temp.cols / 2, temp.rows - 1), cv::Scalar(255));
cv::dilate(temp, temp, element1);
cv::erode(temp, temp, element2);
//cv::imwrite("filter/temp2.bmp", temp);
cv::floodFill(temp, cv::Point(temp.cols / 2, temp.rows / 2), cv::Scalar(0)); //漫水填充中心区域
cv::medianBlur(~temp, temp, 3); //中值滤波
cv::blur(~temp, temp, cv::Size(3, 3)); //中值滤波
//cv::imwrite("filter/temp3.bmp", temp);
//temp = ~temp;
//cv::imshow("二值化", temp);
//陷波滤波器复制
cv::Mat filter;
@ -83,12 +88,16 @@ cv::Mat createFilter(const cv::Mat& spectrum, int dilateSize, int erodeSize)
void CImageApplyTextureRemoval::textureRemovalGray(cv::Mat& img)
{
//得到DFT的最佳尺寸2的指数以加速计算
cv::Mat resizeMat;
cv::resize(img, resizeMat, cv::Size(), 0.5, 0.5);
cv::Mat paddedImg;
int m = cv::getOptimalDFTSize(img.rows);
int n = cv::getOptimalDFTSize(img.cols);
int m = cv::getOptimalDFTSize(resizeMat.rows);
int n = cv::getOptimalDFTSize(resizeMat.cols);
//填充图像的下端和右端
cv::copyMakeBorder(img, paddedImg, 0, m - img.rows, 0, n - img.cols,
cv::copyMakeBorder(resizeMat, paddedImg, 0, m - resizeMat.rows, 0, n - resizeMat.cols,
cv::BORDER_CONSTANT, cv::Scalar::all(0));
//将填充的图像组成一个复数的二维数组两个通道的Mat用于DFT
@ -110,8 +119,16 @@ void CImageApplyTextureRemoval::textureRemovalGray(cv::Mat& img)
cv::merge(matArray, 2, complexOutput);
cv::multiply(complexOutput, filter, filter);
//IDFT得到滤波结果
cv::Size imgSize = img.size();
m = cv::getOptimalDFTSize(img.rows);
n = cv::getOptimalDFTSize(img.cols);
//填充图像的下端和右端
cv::copyMakeBorder(img, img, 0, m - img.rows, 0, n - img.cols,
cv::BORDER_CONSTANT, cv::Scalar::all(0));
cv::copyMakeBorder(filter, filter, 0, m - filter.rows, 0, n - filter.cols,
cv::BORDER_CONSTANT, cv::Scalar::all(0));
//IDFT得到滤波结果
inverseFourierTransform(filter, img);
img = img(cv::Rect(cv::Point(0, 0), imgSize));
img *= 255;
@ -120,8 +137,8 @@ void CImageApplyTextureRemoval::textureRemovalGray(cv::Mat& img)
CImageApplyTextureRemoval::CImageApplyTextureRemoval()
: CImageApply()
, m_dilateSize(5)
, m_erodeSize(3)
, m_dilateSize(9)
, m_erodeSize(5)
{
}
@ -153,8 +170,6 @@ void CImageApplyTextureRemoval::apply(cv::Mat &pDib, int side)
textureRemovalGray(var);
cv::merge(rgb, pDib);
}
pDib *= 1.15;
}
void CImageApplyTextureRemoval::apply(std::vector<cv::Mat>& mats, bool isTwoSide)

View File

@ -1,11 +1,12 @@
/*
/*
* ====================================================
*
*
* 2020/4/21
* 2020/4/21
* v1.0
*
*
* 2020/4/21
* 2020/4/21 v1.0
* 2022/4/09 v1.1
* v1.1
* ====================================================
*/
@ -15,14 +16,14 @@
#include "ImageApply.h"
class CImageApplyTextureRemoval : public CImageApply
class GIMGPROC_LIBRARY_API CImageApplyTextureRemoval : public CImageApply
{
public:
CImageApplyTextureRemoval(void);
/*
* dilateSize [in]:
* erodeSize [in]:
* dilateSize [in]:
* erodeSize [in]:
*/
CImageApplyTextureRemoval(int dilateSize, int erodeSize);

View File

@ -0,0 +1,186 @@
#include "ImageApplyUVMerge.h"
#include "ImageProcess_Public.h"
using namespace cv;
#define SCA 50
CImageApplyUVMerge::CImageApplyUVMerge(): lut(1, 256, CV_8UC1)
{
}
CImageApplyUVMerge::~CImageApplyUVMerge()
{
}
void CImageApplyUVMerge::update_lutData(int contrast)
{
unsigned char* ptr = lut.data;
int m_contrast = cv::max(-127, cv::min(contrast, 127));
for (int i = 0; i < 256; i++)
{
//update contrast
if (i < 128)
ptr[i] = static_cast<unsigned char>(cv::max(0, cv::min(i - m_contrast, 127)));
else
ptr[i] = static_cast<unsigned char>(cv::max(127, cv::min(i + m_contrast, 255)));
}
}
void CImageApplyUVMerge::Apply(cv::Mat& image, const cv::Mat& uv, int dpi, int thresh)
{
update_lutData(12);
cv::LUT(uv, lut, uv);
Mat uv_resize;
cv::resize(uv, uv_resize, cv::Size(uv.cols * SCA / dpi, uv.rows * SCA / dpi));
if (uv_resize.channels() == 3)
cv::cvtColor(uv_resize, uv_resize, cv::COLOR_BGR2GRAY);
cv::threshold(uv_resize, uv_resize, 0, 255, THRESH_OTSU);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1500 / dpi, 1500 / dpi));
cv::dilate(uv_resize, uv_resize, element);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
hg::findContours(uv_resize, contours, hierarchy, cv::RETR_EXTERNAL);
std::map<int, cv::Scalar> map_color;
for (int i = 0; i < contours.size(); i++)
{
cv::Rect roi = cv::boundingRect(contours[i]);
roi.x *= dpi / SCA;
roi.y *= dpi / SCA;
roi.width *= dpi / SCA;
roi.height *= dpi / SCA;
purgeQR_kernal(image, roi, map_color, dpi, thresh);
}
}
cv::Mat CImageApplyUVMerge::Apply(const cv::Mat& image, const cv::Mat& uv, const cv::RotatedRect& uvRoi, bool isDesaskew, int angle)
{
if (uvRoi.size.width == 0) return cv::Mat();
cv::RotatedRect uvRoi_clone = uvRoi;
cv::Mat dst = cv::Mat::zeros(image.rows > image.cols ? image.rows : (image.rows * 2), image.cols > image.rows ? image.cols : (image.cols * 2), image.type());
image.copyTo(dst(cv::Rect(0, 0, image.cols, image.rows)));
cv::Mat dst_uv = dst(cv::Rect(image.rows > image.cols ? image.cols : 0, image.rows > image.cols ? 0 : image.rows, image.cols, image.rows));
if (isDesaskew)
{
cv::Point2f srcTri[4];
cv::Point2f dstTri[3];
uvRoi_clone.points(srcTri);
if (angle == 90)
{
dstTri[0] = cv::Point2f(0, 0);
dstTri[1] = cv::Point2f(dst_uv.cols - 1, 0);
dstTri[2] = cv::Point2f(dst_uv.cols - 1, dst_uv.rows - 1);
}
else if (angle == 180)
{
dstTri[0] = cv::Point2f(dst_uv.cols - 1, 0);
dstTri[1] = cv::Point2f(dst_uv.cols - 1, dst_uv.rows - 1);
dstTri[2] = cv::Point2f(0, dst_uv.rows - 1);
}
else if (angle == 270)
{
dstTri[0] = cv::Point2f(dst_uv.cols - 1, dst_uv.rows - 1);
dstTri[1] = cv::Point2f(0, dst_uv.rows - 1);
dstTri[2] = cv::Point2f(0, 0);
}
else
{
dstTri[0] = cv::Point2f(0, dst_uv.rows - 1);
dstTri[1] = cv::Point2f(0, 0);
dstTri[2] = cv::Point2f(dst_uv.cols - 1, 0);
}
cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri);
if (uv.channels() == 1 && dst_uv.channels() == 3)
{
cv::Mat uv_temp;
cv::warpAffine(uv, uv_temp, warp_mat, dst_uv.size());
cv::cvtColor(uv_temp, dst_uv, cv::COLOR_GRAY2BGR);
}
else
cv::warpAffine(uv, dst_uv, warp_mat, dst_uv.size());
}
else
{
cv::Rect uvBoundingRect = uvRoi_clone.boundingRect();
cv::Rect roi_dst_right;
roi_dst_right.x = dst_uv.cols > uvBoundingRect.width ? (dst_uv.cols - uvBoundingRect.width) / 2 : 0;
roi_dst_right.width = cv::min(dst_uv.cols, uvBoundingRect.width);
roi_dst_right.y = dst_uv.rows > uvBoundingRect.height ? (dst_uv.rows - uvBoundingRect.height) / 2 : 0;
roi_dst_right.height = cv::min(dst_uv.rows, uvBoundingRect.height);
cv::Rect roi_uv_BoundingRect((uvBoundingRect.width - roi_dst_right.width) / 2,
(uvBoundingRect.height - roi_dst_right.height) / 2, roi_dst_right.width, roi_dst_right.height);
Mat uvCrop = (uv(uvBoundingRect))(roi_uv_BoundingRect);
if (uvCrop.channels() == 1 && dst_uv.channels() == 3)
cv::cvtColor(uvCrop, uvCrop, cv::COLOR_GRAY2BGR);
uvCrop.copyTo(dst_uv(roi_dst_right));
}
return dst;
}
void CImageApplyUVMerge::purgeQR_kernal(cv::Mat& image, const cv::Rect& roi, std::map<int, cv::Scalar> map_color, int dpi, int threshold)
{
cv::Mat image_roi = image(roi);
cv::Mat mask;
cv::cvtColor(image_roi, mask, cv::COLOR_BGR2GRAY);
cv::threshold(mask, mask, 127, 255, cv::THRESH_OTSU);
cv::Mat image_resize;
cv::resize(image, image_resize, cv::Size(image.cols, 800));
for (int i = 0, cols = image_roi.cols, rows = image_roi.rows; i < cols; i++)
{
cv::Scalar color_fill;
if (map_color.find(i + roi.x) == map_color.end())
{
color_fill = getColor(image_resize, roi.x + i, threshold);
map_color[i + roi.x] = color_fill;
}
else
color_fill = map_color[i + roi.x];
for (int j = 0; j < rows; j++)
{
if (*mask.ptr<uchar>(j, i))
{
uchar* color = image_roi.ptr<uchar>(j, i);
color[0] = color_fill[0];
color[1] = color_fill[1];
color[2] = color_fill[2];
}
}
}
}
cv::Scalar CImageApplyUVMerge::getColor(const cv::Mat& image, int col, int threshold)
{
cv::Scalar color(0, 0, 0);
int num = 0;
for (int i = 0, length = image.rows; i < length; i++)
{
const uchar* ptr = image.ptr<uchar>(i, col);
int gray = (ptr[0] * 30 + ptr[1] * 59 + ptr[2] * 11) / 100;
if (gray > threshold)
{
color[0] += ptr[0];
color[1] += ptr[1];
color[2] += ptr[2];
num++;
}
}
if (num)
color /= num;
else
color[0] = color[1] = color[2] = 255;
return color;
}

View File

@ -0,0 +1,34 @@
/*
* ====================================================
* <EFBFBD><EFBFBD><EFBFBD>ܣ<EFBFBD>UVͼ<EFBFBD><EFBFBD>ԭͼ<EFBFBD>ϲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭͼ<EFBFBD><EFBFBD>ƫ<EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD>Լ<EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UV<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭͼ<EFBFBD>Ĵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭͼƴ<EFBFBD><EFBFBD>Ϊһ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD>
<EFBFBD>ù<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>UVһ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ά
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD>2020/7/20
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>ʱ<EFBFBD>2020/7/20
* <EFBFBD><EFBFBD>ţ<EFBFBD>v1.0 2020/7/20
* ====================================================
*/
#ifndef IMAGE_APPLY_UV_MERGE_H
#define IMAGE_APPLY_UV_MERGE_H
#include "ImageApply.h"
#include <map>
class GIMGPROC_LIBRARY_API CImageApplyUVMerge
{
public:
CImageApplyUVMerge();
~CImageApplyUVMerge();
void Apply(cv::Mat& image, const cv::Mat& uv, int dpi = 200, int thresh = 100);
static cv::Mat Apply(const cv::Mat& image, const cv::Mat& uv, const cv::RotatedRect& uvRoi, bool isDesaskew, int angle);
private:
void purgeQR_kernal(cv::Mat& image, const cv::Rect& roi, std::map<int, cv::Scalar> map_color, int dpi, int threshold);
cv::Scalar getColor(const cv::Mat& image, int col, int threshold);
void update_lutData(int contrast);
cv::Mat lut;
};
#endif // !IMAGE_APPLY_UV_MERGE_H

View File

@ -2,7 +2,7 @@
#define IMAGE_MULTI_H
#include "IMulti.h"
class IMageMulti
class GIMGPROC_LIBRARY_API IMageMulti
:public IMulti
{
public:

View File

@ -2,7 +2,7 @@
#define IMAGE_MULTI_OUTPUT_RED_H
#include "IMulti.h"
class ImageMultiOutputRed
class GIMGPROC_LIBRARY_API ImageMultiOutputRed
:public IMulti
{
public:

View File

@ -0,0 +1,165 @@
#-------------------------------------------------
#
# Project created by QtCreator 2019-12-29T09:49:19
#
#-------------------------------------------------
QT -= core gui
TARGET = hgimgproc
TEMPLATE = lib
DEFINES += GIMGPROC_LIBRARY GIMGPROC_LIBRARY_BUILD
# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
#DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
INCLUDEPATH += $$PWD/../Tirdparty/3rdparty/nick
DEPENDPATH += $$PWD/../Tirdparty/3rdparty/nick
win32 {
DEFINES += _WIN32
INCLUDEPATH += $$PWD/../gpdf
DEPENDPATH += $$PWD/../gpdf
INCLUDEPATH += $$PWD/../Tirdparty/3party/3rdparty/win/hgOCR/include
DEPENDPATH += $$PWD/../Tirdparty/3rdparty/win/hgOCR/include
INCLUDEPATH += $$PWD/../Tirdparty/3rdparty/win/opencv/include
DEPENDPATH += $$PWD/../Tirdparty/3rdparty/win/opencv/include
LIBS += -L$$PWD/../Tirdparty/3rdparty/win/hgOCR/x86/lib
INCLUDEPATH += $$PWD/include
contains(QT_ARCH, i386) {
CONFIG(release, debug|release) {
DESTDIR += ../bin/x86/release
LIBS += -L$$PWD/../Tirdparty/3rdparty/win/opencv/lib/x86/Release -lopencv_world346
LIBS += -L$$PWD/../bin/x86/release -lhg_gpdf
#LIBS += -L$$PWD/lib/release -lzxing -lzbar
LIBS += -lwinmm
}
CONFIG(debug, debug|release) {
DESTDIR += ../bin/x86/debug
LIBS += -L$$PWD/../Tirdparty/3rdparty/win/opencv/lib/x86/Debug -lopencv_world346d
LIBS += -L$$PWD/../bin/x86/debug -lhg_gpdf
#LIBS += -L$$PWD/lib/debug -lzxing -lzbar
LIBS += -lwinmm
}
} else {
CONFIG(release, debug|release) {
DESTDIR += ../bin/x64/release
LIBS += -L$$PWD/../Tirdparty/3rdparty/win/opencv/lib/x64/Release -lopencv_world346
LIBS += -L$$PWD/../bin/x64/release -lhg_gpdf
}
CONFIG(debug, debug|release) {
DESTDIR += ../bin/x64/debug
LIBS += -L$$PWD/../Tirdparty/3rdparty/win/opencv/lib/x64/Debug -lopencv_world346d
LIBS += -L$$PWD/../bin/x64/debug -lhg_gpdf
}
}
}
else:unix:!macx: {
#LIBS += -lopencv_world
#linux系统上面需安装opencv3.4.6
INCLUDEPATH += $$PWD/../Tirdparty/3rdparty/opencv/include
CONFIG(debug, debug|release) {
DESTDIR += ../bin/x86/debug
LIBS += -L$$PWD/../Tirdparty/3rdparty/opencv/lib/Debug -lopencv_world -llibtiff -llibjpeg-turbo -lIlmImf -littnotify -llibjasper \
-llibprotobuf -llibwebp -llibpng -lquirc -lzlib
#LIBS += -L$$PWD/../bin/x86/debug -lhg_gpdf
}
CONFIG(release, debug|release) {
DESTDIR += ../bin/x86/release
LIBS += -L$$PWD/../Tirdparty/3rdparty/opencv/lib/Debug -lopencv_world -llibtiff -llibjpeg-turbo -lIlmImf -littnotify -llibjasper \
-llibprotobuf -llibwebp -llibpng -lquirc -lzlib
#LIBS += -L$$PWD/../bin/x86/release -lhg_gpdf
}
}
SOURCES += \
ImageApply.cpp \
ImageApplyAdjustColors.cpp \
ImageApplyAutoContrast.cpp \
ImageApplyAutoCrop.cpp \
ImageApplyBWBinaray.cpp \
#ImageApplyBarCodeRecognition.cpp \
ImageApplyChannel.cpp \
ImageApplyColorRecognition.cpp \
ImageApplyConcatenation.cpp \
ImageApplyCustomCrop.cpp \
ImageApplyCustomGamma.cpp \
ImageApplyCvtColor.cpp \
ImageApplyDetachNoise.cpp \
ImageApplyDiscardBlank.cpp \
ImageApplyDispersion.cpp \
ImageApplyDogEarDetection.cpp \
ImageApplyFadeBackGroundColor.cpp \
ImageApplyFilter.cpp \
ImageApplyHSVCorrect.cpp \
ImageApplyMarkCrop.cpp \
ImageApplyOutHole.cpp \
ImageApplyRefuseInflow.cpp \
ImageApplyResize.cpp \
ImageApplyRotation.cpp \
ImageApplySizeDetection.cpp \
ImageApplySplit.cpp \
ImageApplyTextureRemoval.cpp \
#ImageApplyUVMerge.cpp \
ImageMulti.cpp \
ImageMultiOutputRed.cpp \
ImageProcess_Public.cpp \
IMulti.cpp
HEADERS += \
ImageApply.h \
ImageApplyAdjustColors.h \
ImageApplyAutoContrast.h \
ImageApplyAutoCrop.h \
ImageApplyBWBinaray.h \
#ImageApplyBarCodeRecognition.h \
ImageApplyChannel.h \
ImageApplyColorRecognition.h \
ImageApplyConcatenation.h \
ImageApplyCustomCrop.h \
ImageApplyCustomGamma.h \
ImageApplyCvtColor.h \
ImageApplyDetachNoise.h \
ImageApplyDiscardBlank.h \
ImageApplyDispersion.h \
ImageApplyDogEarDetection.h \
ImageApplyFadeBackGroundColor.h \
ImageApplyFilter.h \
ImageApplyHSVCorrect.h \
ImageApplyHeaders.h \
ImageApplyMarkCrop.h \
ImageApplyOutHole.h \
ImageApplyRefuseInflow.h \
ImageApplyResize.h \
ImageApplyRotation.h \
ImageApplySizeDetection.h \
ImageApplySplit.h \
ImageApplyTextureRemoval.h \
#ImageApplyUVMerge.h \
ImageMulti.h \
ImageMultiOutputRed.h \
ImageProcess_Public.h \
IMulti.h\
imgprocdefs.h
#VERSION = 1.0.0.0
QMAKE_TARGET_PRODUCT = "gimgproc"
QMAKE_TARGET_COMPANY = "huagaoscan"
QMAKE_TARGET_DESCRIPTION = "文件描述"
QMAKE_TARGET_COPYRIGHT = "版权"

View File

@ -7,7 +7,7 @@ namespace hg
CvMemStorage* storage = cvCreateMemStorage(); //
CvSeq* ptseq = cvCreateSeq(CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof(CvContour), sizeof(CvPoint), storage); //ptseqstorage
//
//将src的点集填充至ptseq
for (const cv::Point& item : src)
{
CvPoint p;
@ -16,15 +16,22 @@ namespace hg
cvSeqPush(ptseq, &p);
}
//¦Ìhullstorage
//获取轮廓点
CvSeq* hull = cvConvexHull2(ptseq, nullptr, clockwise ? CV_CLOCKWISE : CV_COUNTER_CLOCKWISE, 0);
//dst
if (hull == nullptr)
{
//释放storage
cvReleaseMemStorage(&storage);
return;
}
//填充dst
dst.clear();
for (int i = 0, hullCount = hull->total; i < hullCount; i++)
dst.push_back(**CV_GET_SEQ_ELEM(CvPoint*, hull, i));
//storage
//释放storage
cvReleaseMemStorage(&storage);
}
@ -143,15 +150,22 @@ namespace hg
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy, int retr, int method, cv::Point offset)
{
#if CV_VERSION_REVISION <= 6
CvMat c_image = src;
#else
CvMat c_image;
CV_DbgAssert(src.dims <= 2);
c_image = cvMat(src.rows, src.dims == 1 ? 1 : src.cols, src.type(), src.data);
c_image.step = (int)src.step[0];
c_image = cvMat(src.rows, src.cols, src.type(), src.data);
c_image.step = src.step[0];
c_image.type = (c_image.type & ~cv::Mat::CONTINUOUS_FLAG) | (src.flags & cv::Mat::CONTINUOUS_FLAG);
#endif
cv::MemStorage storage(cvCreateMemStorage());
CvSeq* _ccontours = nullptr;
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint({ offset.x,offset.y }));
#if CV_VERSION_REVISION <= 6
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint(offset));
#else
cvFindContours(&c_image, storage, &_ccontours, sizeof(CvContour), retr, method, CvPoint{ offset.x, offset.y });
#endif
if (!_ccontours)
{
contours.clear();
@ -203,7 +217,6 @@ namespace hg
rect.size.width = rect.size.height;
rect.size.height = temp;
}
if (rect.angle > 45)
{
rect.angle -= 90;

View File

@ -5,7 +5,9 @@
*
* 2020/4/21
* 2020/4/21
* v1.0
* 2021/07/12 v1.1 getBoundingRect中 angle > 90
* 2021/07/22 v1.2 convexHull中BUG
* v1.2
* ====================================================
*/
@ -13,7 +15,7 @@
#ifndef IMAGE_PROCESS_PUBLIC_H
#define IMAGE_PROCESS_PUBLIC_H
#include <opencv2/opencv.hpp>
#include "opencv2/opencv.hpp"
#include <vector>
namespace hg
@ -53,6 +55,11 @@ namespace hg
void findContours(const cv::Mat& src, std::vector<std::vector<cv::Point>>& contours, std::vector<cv::Vec4i>& hierarchy,
int retr = cv::RETR_LIST, int method = cv::CHAIN_APPROX_SIMPLE, cv::Point offset = cv::Point(0, 0));
/*
*
* contour:
* :
*/
cv::RotatedRect getBoundingRect(const std::vector<cv::Point>& contour);
/*

View File

@ -9,11 +9,11 @@ public:
};
MatEx(cv::Mat &mat, int bpp) :
MatEx(cv::Mat mat, int bpp) :
mat(cv::Mat())
, Bpp(bpp)
{
this->mat = mat;
this->mat = mat.clone();
this->Bpp = bpp;
}
public:

View File

@ -1,22 +1,21 @@
#ifndef IMAGE_PROCESS_DEFINES_H
#define IMAGE_PROCESS_DEFINES_H
//#if defined(_MSC_VER)
//# define HT_DECL_EXPORT __declspec(dllexport)
//# define HT_DECL_IMPORT __declspec(dllimport)
//#elif defined(__linux__) || defined(__linux)
//# define HT_DECL_EXPORT __attribute__((visibility("default")))
//# define HT_DECL_IMPORT __attribute__((visibility("default")))
//# define HT_DECL_HIDDEN __attribute__((visibility("hidden")))
//#endif
//
//#if defined(GIMGPROC_LIBRARY_BUILD)
//#define HT_DECL_EXPORT
//#elif defined(_DIRECT_BUILD)
//#define
//#else
////#define HT_DECL_IMPORT
//#endif
#define IMAGE_PROCESS_DEFINES_H
#if defined(_MSC_VER)
# define HT_DECL_EXPORT __declspec(dllexport)
# define HT_DECL_IMPORT __declspec(dllimport)
#elif defined(__linux__) || defined(__linux)
# define HT_DECL_EXPORT __attribute__((visibility("default")))
# define HT_DECL_IMPORT __attribute__((visibility("default")))
# define HT_DECL_HIDDEN __attribute__((visibility("hidden")))
#endif
#if defined(GIMGPROC_LIBRARY_BUILD)
#define GIMGPROC_LIBRARY_API HT_DECL_EXPORT
#elif defined(_DIRECT_BUILD)
#define GIMGPROC_LIBRARY_API
#else
#define GIMGPROC_LIBRARY_API HT_DECL_IMPORT
#endif
#endif // !IMAGE_PROCESS_DEFINES_H

View File

@ -0,0 +1,215 @@
#ifndef BIGINTEGER_H
#define BIGINTEGER_H
#include "BigUnsigned.hh"
/* A BigInteger object represents a signed integer of size limited only by
* available memory. BigUnsigneds support most mathematical operators and can
* be converted to and from most primitive integer types.
*
* A BigInteger is just an aggregate of a BigUnsigned and a sign. (It is no
* longer derived from BigUnsigned because that led to harmful implicit
* conversions.) */
class BigInteger {
public:
typedef BigUnsigned::Blk Blk;
typedef BigUnsigned::Index Index;
typedef BigUnsigned::CmpRes CmpRes;
static const CmpRes
less = BigUnsigned::less ,
equal = BigUnsigned::equal ,
greater = BigUnsigned::greater;
// Enumeration for the sign of a BigInteger.
enum Sign { negative = -1, zero = 0, positive = 1 };
protected:
Sign sign;
BigUnsigned mag;
public:
// Constructs zero.
BigInteger() : sign(zero), mag() {}
// Copy constructor
BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {};
// Assignment operator
void operator=(const BigInteger &x);
// Constructor that copies from a given array of blocks with a sign.
BigInteger(const Blk *b, Index blen, Sign s);
// Nonnegative constructor that copies from a given array of blocks.
BigInteger(const Blk *b, Index blen) : mag(b, blen) {
sign = mag.isZero() ? zero : positive;
}
// Constructor from a BigUnsigned and a sign
BigInteger(const BigUnsigned &x, Sign s);
// Nonnegative constructor from a BigUnsigned
BigInteger(const BigUnsigned &x) : mag(x) {
sign = mag.isZero() ? zero : positive;
}
// Constructors from primitive integer types
BigInteger(unsigned long x);
BigInteger( long x);
BigInteger(unsigned int x);
BigInteger( int x);
BigInteger(unsigned short x);
BigInteger( short x);
/* Converters to primitive integer types
* The implicit conversion operators caused trouble, so these are now
* named. */
unsigned long toUnsignedLong () const;
long toLong () const;
unsigned int toUnsignedInt () const;
int toInt () const;
unsigned short toUnsignedShort() const;
short toShort () const;
protected:
// Helper
template <class X> X convertToUnsignedPrimitive() const;
template <class X, class UX> X convertToSignedPrimitive() const;
public:
// ACCESSORS
Sign getSign() const { return sign; }
/* The client can't do any harm by holding a read-only reference to the
* magnitude. */
const BigUnsigned &getMagnitude() const { return mag; }
// Some accessors that go through to the magnitude
Index getLength() const { return mag.getLength(); }
Index getCapacity() const { return mag.getCapacity(); }
Blk getBlock(Index i) const { return mag.getBlock(i); }
bool isZero() const { return sign == zero; } // A bit special
// COMPARISONS
// Compares this to x like Perl's <=>
CmpRes compareTo(const BigInteger &x) const;
// Ordinary comparison operators
bool operator ==(const BigInteger &x) const {
return sign == x.sign && mag == x.mag;
}
bool operator !=(const BigInteger &x) const { return !operator ==(x); };
bool operator < (const BigInteger &x) const { return compareTo(x) == less ; }
bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
bool operator >=(const BigInteger &x) const { return compareTo(x) != less ; }
bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
// OPERATORS -- See the discussion in BigUnsigned.hh.
void add (const BigInteger &a, const BigInteger &b);
void subtract(const BigInteger &a, const BigInteger &b);
void multiply(const BigInteger &a, const BigInteger &b);
/* See the comment on BigUnsigned::divideWithRemainder. Semantics
* differ from those of primitive integers when negatives and/or zeros
* are involved. */
void divideWithRemainder(const BigInteger &b, BigInteger &q);
void negate(const BigInteger &a);
/* Bitwise operators are not provided for BigIntegers. Use
* getMagnitude to get the magnitude and operate on that instead. */
BigInteger operator +(const BigInteger &x) const;
BigInteger operator -(const BigInteger &x) const;
BigInteger operator *(const BigInteger &x) const;
BigInteger operator /(const BigInteger &x) const;
BigInteger operator %(const BigInteger &x) const;
BigInteger operator -() const;
void operator +=(const BigInteger &x);
void operator -=(const BigInteger &x);
void operator *=(const BigInteger &x);
void operator /=(const BigInteger &x);
void operator %=(const BigInteger &x);
void flipSign();
// INCREMENT/DECREMENT OPERATORS
void operator ++( );
void operator ++(int);
void operator --( );
void operator --(int);
};
// NORMAL OPERATORS
/* These create an object to hold the result and invoke
* the appropriate put-here operation on it, passing
* this and x. The new object is then returned. */
inline BigInteger BigInteger::operator +(const BigInteger &x) const {
BigInteger ans;
ans.add(*this, x);
return ans;
}
inline BigInteger BigInteger::operator -(const BigInteger &x) const {
BigInteger ans;
ans.subtract(*this, x);
return ans;
}
inline BigInteger BigInteger::operator *(const BigInteger &x) const {
BigInteger ans;
ans.multiply(*this, x);
return ans;
}
inline BigInteger BigInteger::operator /(const BigInteger &x) const {
if (x.isZero()) throw "BigInteger::operator /: division by zero";
BigInteger q, r;
r = *this;
r.divideWithRemainder(x, q);
return q;
}
inline BigInteger BigInteger::operator %(const BigInteger &x) const {
if (x.isZero()) throw "BigInteger::operator %: division by zero";
BigInteger q, r;
r = *this;
r.divideWithRemainder(x, q);
return r;
}
inline BigInteger BigInteger::operator -() const {
BigInteger ans;
ans.negate(*this);
return ans;
}
/*
* ASSIGNMENT OPERATORS
*
* Now the responsibility for making a temporary copy if necessary
* belongs to the put-here operations. See Assignment Operators in
* BigUnsigned.hh.
*/
inline void BigInteger::operator +=(const BigInteger &x) {
add(*this, x);
}
inline void BigInteger::operator -=(const BigInteger &x) {
subtract(*this, x);
}
inline void BigInteger::operator *=(const BigInteger &x) {
multiply(*this, x);
}
inline void BigInteger::operator /=(const BigInteger &x) {
if (x.isZero()) throw "BigInteger::operator /=: division by zero";
/* The following technique is slightly faster than copying *this first
* when x is large. */
BigInteger q;
divideWithRemainder(x, q);
// *this contains the remainder, but we overwrite it with the quotient.
*this = q;
}
inline void BigInteger::operator %=(const BigInteger &x) {
if (x.isZero()) throw "BigInteger::operator %=: division by zero";
BigInteger q;
// Mods *this by x. Don't care about quotient left in q.
divideWithRemainder(x, q);
}
// This one is trivial
inline void BigInteger::flipSign() {
sign = Sign(-sign);
}
#endif

View File

@ -0,0 +1,25 @@
#ifndef BIGINTEGERALGORITHMS_H
#define BIGINTEGERALGORITHMS_H
#include "BigInteger.hh"
/* Some mathematical algorithms for big integers.
* This code is new and, as such, experimental. */
// Returns the greatest common divisor of a and b.
BigUnsigned gcd(BigUnsigned a, BigUnsigned b);
/* Extended Euclidean algorithm.
* Given m and n, finds gcd g and numbers r, s such that r*m + s*n == g. */
void extendedEuclidean(BigInteger m, BigInteger n,
BigInteger &g, BigInteger &r, BigInteger &s);
/* Returns the multiplicative inverse of x modulo n, or throws an exception if
* they have a common factor. */
BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n);
// Returns (base ^ exponent) % modulus.
BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
const BigUnsigned &modulus);
#endif

View File

@ -0,0 +1,8 @@
// This header file includes all of the library header files.
#include "NumberlikeArray.hh"
#include "BigUnsigned.hh"
#include "BigInteger.hh"
#include "BigIntegerAlgorithms.hh"
#include "BigUnsignedInABase.hh"
#include "BigIntegerUtils.hh"

View File

@ -0,0 +1,72 @@
#ifndef BIGINTEGERUTILS_H
#define BIGINTEGERUTILS_H
#include "BigInteger.hh"
#include <string>
#include <iostream>
/* This file provides:
* - Convenient std::string <-> BigUnsigned/BigInteger conversion routines
* - std::ostream << operators for BigUnsigned/BigInteger */
// std::string conversion routines. Base 10 only.
std::string bigUnsignedToString(const BigUnsigned &x);
std::string bigIntegerToString(const BigInteger &x);
BigUnsigned stringToBigUnsigned(const std::string &s);
BigInteger stringToBigInteger(const std::string &s);
// Creates a BigInteger from data such as `char's; read below for details.
template <class T>
BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign);
// Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'.
std::ostream &operator <<(std::ostream &os, const BigUnsigned &x);
// Outputs x to os, obeying the flags `dec', `hex', `bin', and `showbase'.
// My somewhat arbitrary policy: a negative sign comes before a base indicator (like -0xFF).
std::ostream &operator <<(std::ostream &os, const BigInteger &x);
// BEGIN TEMPLATE DEFINITIONS.
/*
* Converts binary data to a BigInteger.
* Pass an array `data', its length, and the desired sign.
*
* Elements of `data' may be of any type `T' that has the following
* two properties (this includes almost all integral types):
*
* (1) `sizeof(T)' correctly gives the amount of binary data in one
* value of `T' and is a factor of `sizeof(Blk)'.
*
* (2) When a value of `T' is casted to a `Blk', the low bytes of
* the result contain the desired binary data.
*/
template <class T>
BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign) {
// really ceiling(numBytes / sizeof(BigInteger::Blk))
unsigned int pieceSizeInBits = 8 * sizeof(T);
unsigned int piecesPerBlock = sizeof(BigInteger::Blk) / sizeof(T);
unsigned int numBlocks = (length + piecesPerBlock - 1) / piecesPerBlock;
// Allocate our block array
BigInteger::Blk *blocks = new BigInteger::Blk[numBlocks];
BigInteger::Index blockNum, pieceNum, pieceNumHere;
// Convert
for (blockNum = 0, pieceNum = 0; blockNum < numBlocks; blockNum++) {
BigInteger::Blk curBlock = 0;
for (pieceNumHere = 0; pieceNumHere < piecesPerBlock && pieceNum < length;
pieceNumHere++, pieceNum++)
curBlock |= (BigInteger::Blk(data[pieceNum]) << (pieceSizeInBits * pieceNumHere));
blocks[blockNum] = curBlock;
}
// Create the BigInteger.
BigInteger x(blocks, numBlocks, sign);
delete [] blocks;
return x;
}
#endif

View File

@ -0,0 +1,418 @@
#ifndef BIGUNSIGNED_H
#define BIGUNSIGNED_H
#include "NumberlikeArray.hh"
/* A BigUnsigned object represents a nonnegative integer of size limited only by
* available memory. BigUnsigneds support most mathematical operators and can
* be converted to and from most primitive integer types.
*
* The number is stored as a NumberlikeArray of unsigned longs as if it were
* written in base 256^sizeof(unsigned long). The least significant block is
* first, and the length is such that the most significant block is nonzero. */
class BigUnsigned : protected NumberlikeArray<unsigned long> {
public:
// Enumeration for the result of a comparison.
enum CmpRes { less = -1, equal = 0, greater = 1 };
// BigUnsigneds are built with a Blk type of unsigned long.
typedef unsigned long Blk;
typedef NumberlikeArray<Blk>::Index Index;
using NumberlikeArray<Blk>::N;
protected:
// Creates a BigUnsigned with a capacity; for internal use.
BigUnsigned(int, Index c) : NumberlikeArray<Blk>(0, c) {}
// Decreases len to eliminate any leading zero blocks.
void zapLeadingZeros() {
while (len > 0 && blk[len - 1] == 0)
len--;
}
public:
// Constructs zero.
BigUnsigned() : NumberlikeArray<Blk>() {}
// Copy constructor
BigUnsigned(const BigUnsigned &x) : NumberlikeArray<Blk>(x) {}
// Assignment operator
void operator=(const BigUnsigned &x) {
NumberlikeArray<Blk>::operator =(x);
}
// Constructor that copies from a given array of blocks.
BigUnsigned(const Blk *b, Index blen) : NumberlikeArray<Blk>(b, blen) {
// Eliminate any leading zeros we may have been passed.
zapLeadingZeros();
}
// Destructor. NumberlikeArray does the delete for us.
~BigUnsigned() {}
// Constructors from primitive integer types
BigUnsigned(unsigned long x);
BigUnsigned( long x);
BigUnsigned(unsigned int x);
BigUnsigned( int x);
BigUnsigned(unsigned short x);
BigUnsigned( short x);
protected:
// Helpers
template <class X> void initFromPrimitive (X x);
template <class X> void initFromSignedPrimitive(X x);
public:
/* Converters to primitive integer types
* The implicit conversion operators caused trouble, so these are now
* named. */
unsigned long toUnsignedLong () const;
long toLong () const;
unsigned int toUnsignedInt () const;
int toInt () const;
unsigned short toUnsignedShort() const;
short toShort () const;
protected:
// Helpers
template <class X> X convertToSignedPrimitive() const;
template <class X> X convertToPrimitive () const;
public:
// BIT/BLOCK ACCESSORS
// Expose these from NumberlikeArray directly.
using NumberlikeArray<Blk>::getCapacity;
using NumberlikeArray<Blk>::getLength;
/* Returns the requested block, or 0 if it is beyond the length (as if
* the number had 0s infinitely to the left). */
Blk getBlock(Index i) const { return i >= len ? 0 : blk[i]; }
/* Sets the requested block. The number grows or shrinks as necessary. */
void setBlock(Index i, Blk newBlock);
// The number is zero if and only if the canonical length is zero.
bool isZero() const { return NumberlikeArray<Blk>::isEmpty(); }
/* Returns the length of the number in bits, i.e., zero if the number
* is zero and otherwise one more than the largest value of bi for
* which getBit(bi) returns true. */
Index bitLength() const;
/* Get the state of bit bi, which has value 2^bi. Bits beyond the
* number's length are considered to be 0. */
bool getBit(Index bi) const {
return (getBlock(bi / N) & (Blk(1) << (bi % N))) != 0;
}
/* Sets the state of bit bi to newBit. The number grows or shrinks as
* necessary. */
void setBit(Index bi, bool newBit);
// COMPARISONS
// Compares this to x like Perl's <=>
CmpRes compareTo(const BigUnsigned &x) const;
// Ordinary comparison operators
bool operator ==(const BigUnsigned &x) const {
return NumberlikeArray<Blk>::operator ==(x);
}
bool operator !=(const BigUnsigned &x) const {
return NumberlikeArray<Blk>::operator !=(x);
}
bool operator < (const BigUnsigned &x) const { return compareTo(x) == less ; }
bool operator <=(const BigUnsigned &x) const { return compareTo(x) != greater; }
bool operator >=(const BigUnsigned &x) const { return compareTo(x) != less ; }
bool operator > (const BigUnsigned &x) const { return compareTo(x) == greater; }
/*
* BigUnsigned and BigInteger both provide three kinds of operators.
* Here ``big-integer'' refers to BigInteger or BigUnsigned.
*
* (1) Overloaded ``return-by-value'' operators:
* +, -, *, /, %, unary -, &, |, ^, <<, >>.
* Big-integer code using these operators looks identical to code using
* the primitive integer types. These operators take one or two
* big-integer inputs and return a big-integer result, which can then
* be assigned to a BigInteger variable or used in an expression.
* Example:
* BigInteger a(1), b = 1;
* BigInteger c = a + b;
*
* (2) Overloaded assignment operators:
* +=, -=, *=, /=, %=, flipSign, &=, |=, ^=, <<=, >>=, ++, --.
* Again, these are used on big integers just like on ints. They take
* one writable big integer that both provides an operand and receives a
* result. Most also take a second read-only operand.
* Example:
* BigInteger a(1), b(1);
* a += b;
*
* (3) Copy-less operations: `add', `subtract', etc.
* These named methods take operands as arguments and store the result
* in the receiver (*this), avoiding unnecessary copies and allocations.
* `divideWithRemainder' is special: it both takes the dividend from and
* stores the remainder into the receiver, and it takes a separate
* object in which to store the quotient. NOTE: If you are wondering
* why these don't return a value, you probably mean to use the
* overloaded return-by-value operators instead.
*
* Examples:
* BigInteger a(43), b(7), c, d;
*
* c = a + b; // Now c == 50.
* c.add(a, b); // Same effect but without the two copies.
*
* c.divideWithRemainder(b, d);
* // 50 / 7; now d == 7 (quotient) and c == 1 (remainder).
*
* // ``Aliased'' calls now do the right thing using a temporary
* // copy, but see note on `divideWithRemainder'.
* a.add(a, b);
*/
// COPY-LESS OPERATIONS
// These 8: Arguments are read-only operands, result is saved in *this.
void add(const BigUnsigned &a, const BigUnsigned &b);
void subtract(const BigUnsigned &a, const BigUnsigned &b);
void multiply(const BigUnsigned &a, const BigUnsigned &b);
void bitAnd(const BigUnsigned &a, const BigUnsigned &b);
void bitOr(const BigUnsigned &a, const BigUnsigned &b);
void bitXor(const BigUnsigned &a, const BigUnsigned &b);
/* Negative shift amounts translate to opposite-direction shifts,
* except for -2^(8*sizeof(int)-1) which is unimplemented. */
void bitShiftLeft(const BigUnsigned &a, int b);
void bitShiftRight(const BigUnsigned &a, int b);
/* `a.divideWithRemainder(b, q)' is like `q = a / b, a %= b'.
* / and % use semantics similar to Knuth's, which differ from the
* primitive integer semantics under division by zero. See the
* implementation in BigUnsigned.cc for details.
* `a.divideWithRemainder(b, a)' throws an exception: it doesn't make
* sense to write quotient and remainder into the same variable. */
void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q);
/* `divide' and `modulo' are no longer offered. Use
* `divideWithRemainder' instead. */
// OVERLOADED RETURN-BY-VALUE OPERATORS
BigUnsigned operator +(const BigUnsigned &x) const;
BigUnsigned operator -(const BigUnsigned &x) const;
BigUnsigned operator *(const BigUnsigned &x) const;
BigUnsigned operator /(const BigUnsigned &x) const;
BigUnsigned operator %(const BigUnsigned &x) const;
/* OK, maybe unary minus could succeed in one case, but it really
* shouldn't be used, so it isn't provided. */
BigUnsigned operator &(const BigUnsigned &x) const;
BigUnsigned operator |(const BigUnsigned &x) const;
BigUnsigned operator ^(const BigUnsigned &x) const;
BigUnsigned operator <<(int b) const;
BigUnsigned operator >>(int b) const;
// OVERLOADED ASSIGNMENT OPERATORS
void operator +=(const BigUnsigned &x);
void operator -=(const BigUnsigned &x);
void operator *=(const BigUnsigned &x);
void operator /=(const BigUnsigned &x);
void operator %=(const BigUnsigned &x);
void operator &=(const BigUnsigned &x);
void operator |=(const BigUnsigned &x);
void operator ^=(const BigUnsigned &x);
void operator <<=(int b);
void operator >>=(int b);
/* INCREMENT/DECREMENT OPERATORS
* To discourage messy coding, these do not return *this, so prefix
* and postfix behave the same. */
void operator ++( );
void operator ++(int);
void operator --( );
void operator --(int);
// Helper function that needs access to BigUnsigned internals
friend Blk getShiftedBlock(const BigUnsigned &num, Index x,
unsigned int y);
// See BigInteger.cc.
template <class X>
friend X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a);
};
/* Implementing the return-by-value and assignment operators in terms of the
* copy-less operations. The copy-less operations are responsible for making
* any necessary temporary copies to work around aliasing. */
inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const {
BigUnsigned ans;
ans.add(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const {
BigUnsigned ans;
ans.subtract(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const {
BigUnsigned ans;
ans.multiply(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const {
if (x.isZero()) throw "BigUnsigned::operator /: division by zero";
BigUnsigned q, r;
r = *this;
r.divideWithRemainder(x, q);
return q;
}
inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const {
if (x.isZero()) throw "BigUnsigned::operator %: division by zero";
BigUnsigned q, r;
r = *this;
r.divideWithRemainder(x, q);
return r;
}
inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const {
BigUnsigned ans;
ans.bitAnd(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const {
BigUnsigned ans;
ans.bitOr(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const {
BigUnsigned ans;
ans.bitXor(*this, x);
return ans;
}
inline BigUnsigned BigUnsigned::operator <<(int b) const {
BigUnsigned ans;
ans.bitShiftLeft(*this, b);
return ans;
}
inline BigUnsigned BigUnsigned::operator >>(int b) const {
BigUnsigned ans;
ans.bitShiftRight(*this, b);
return ans;
}
inline void BigUnsigned::operator +=(const BigUnsigned &x) {
add(*this, x);
}
inline void BigUnsigned::operator -=(const BigUnsigned &x) {
subtract(*this, x);
}
inline void BigUnsigned::operator *=(const BigUnsigned &x) {
multiply(*this, x);
}
inline void BigUnsigned::operator /=(const BigUnsigned &x) {
if (x.isZero()) throw "BigUnsigned::operator /=: division by zero";
/* The following technique is slightly faster than copying *this first
* when x is large. */
BigUnsigned q;
divideWithRemainder(x, q);
// *this contains the remainder, but we overwrite it with the quotient.
*this = q;
}
inline void BigUnsigned::operator %=(const BigUnsigned &x) {
if (x.isZero()) throw "BigUnsigned::operator %=: division by zero";
BigUnsigned q;
// Mods *this by x. Don't care about quotient left in q.
divideWithRemainder(x, q);
}
inline void BigUnsigned::operator &=(const BigUnsigned &x) {
bitAnd(*this, x);
}
inline void BigUnsigned::operator |=(const BigUnsigned &x) {
bitOr(*this, x);
}
inline void BigUnsigned::operator ^=(const BigUnsigned &x) {
bitXor(*this, x);
}
inline void BigUnsigned::operator <<=(int b) {
bitShiftLeft(*this, b);
}
inline void BigUnsigned::operator >>=(int b) {
bitShiftRight(*this, b);
}
/* Templates for conversions of BigUnsigned to and from primitive integers.
* BigInteger.cc needs to instantiate convertToPrimitive, and the uses in
* BigUnsigned.cc didn't do the trick; I think g++ inlined convertToPrimitive
* instead of generating linkable instantiations. So for consistency, I put
* all the templates here. */
// CONSTRUCTION FROM PRIMITIVE INTEGERS
/* Initialize this BigUnsigned from the given primitive integer. The same
* pattern works for all primitive integer types, so I put it into a template to
* reduce code duplication. (Don't worry: this is protected and we instantiate
* it only with primitive integer types.) Type X could be signed, but x is
* known to be nonnegative. */
template <class X>
void BigUnsigned::initFromPrimitive(X x) {
if (x == 0)
; // NumberlikeArray already initialized us to zero.
else {
// Create a single block. blk is NULL; no need to delete it.
cap = 1;
blk = new Blk[1];
len = 1;
blk[0] = Blk(x);
}
}
/* Ditto, but first check that x is nonnegative. I could have put the check in
* initFromPrimitive and let the compiler optimize it out for unsigned-type
* instantiations, but I wanted to avoid the warning stupidly issued by g++ for
* a condition that is constant in *any* instantiation, even if not in all. */
template <class X>
void BigUnsigned::initFromSignedPrimitive(X x) {
if (x < 0)
throw "BigUnsigned constructor: "
"Cannot construct a BigUnsigned from a negative number";
else
initFromPrimitive(x);
}
// CONVERSION TO PRIMITIVE INTEGERS
/* Template with the same idea as initFromPrimitive. This might be slightly
* slower than the previous version with the masks, but it's much shorter and
* clearer, which is the library's stated goal. */
template <class X>
X BigUnsigned::convertToPrimitive() const {
if (len == 0)
// The number is zero; return zero.
return 0;
else if (len == 1) {
// The single block might fit in an X. Try the conversion.
X x = X(blk[0]);
// Make sure the result accurately represents the block.
if (Blk(x) == blk[0])
// Successful conversion.
return x;
// Otherwise fall through.
}
throw "BigUnsigned::to<Primitive>: "
"Value is too big to fit in the requested type";
}
/* Wrap the above in an x >= 0 test to make sure we got a nonnegative result,
* not a negative one that happened to convert back into the correct nonnegative
* one. (E.g., catch incorrect conversion of 2^31 to the long -2^31.) Again,
* separated to avoid a g++ warning. */
template <class X>
X BigUnsigned::convertToSignedPrimitive() const {
X x = convertToPrimitive<X>();
if (x >= 0)
return x;
else
throw "BigUnsigned::to(Primitive): "
"Value is too big to fit in the requested type";
}
#endif

View File

@ -0,0 +1,122 @@
#ifndef BIGUNSIGNEDINABASE_H
#define BIGUNSIGNEDINABASE_H
#include "NumberlikeArray.hh"
#include "BigUnsigned.hh"
#include <string>
/*
* A BigUnsignedInABase object represents a nonnegative integer of size limited
* only by available memory, represented in a user-specified base that can fit
* in an `unsigned short' (most can, and this saves memory).
*
* BigUnsignedInABase is intended as an intermediary class with little
* functionality of its own. BigUnsignedInABase objects can be constructed
* from, and converted to, BigUnsigneds (requiring multiplication, mods, etc.)
* and `std::string's (by switching digit values for appropriate characters).
*
* BigUnsignedInABase is similar to BigUnsigned. Note the following:
*
* (1) They represent the number in exactly the same way, except that
* BigUnsignedInABase uses ``digits'' (or Digit) where BigUnsigned uses
* ``blocks'' (or Blk).
*
* (2) Both use the management features of NumberlikeArray. (In fact, my desire
* to add a BigUnsignedInABase class without duplicating a lot of code led me to
* introduce NumberlikeArray.)
*
* (3) The only arithmetic operation supported by BigUnsignedInABase is an
* equality test. Use BigUnsigned for arithmetic.
*/
class BigUnsignedInABase : protected NumberlikeArray<unsigned short> {
public:
// The digits of a BigUnsignedInABase are unsigned shorts.
typedef unsigned short Digit;
// That's also the type of a base.
typedef Digit Base;
protected:
// The base in which this BigUnsignedInABase is expressed
Base base;
// Creates a BigUnsignedInABase with a capacity; for internal use.
BigUnsignedInABase(int, Index c) : NumberlikeArray<Digit>(0, c) {}
// Decreases len to eliminate any leading zero digits.
void zapLeadingZeros() {
while (len > 0 && blk[len - 1] == 0)
len--;
}
public:
// Constructs zero in base 2.
BigUnsignedInABase() : NumberlikeArray<Digit>(), base(2) {}
// Copy constructor
BigUnsignedInABase(const BigUnsignedInABase &x) : NumberlikeArray<Digit>(x), base(x.base) {}
// Assignment operator
void operator =(const BigUnsignedInABase &x) {
NumberlikeArray<Digit>::operator =(x);
base = x.base;
}
// Constructor that copies from a given array of digits.
BigUnsignedInABase(const Digit *d, Index l, Base base);
// Destructor. NumberlikeArray does the delete for us.
~BigUnsignedInABase() {}
// LINKS TO BIGUNSIGNED
BigUnsignedInABase(const BigUnsigned &x, Base base);
operator BigUnsigned() const;
/* LINKS TO STRINGS
*
* These use the symbols ``0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'' to
* represent digits of 0 through 35. When parsing strings, lowercase is
* also accepted.
*
* All string representations are big-endian (big-place-value digits
* first). (Computer scientists have adopted zero-based counting; why
* can't they tolerate little-endian numbers?)
*
* No string representation has a ``base indicator'' like ``0x''.
*
* An exception is made for zero: it is converted to ``0'' and not the
* empty string.
*
* If you want different conventions, write your own routines to go
* between BigUnsignedInABase and strings. It's not hard.
*/
operator std::string() const;
BigUnsignedInABase(const std::string &s, Base base);
public:
// ACCESSORS
Base getBase() const { return base; }
// Expose these from NumberlikeArray directly.
using NumberlikeArray<Digit>::getCapacity;
using NumberlikeArray<Digit>::getLength;
/* Returns the requested digit, or 0 if it is beyond the length (as if
* the number had 0s infinitely to the left). */
Digit getDigit(Index i) const { return i >= len ? 0 : blk[i]; }
// The number is zero if and only if the canonical length is zero.
bool isZero() const { return NumberlikeArray<Digit>::isEmpty(); }
/* Equality test. For the purposes of this test, two BigUnsignedInABase
* values must have the same base to be equal. */
bool operator ==(const BigUnsignedInABase &x) const {
return base == x.base && NumberlikeArray<Digit>::operator ==(x);
}
bool operator !=(const BigUnsignedInABase &x) const { return !operator ==(x); }
};
#endif

View File

@ -0,0 +1,177 @@
#ifndef NUMBERLIKEARRAY_H
#define NUMBERLIKEARRAY_H
// Make sure we have NULL.
#ifndef NULL
#define NULL 0
#endif
/* A NumberlikeArray<Blk> object holds a heap-allocated array of Blk with a
* length and a capacity and provides basic memory management features.
* BigUnsigned and BigUnsignedInABase both subclass it.
*
* NumberlikeArray provides no information hiding. Subclasses should use
* nonpublic inheritance and manually expose members as desired using
* declarations like this:
*
* public:
* NumberlikeArray< the-type-argument >::getLength;
*/
template <class Blk>
class NumberlikeArray {
public:
// Type for the index of a block in the array
typedef unsigned int Index;
// The number of bits in a block, defined below.
static const unsigned int N;
// The current allocated capacity of this NumberlikeArray (in blocks)
Index cap;
// The actual length of the value stored in this NumberlikeArray (in blocks)
Index len;
// Heap-allocated array of the blocks (can be NULL if len == 0)
Blk *blk;
// Constructs a ``zero'' NumberlikeArray with the given capacity.
NumberlikeArray(Index c) : cap(c), len(0) {
blk = (cap > 0) ? (new Blk[cap]) : NULL;
}
/* Constructs a zero NumberlikeArray without allocating a backing array.
* A subclass that doesn't know the needed capacity at initialization
* time can use this constructor and then overwrite blk without first
* deleting it. */
NumberlikeArray() : cap(0), len(0) {
blk = NULL;
}
// Destructor. Note that `delete NULL' is a no-op.
~NumberlikeArray() {
delete [] blk;
}
/* Ensures that the array has at least the requested capacity; may
* destroy the contents. */
void allocate(Index c);
/* Ensures that the array has at least the requested capacity; does not
* destroy the contents. */
void allocateAndCopy(Index c);
// Copy constructor
NumberlikeArray(const NumberlikeArray<Blk> &x);
// Assignment operator
void operator=(const NumberlikeArray<Blk> &x);
// Constructor that copies from a given array of blocks
NumberlikeArray(const Blk *b, Index blen);
// ACCESSORS
Index getCapacity() const { return cap; }
Index getLength() const { return len; }
Blk getBlock(Index i) const { return blk[i]; }
bool isEmpty() const { return len == 0; }
/* Equality comparison: checks if both objects have the same length and
* equal (==) array elements to that length. Subclasses may wish to
* override. */
bool operator ==(const NumberlikeArray<Blk> &x) const;
bool operator !=(const NumberlikeArray<Blk> &x) const {
return !operator ==(x);
}
};
/* BEGIN TEMPLATE DEFINITIONS. They are present here so that source files that
* include this header file can generate the necessary real definitions. */
template <class Blk>
const unsigned int NumberlikeArray<Blk>::N = 8 * sizeof(Blk);
template <class Blk>
void NumberlikeArray<Blk>::allocate(Index c) {
// If the requested capacity is more than the current capacity...
if (c > cap) {
// Delete the old number array
delete [] blk;
// Allocate the new array
cap = c;
blk = new Blk[cap];
}
}
template <class Blk>
void NumberlikeArray<Blk>::allocateAndCopy(Index c) {
// If the requested capacity is more than the current capacity...
if (c > cap) {
Blk *oldBlk = blk;
// Allocate the new number array
cap = c;
blk = new Blk[cap];
// Copy number blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = oldBlk[i];
// Delete the old array
delete [] oldBlk;
}
}
template <class Blk>
NumberlikeArray<Blk>::NumberlikeArray(const NumberlikeArray<Blk> &x)
: len(x.len) {
// Create array
cap = len;
blk = new Blk[cap];
// Copy blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = x.blk[i];
}
template <class Blk>
void NumberlikeArray<Blk>::operator=(const NumberlikeArray<Blk> &x) {
/* Calls like a = a have no effect; catch them before the aliasing
* causes a problem */
if (this == &x)
return;
// Copy length
len = x.len;
// Expand array if necessary
allocate(len);
// Copy number blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = x.blk[i];
}
template <class Blk>
NumberlikeArray<Blk>::NumberlikeArray(const Blk *b, Index blen)
: cap(blen), len(blen) {
// Create array
blk = new Blk[cap];
// Copy blocks
Index i;
for (i = 0; i < len; i++)
blk[i] = b[i];
}
template <class Blk>
bool NumberlikeArray<Blk>::operator ==(const NumberlikeArray<Blk> &x) const {
if (len != x.len)
// Definitely unequal.
return false;
else {
// Compare corresponding blocks one by one.
Index i;
for (i = 0; i < len; i++)
if (blk[i] != x.blk[i])
return false;
// No blocks differed, so the objects are equal.
return true;
}
}
#endif

View File

@ -0,0 +1,14 @@
#ifndef _LIBICONV_H
#define _LIBICONV_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void* iconv_t;
iconv_t iconv_open(const char *tocode, const char *fromcode);
int iconv_close(iconv_t cd);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
#ifdef __cplusplus
}
#endif
#endif//_LIBICONV_H

View File

@ -0,0 +1,247 @@
// ISO C9x compliant stdint.h for Microsoft Visual Studio
// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
//
// Copyright (c) 2006-2008 Alexander Chemeris
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// 3. The name of the author may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////////
#ifndef _MSC_VER // [
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_
#if _MSC_VER > 1000
#pragma once
#endif
#include <limits.h>
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
// compiling for ARM we should wrap <wchar.h> include with 'extern "C++" {}'
// or compiler give many errors like this:
// error C2733: second C linkage of overloaded function 'wmemchr' not allowed
#ifdef __cplusplus
extern "C" {
#endif
# include <wchar.h>
#ifdef __cplusplus
}
#endif
// Define _W64 macros to mark types changing their size, like intptr_t.
#ifndef _W64
# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
# define _W64 __w64
# else
# define _W64
# endif
#endif
// 7.18.1 Integer types
// 7.18.1.1 Exact-width integer types
// Visual Studio 6 and Embedded Visual C++ 4 doesn't
// realize that, e.g. char has the same size as __int8
// so we give up on __intX for them.
#if (_MSC_VER < 1300)
typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
#else
typedef signed __int8 int8_t;
typedef signed __int16 int16_t;
typedef signed __int32 int32_t;
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
#endif
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
// 7.18.1.2 Minimum-width integer types
typedef int8_t int_least8_t;
typedef int16_t int_least16_t;
typedef int32_t int_least32_t;
typedef int64_t int_least64_t;
typedef uint8_t uint_least8_t;
typedef uint16_t uint_least16_t;
typedef uint32_t uint_least32_t;
typedef uint64_t uint_least64_t;
// 7.18.1.3 Fastest minimum-width integer types
typedef int8_t int_fast8_t;
typedef int16_t int_fast16_t;
typedef int32_t int_fast32_t;
typedef int64_t int_fast64_t;
typedef uint8_t uint_fast8_t;
typedef uint16_t uint_fast16_t;
typedef uint32_t uint_fast32_t;
typedef uint64_t uint_fast64_t;
// 7.18.1.4 Integer types capable of holding object pointers
#ifdef _WIN64 // [
typedef signed __int64 intptr_t;
typedef unsigned __int64 uintptr_t;
#else // _WIN64 ][
typedef _W64 signed int intptr_t;
typedef _W64 unsigned int uintptr_t;
#endif // _WIN64 ]
// 7.18.1.5 Greatest-width integer types
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
// 7.18.2 Limits of specified-width integer types
#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259
// 7.18.2.1 Limits of exact-width integer types
#define INT8_MIN ((int8_t)_I8_MIN)
#define INT8_MAX _I8_MAX
#define INT16_MIN ((int16_t)_I16_MIN)
#define INT16_MAX _I16_MAX
#define INT32_MIN ((int32_t)_I32_MIN)
#define INT32_MAX _I32_MAX
#define INT64_MIN ((int64_t)_I64_MIN)
#define INT64_MAX _I64_MAX
#define UINT8_MAX _UI8_MAX
#define UINT16_MAX _UI16_MAX
#define UINT32_MAX _UI32_MAX
#define UINT64_MAX _UI64_MAX
// 7.18.2.2 Limits of minimum-width integer types
#define INT_LEAST8_MIN INT8_MIN
#define INT_LEAST8_MAX INT8_MAX
#define INT_LEAST16_MIN INT16_MIN
#define INT_LEAST16_MAX INT16_MAX
#define INT_LEAST32_MIN INT32_MIN
#define INT_LEAST32_MAX INT32_MAX
#define INT_LEAST64_MIN INT64_MIN
#define INT_LEAST64_MAX INT64_MAX
#define UINT_LEAST8_MAX UINT8_MAX
#define UINT_LEAST16_MAX UINT16_MAX
#define UINT_LEAST32_MAX UINT32_MAX
#define UINT_LEAST64_MAX UINT64_MAX
// 7.18.2.3 Limits of fastest minimum-width integer types
#define INT_FAST8_MIN INT8_MIN
#define INT_FAST8_MAX INT8_MAX
#define INT_FAST16_MIN INT16_MIN
#define INT_FAST16_MAX INT16_MAX
#define INT_FAST32_MIN INT32_MIN
#define INT_FAST32_MAX INT32_MAX
#define INT_FAST64_MIN INT64_MIN
#define INT_FAST64_MAX INT64_MAX
#define UINT_FAST8_MAX UINT8_MAX
#define UINT_FAST16_MAX UINT16_MAX
#define UINT_FAST32_MAX UINT32_MAX
#define UINT_FAST64_MAX UINT64_MAX
// 7.18.2.4 Limits of integer types capable of holding object pointers
#ifdef _WIN64 // [
# define INTPTR_MIN INT64_MIN
# define INTPTR_MAX INT64_MAX
# define UINTPTR_MAX UINT64_MAX
#else // _WIN64 ][
# define INTPTR_MIN INT32_MIN
# define INTPTR_MAX INT32_MAX
# define UINTPTR_MAX UINT32_MAX
#endif // _WIN64 ]
// 7.18.2.5 Limits of greatest-width integer types
#define INTMAX_MIN INT64_MIN
#define INTMAX_MAX INT64_MAX
#define UINTMAX_MAX UINT64_MAX
// 7.18.3 Limits of other integer types
#ifdef _WIN64 // [
# define PTRDIFF_MIN _I64_MIN
# define PTRDIFF_MAX _I64_MAX
#else // _WIN64 ][
# define PTRDIFF_MIN _I32_MIN
# define PTRDIFF_MAX _I32_MAX
#endif // _WIN64 ]
#define SIG_ATOMIC_MIN INT_MIN
#define SIG_ATOMIC_MAX INT_MAX
#ifndef SIZE_MAX // [
# ifdef _WIN64 // [
# define SIZE_MAX _UI64_MAX
# else // _WIN64 ][
# define SIZE_MAX _UI32_MAX
# endif // _WIN64 ]
#endif // SIZE_MAX ]
// WCHAR_MIN and WCHAR_MAX are also defined in <wchar.h>
#ifndef WCHAR_MIN // [
# define WCHAR_MIN 0
#endif // WCHAR_MIN ]
#ifndef WCHAR_MAX // [
# define WCHAR_MAX _UI16_MAX
#endif // WCHAR_MAX ]
#define WINT_MIN 0
#define WINT_MAX _UI16_MAX
#endif // __STDC_LIMIT_MACROS ]
// 7.18.4 Limits of other integer types
#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260
// 7.18.4.1 Macros for minimum-width integer constants
#define INT8_C(val) val##i8
#define INT16_C(val) val##i16
#define INT32_C(val) val##i32
#define INT64_C(val) val##i64
#define UINT8_C(val) val##ui8
#define UINT16_C(val) val##ui16
#define UINT32_C(val) val##ui32
#define UINT64_C(val) val##ui64
// 7.18.4.2 Macros for greatest-width integer constants
#define INTMAX_C INT64_C
#define UINTMAX_C UINT64_C
#endif // __STDC_CONSTANT_MACROS ]
#endif // _MSC_STDINT_H_ ]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,202 @@
//------------------------------------------------------------------------
// Copyright 2007-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_DECODER_H_
#define _ZBAR_DECODER_H_
/// @file
/// Decoder C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Decoder.h"
#endif
#include <string>
namespace zbar {
/// low-level bar width stream decoder interface.
/// identifies symbols and extracts encoded data
class Decoder {
public:
/// Decoder result handler.
/// applications should subtype this and pass an instance to
/// set_handler() to implement result processing
class Handler {
public:
virtual ~Handler() { }
/// invoked by the Decoder as decode results become available.
virtual void decode_callback(Decoder &decoder) = 0;
};
/// constructor.
Decoder ()
: _handler(NULL)
{
_decoder = zbar_decoder_create();
}
~Decoder ()
{
zbar_decoder_destroy(_decoder);
}
/// clear all decoder state.
/// see zbar_decoder_reset()
void reset ()
{
zbar_decoder_reset(_decoder);
}
/// mark start of a new scan pass.
/// see zbar_decoder_new_scan()
void new_scan ()
{
zbar_decoder_new_scan(_decoder);
}
/// process next bar/space width from input stream.
/// see zbar_decode_width()
zbar_symbol_type_t decode_width (unsigned width)
{
return(zbar_decode_width(_decoder, width));
}
/// process next bar/space width from input stream.
/// see zbar_decode_width()
Decoder& operator<< (unsigned width)
{
zbar_decode_width(_decoder, width);
return(*this);
}
/// retrieve color of @em next element passed to Decoder.
/// see zbar_decoder_get_color()
zbar_color_t get_color () const
{
return(zbar_decoder_get_color(_decoder));
}
/// retrieve last decoded symbol type.
/// see zbar_decoder_get_type()
zbar_symbol_type_t get_type () const
{
return(zbar_decoder_get_type(_decoder));
}
/// retrieve string name of last decoded symbol type.
/// see zbar_get_symbol_name()
const char *get_symbol_name () const
{
return(zbar_get_symbol_name(zbar_decoder_get_type(_decoder)));
}
/// retrieve string name for last decode addon.
/// see zbar_get_addon_name()
/// @deprecated in 0.11
const char *get_addon_name () const
{
return(zbar_get_addon_name(zbar_decoder_get_type(_decoder)));
}
/// retrieve last decoded data in ASCII format as a char array.
/// see zbar_decoder_get_data()
const char *get_data_chars() const
{
return(zbar_decoder_get_data(_decoder));
}
/// retrieve last decoded data as a std::string.
/// see zbar_decoder_get_data()
const std::string get_data_string() const
{
return(std::string(zbar_decoder_get_data(_decoder),
zbar_decoder_get_data_length(_decoder)));
}
/// retrieve last decoded data as a std::string.
/// see zbar_decoder_get_data()
const std::string get_data() const
{
return(get_data_string());
}
/// retrieve length of decoded binary data.
/// see zbar_decoder_get_data_length()
int get_data_length() const
{
return(zbar_decoder_get_data_length(_decoder));
}
/// retrieve last decode direction.
/// see zbar_decoder_get_direction()
/// @since 0.11
int get_direction() const
{
return(zbar_decoder_get_direction(_decoder));
}
/// setup callback to handle result data.
void set_handler (Handler &handler)
{
_handler = &handler;
zbar_decoder_set_handler(_decoder, _cb);
zbar_decoder_set_userdata(_decoder, this);
}
/// set config for indicated symbology (0 for all) to specified value.
/// @see zbar_decoder_set_config()
/// @since 0.4
int set_config (zbar_symbol_type_t symbology,
zbar_config_t config,
int value)
{
return(zbar_decoder_set_config(_decoder, symbology, config, value));
}
/// set config parsed from configuration string.
/// @see zbar_decoder_parse_config()
/// @since 0.4
int set_config (std::string cfgstr)
{
return(zbar_decoder_parse_config(_decoder, cfgstr.c_str()));
}
private:
friend class Scanner;
zbar_decoder_t *_decoder;
Handler *_handler;
static void _cb (zbar_decoder_t *cdcode)
{
Decoder *dcode = (Decoder*)zbar_decoder_get_userdata(cdcode);
if(dcode && dcode->_handler)
dcode->_handler->decode_callback(*dcode);
}
};
}
#endif

View File

@ -0,0 +1,187 @@
//------------------------------------------------------------------------
// Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_EXCEPTION_H_
#define _ZBAR_EXCEPTION_H_
/// @file
/// C++ Exception definitions
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Exception.h"
#endif
#include <exception>
#include <new>
namespace zbar {
/// base class for exceptions defined by this API.
class Exception : public std::exception {
public:
/// create exception from C library error
Exception (const void *obj = NULL)
: std::exception(),
_obj(obj)
{ }
~Exception () throw() { }
/// retrieve error message
virtual const char* what () const throw()
{
if(!_obj)
return("zbar library unspecified generic error");
return(_zbar_error_string(_obj, 0));
}
private:
const void *_obj;
};
/// internal library error.
class InternalError : public Exception {
public:
/// create exception from C library error
InternalError (const void *obj)
: Exception(obj)
{ }
};
/// unsupported request.
class UnsupportedError : public Exception {
public:
/// create exception from C library error
UnsupportedError (const void *obj)
: Exception(obj)
{ }
};
/// invalid request.
class InvalidError : public Exception {
public:
/// create exception from C library error
InvalidError (const void *obj)
: Exception(obj)
{ }
};
/// failed system call.
class SystemError : public Exception {
public:
/// create exception from C library error
SystemError (const void *obj)
: Exception(obj)
{ }
};
/// locking error.
class LockingError : public Exception {
public:
/// create exception from C library error
LockingError (const void *obj)
: Exception(obj)
{ }
};
/// all resources busy.
class BusyError : public Exception {
public:
/// create exception from C library error
BusyError (const void *obj)
: Exception(obj)
{ }
};
/// X11 display error.
class XDisplayError : public Exception {
public:
/// create exception from C library error
XDisplayError (const void *obj)
: Exception(obj)
{ }
};
/// X11 protocol error.
class XProtoError : public Exception {
public:
/// create exception from C library error
XProtoError (const void *obj)
: Exception(obj)
{ }
};
/// output window is closed.
class ClosedError : public Exception {
public:
/// create exception from C library error
ClosedError (const void *obj)
: Exception(obj)
{ }
};
/// image format error
class FormatError : public Exception {
// FIXME needs c equivalent
virtual const char* what () const throw()
{
// FIXME what format?
return("unsupported format");
}
};
/// @internal
/// extract error information and create exception.
static __inline std::exception throw_exception (const void *obj)
{
switch(_zbar_get_error_code(obj)) {
case ZBAR_ERR_NOMEM:
throw std::bad_alloc();
case ZBAR_ERR_INTERNAL:
throw InternalError(obj);
case ZBAR_ERR_UNSUPPORTED:
throw UnsupportedError(obj);
case ZBAR_ERR_INVALID:
throw InvalidError(obj);
case ZBAR_ERR_SYSTEM:
throw SystemError(obj);
case ZBAR_ERR_LOCKING:
throw LockingError(obj);
case ZBAR_ERR_BUSY:
throw BusyError(obj);
case ZBAR_ERR_XDISPLAY:
throw XDisplayError(obj);
case ZBAR_ERR_XPROTO:
throw XProtoError(obj);
case ZBAR_ERR_CLOSED:
throw ClosedError(obj);
default:
throw Exception(obj);
}
}
}
#endif

View File

@ -0,0 +1,329 @@
//------------------------------------------------------------------------
// Copyright 2007-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_IMAGE_H_
#define _ZBAR_IMAGE_H_
/// @file
/// Image C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Image.h"
#endif
#include <assert.h>
#include <iterator>
#include "Symbol.h"
#include "Exception.h"
namespace zbar {
class Video;
/// stores image data samples along with associated format and size
/// metadata
class Image {
public:
/// general Image result handler.
/// applications should subtype this and pass an instance to
/// eg. ImageScanner::set_handler() to implement result processing
class Handler {
public:
virtual ~Handler() { }
/// invoked by library when Image should be processed
virtual void image_callback(Image &image) = 0;
/// cast this handler to the C handler
operator zbar_image_data_handler_t* () const
{
return(_cb);
}
private:
static void _cb (zbar_image_t *zimg,
const void *userdata)
{
if(userdata) {
Image *image = (Image*)zbar_image_get_userdata(zimg);
if(image)
((Handler*)userdata)->image_callback(*image);
else {
Image tmp(zimg, 1);
((Handler*)userdata)->image_callback(tmp);
}
}
}
};
class SymbolIterator : public zbar::SymbolIterator {
public:
/// default constructor.
SymbolIterator ()
: zbar::SymbolIterator()
{ }
/// constructor.
SymbolIterator (const SymbolSet &syms)
: zbar::SymbolIterator(syms)
{ }
/// copy constructor.
SymbolIterator (const SymbolIterator& iter)
: zbar::SymbolIterator(iter)
{ }
};
/// constructor.
/// create a new Image with the specified parameters
Image (unsigned width = 0,
unsigned height = 0,
const std::string& format = "",
const void *data = NULL,
unsigned long length = 0)
: _img(zbar_image_create())
{
zbar_image_set_userdata(_img, this);
if(width && height)
set_size(width, height);
if(format.length())
set_format(format);
if(data && length)
set_data(data, length);
}
~Image ()
{
if(zbar_image_get_userdata(_img) == this)
zbar_image_set_userdata(_img, NULL);
zbar_image_ref(_img, -1);
}
/// cast to C image object
operator const zbar_image_t* () const
{
return(_img);
}
/// cast to C image object
operator zbar_image_t* ()
{
return(_img);
}
/// retrieve the image format.
/// see zbar_image_get_format()
unsigned long get_format () const
{
return(zbar_image_get_format(_img));
}
/// specify the fourcc image format code for image sample data.
/// see zbar_image_set_format()
void set_format (unsigned long format)
{
zbar_image_set_format(_img, format);
}
/// specify the fourcc image format code for image sample data.
/// see zbar_image_set_format()
void set_format (const std::string& format)
{
unsigned long fourcc = zbar_fourcc_parse(format.c_str());
zbar_image_set_format(_img, fourcc);
}
/// retrieve a "sequence" (page/frame) number associated with this
/// image.
/// see zbar_image_get_sequence()
/// @since 0.6
unsigned get_sequence () const
{
return(zbar_image_get_sequence(_img));
}
/// associate a "sequence" (page/frame) number with this image.
/// see zbar_image_set_sequence()
/// @since 0.6
void set_sequence (unsigned sequence_num)
{
zbar_image_set_sequence(_img, sequence_num);
}
/// retrieve the width of the image.
/// see zbar_image_get_width()
unsigned get_width () const
{
return(zbar_image_get_width(_img));
}
/// retrieve the height of the image.
/// see zbar_image_get_height()
unsigned get_height () const
{
return(zbar_image_get_height(_img));
}
/// retrieve both dimensions of the image.
/// see zbar_image_get_size()
/// @since 0.11
void get_size (unsigned &width,
unsigned &height) const
{
zbar_image_get_size(_img, &width, &height);
}
/// specify the pixel size of the image.
/// see zbar_image_set_size()
void set_size (unsigned width,
unsigned height)
{
zbar_image_set_size(_img, width, height);
}
/// retrieve the scan crop rectangle.
/// see zbar_image_get_crop()
void get_crop (unsigned &x,
unsigned &y,
unsigned &width,
unsigned &height) const
{
zbar_image_get_crop(_img, &x, &y, &width, &height);
}
/// set the scan crop rectangle.
/// see zbar_image_set_crop()
void set_crop (unsigned x,
unsigned y,
unsigned width,
unsigned height)
{
zbar_image_set_crop(_img, x, y, width, height);
}
/// return the image sample data.
/// see zbar_image_get_data()
const void *get_data () const
{
return(zbar_image_get_data(_img));
}
/// return the size of the image sample data.
/// see zbar_image_get_data_length()
/// @since 0.6
unsigned long get_data_length () const
{
return(zbar_image_get_data_length(_img));
}
/// specify image sample data.
/// see zbar_image_set_data()
void set_data (const void *data,
unsigned long length)
{
zbar_image_set_data(_img, data, length, _cleanup);
}
/// image format conversion.
/// see zbar_image_convert()
Image convert (unsigned long format) const
{
zbar_image_t *img = zbar_image_convert(_img, format);
if(img)
return(Image(img));
throw FormatError();
}
/// image format conversion.
/// see zbar_image_convert()
/// @since 0.11
Image convert (std::string format) const
{
unsigned long fourcc = zbar_fourcc_parse(format.c_str());
return(convert(fourcc));
}
/// image format conversion with crop/pad.
/// see zbar_image_convert_resize()
/// @since 0.4
Image convert (unsigned long format,
unsigned width,
unsigned height) const
{
zbar_image_t *img =
zbar_image_convert_resize(_img, format, width, height);
if(img)
return(Image(img));
throw FormatError();
}
const SymbolSet get_symbols () const {
return(SymbolSet(zbar_image_get_symbols(_img)));
}
void set_symbols (const SymbolSet &syms) {
zbar_image_set_symbols(_img, syms);
}
/// create a new SymbolIterator over decoded results.
SymbolIterator symbol_begin () const {
return(SymbolIterator(get_symbols()));
}
/// return a SymbolIterator suitable for ending iteration.
SymbolIterator symbol_end () const {
return(SymbolIterator());
}
protected:
friend class Video;
/// constructor.
/// @internal
/// create a new Image from a zbar_image_t C object
Image (zbar_image_t *src,
int refs = 0)
: _img(src)
{
if(refs)
zbar_image_ref(_img, refs);
zbar_image_set_userdata(_img, this);
}
/// default data cleanup (noop)
/// @internal
static void _cleanup (zbar_image_t *img)
{
// by default nothing is cleaned
assert(img);
}
private:
zbar_image_t *_img;
};
}
#endif

View File

@ -0,0 +1,130 @@
//------------------------------------------------------------------------
// Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_IMAGE_SCANNER_H_
#define _ZBAR_IMAGE_SCANNER_H_
/// @file
/// Image Scanner C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/ImageScanner.h"
#endif
#include "Image.h"
namespace zbar {
/// mid-level image scanner interface.
/// reads barcodes from a 2-D Image
class ImageScanner {
public:
/// constructor.
ImageScanner (zbar_image_scanner_t *scanner = NULL)
{
if(scanner)
_scanner = scanner;
else
_scanner = zbar_image_scanner_create();
}
~ImageScanner ()
{
zbar_image_scanner_destroy(_scanner);
}
/// cast to C image_scanner object
operator zbar_image_scanner_t* () const
{
return(_scanner);
}
/// setup result handler callback.
void set_handler (Image::Handler &handler)
{
zbar_image_scanner_set_data_handler(_scanner, handler, &handler);
}
/// set config for indicated symbology (0 for all) to specified value.
/// @see zbar_image_scanner_set_config()
/// @since 0.4
int set_config (zbar_symbol_type_t symbology,
zbar_config_t config,
int value)
{
return(zbar_image_scanner_set_config(_scanner, symbology,
config, value));
}
/// set config parsed from configuration string.
/// @see zbar_image_scanner_parse_config()
/// @since 0.4
int set_config (std::string cfgstr)
{
return(zbar_image_scanner_parse_config(_scanner, cfgstr.c_str()));
}
/// enable or disable the inter-image result cache.
/// see zbar_image_scanner_enable_cache()
void enable_cache (bool enable = true)
{
zbar_image_scanner_enable_cache(_scanner, enable);
}
/// remove previous results from scanner and image.
/// @see zbar_image_scanner_recycle_image()
/// @since 0.10
void recycle_image (Image &image)
{
zbar_image_scanner_recycle_image(_scanner, image);
}
/// retrieve decode results for last scanned image.
/// @see zbar_image_scanner_get_results()
/// @since 0.10
const SymbolSet get_results () const {
return(SymbolSet(zbar_image_scanner_get_results(_scanner)));
}
/// scan for symbols in provided image.
/// see zbar_scan_image()
int scan (Image& image)
{
return(zbar_scan_image(_scanner, image));
}
/// scan for symbols in provided image.
/// see zbar_scan_image()
ImageScanner& operator<< (Image& image)
{
scan(image);
return(*this);
}
private:
zbar_image_scanner_t *_scanner;
};
}
#endif

View File

@ -0,0 +1,223 @@
//------------------------------------------------------------------------
// Copyright 2007-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_PROCESSOR_H_
#define _ZBAR_PROCESSOR_H_
/// @file
/// Processor C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Processor.h"
#endif
#include "Exception.h"
#include "Image.h"
namespace zbar {
/// high-level self-contained image processor.
/// processes video and images for barcodes, optionally displaying
/// images to a library owned output window
class Processor {
public:
/// value to pass for no timeout.
static const int FOREVER = -1;
/// constructor.
Processor (bool threaded = true,
const char *video_device = "",
bool enable_display = true)
{
_processor = zbar_processor_create(threaded);
if(!_processor)
throw std::bad_alloc();
init(video_device, enable_display);
}
~Processor ()
{
zbar_processor_destroy(_processor);
}
/// cast to C processor object.
operator zbar_processor_t* ()
{
return(_processor);
}
/// opens a video input device and/or prepares to display output.
/// see zbar_processor_init()
void init (const char *video_device = "",
bool enable_display = true)
{
if(zbar_processor_init(_processor, video_device, enable_display))
throw_exception(_processor);
}
/// setup result handler callback.
/// see zbar_processor_set_data_handler()
void set_handler (Image::Handler& handler)
{
zbar_processor_set_data_handler(_processor, handler, &handler);
}
/// set config for indicated symbology (0 for all) to specified value.
/// @see zbar_processor_set_config()
/// @since 0.4
int set_config (zbar_symbol_type_t symbology,
zbar_config_t config,
int value)
{
return(zbar_processor_set_config(_processor, symbology,
config, value));
}
/// set config parsed from configuration string.
/// @see zbar_processor_parse_config()
/// @since 0.4
int set_config (std::string cfgstr)
{
return(zbar_processor_parse_config(_processor, cfgstr.c_str()));
}
/// retrieve the current state of the ouput window.
/// see zbar_processor_is_visible()
bool is_visible ()
{
int rc = zbar_processor_is_visible(_processor);
if(rc < 0)
throw_exception(_processor);
return(rc != 0);
}
/// show or hide the display window owned by the library.
/// see zbar_processor_set_visible()
void set_visible (bool visible = true)
{
if(zbar_processor_set_visible(_processor, visible) < 0)
throw_exception(_processor);
}
/// control the processor in free running video mode.
/// see zbar_processor_set_active()
void set_active (bool active = true)
{
if(zbar_processor_set_active(_processor, active) < 0)
throw_exception(_processor);
}
/// retrieve decode results for last scanned image.
/// @see zbar_processor_get_results()
/// @since 0.10
const SymbolSet get_results () const {
return(SymbolSet(zbar_processor_get_results(_processor)));
}
/// wait for input to the display window from the user.
/// see zbar_processor_user_wait()
int user_wait (int timeout = FOREVER)
{
int rc = zbar_processor_user_wait(_processor, timeout);
if(rc < 0)
throw_exception(_processor);
return(rc);
}
/// process from the video stream until a result is available.
/// see zbar_process_one()
void process_one (int timeout = FOREVER)
{
if(zbar_process_one(_processor, timeout) < 0)
throw_exception(_processor);
}
/// process the provided image for barcodes.
/// see zbar_process_image()
void process_image (Image& image)
{
if(zbar_process_image(_processor, image) < 0)
throw_exception(_processor);
}
/// process the provided image for barcodes.
/// see zbar_process_image()
Processor& operator<< (Image& image)
{
process_image(image);
return(*this);
}
/// force specific input and output formats for debug/testing.
/// see zbar_processor_force_format()
void force_format (unsigned long input_format,
unsigned long output_format)
{
if(zbar_processor_force_format(_processor, input_format,
output_format))
throw_exception(_processor);
}
/// force specific input and output formats for debug/testing.
/// see zbar_processor_force_format()
void force_format (std::string& input_format,
std::string& output_format)
{
unsigned long ifourcc = zbar_fourcc_parse(input_format.c_str());
unsigned long ofourcc = zbar_fourcc_parse(output_format.c_str());
if(zbar_processor_force_format(_processor, ifourcc, ofourcc))
throw_exception(_processor);
}
/// request a preferred size for the video image from the device.
/// see zbar_processor_request_size()
/// @since 0.6
void request_size (int width, int height)
{
zbar_processor_request_size(_processor, width, height);
}
/// request a preferred driver interface version for debug/testing.
/// see zbar_processor_request_interface()
/// @since 0.6
void request_interface (int version)
{
zbar_processor_request_interface(_processor, version);
}
/// request a preferred I/O mode for debug/testing.
/// see zbar_processor_request_iomode()
/// @since 0.7
void request_iomode (int iomode)
{
if(zbar_processor_request_iomode(_processor, iomode))
throw_exception(_processor);
}
private:
zbar_processor_t *_processor;
};
}
#endif

View File

@ -0,0 +1,169 @@
//------------------------------------------------------------------------
// Copyright 2008-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _QZBAR_H_
#define _QZBAR_H_
/// @file
/// Barcode Reader Qt4 Widget
#include <qwidget.h>
namespace zbar {
class QZBarThread;
/// barcode reader Qt4 widget.
/// embeds a barcode reader directly into a Qt4 based GUI. the widget
/// can process barcodes from a video source (using the QZBar::videoDevice
/// and QZBar::videoEnabled properties) or from individual QImages
/// supplied to the QZBar::scanImage() slot
/// @since 1.5
class QZBar : public QWidget
{
Q_OBJECT
/// the currently opened video device.
///
/// setting a new device opens it and automatically sets
/// QZBar::videoEnabled
///
/// @see videoDevice(), setVideoDevice()
Q_PROPERTY(QString videoDevice
READ videoDevice
WRITE setVideoDevice
DESIGNABLE false)
/// video device streaming state.
///
/// use to pause/resume video scanning.
///
/// @see isVideoEnabled(), setVideoEnabled()
Q_PROPERTY(bool videoEnabled
READ isVideoEnabled
WRITE setVideoEnabled
DESIGNABLE false)
/// video device opened state.
///
/// (re)setting QZBar::videoDevice should eventually cause it
/// to be opened or closed. any errors while streaming/scanning
/// will also cause the device to be closed
///
/// @see isVideoOpened()
Q_PROPERTY(bool videoOpened
READ isVideoOpened
DESIGNABLE false)
public:
/// constructs a barcode reader widget with the given @a parent
QZBar(QWidget *parent = NULL);
~QZBar();
/// retrieve the currently opened video device.
/// @returns the current video device or the empty string if no
/// device is opened
QString videoDevice() const;
/// retrieve the current video enabled state.
/// @returns true if video scanning is currently enabled, false
/// otherwise
bool isVideoEnabled() const;
/// retrieve the current video opened state.
/// @returns true if video device is currently opened, false otherwise
bool isVideoOpened() const;
/// @{
/// @internal
QSize sizeHint() const;
int heightForWidth(int) const;
QPaintEngine *paintEngine() const;
/// @}
public Q_SLOTS:
/// open a new video device.
///
/// use an empty string to close a currently opened device.
///
/// @note since opening a device may take some time, this call will
/// return immediately and the device will be opened asynchronously
void setVideoDevice(const QString &videoDevice);
/// enable/disable video scanning.
/// has no effect unless a video device is opened
void setVideoEnabled(bool videoEnabled = true);
/// scan for barcodes in a QImage.
void scanImage(const QImage &image);
Q_SIGNALS:
/// emitted when when a video device is opened or closed.
///
/// (re)setting QZBar::videoDevice should eventually cause it
/// to be opened or closed. any errors while streaming/scanning
/// will also cause the device to be closed
void videoOpened(bool videoOpened);
/// emitted when a barcode is decoded from an image.
/// the symbol type and contained data are provided as separate
/// parameters.
void decoded(int type, const QString &data);
/// emitted when a barcode is decoded from an image.
/// the symbol type name is prefixed to the data, separated by a
/// colon
void decodedText(const QString &text);
/// @{
/// @internal
protected:
void attach();
void showEvent(QShowEvent*);
void paintEvent(QPaintEvent*);
void resizeEvent(QResizeEvent*);
void changeEvent(QEvent*);
void dragEnterEvent(QDragEnterEvent*);
void dropEvent(QDropEvent*);
protected Q_SLOTS:
void sizeChange();
/// @}
private:
QZBarThread *thread;
QString _videoDevice;
bool _videoEnabled;
bool _attached;
};
};
#endif

View File

@ -0,0 +1,72 @@
//------------------------------------------------------------------------
// Copyright 2008-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _QZBARIMAGE_H_
#define _QZBARIMAGE_H_
/// @file
/// QImage to Image type conversion wrapper
#include <qimage.h>
#include <zbar.h>
namespace zbar {
/// wrap a QImage and convert into a format suitable for scanning.
class QZBarImage
: public Image
{
public:
/// construct a zbar library image based on an existing QImage.
QZBarImage (const QImage &qimg)
: qimg(qimg)
{
QImage::Format fmt = qimg.format();
if(fmt != QImage::Format_RGB32 &&
fmt != QImage::Format_ARGB32 &&
fmt != QImage::Format_ARGB32_Premultiplied)
throw FormatError();
unsigned bpl = qimg.bytesPerLine();
unsigned width = bpl / 4;
unsigned height = qimg.height();
set_size(width, height);
set_format(zbar_fourcc('B','G','R','4'));
unsigned long datalen = qimg.numBytes();
set_data(qimg.bits(), datalen);
if((width * 4 != bpl) ||
(width * height * 4 > datalen))
throw FormatError();
}
private:
QImage qimg;
};
};
#endif

View File

@ -0,0 +1,162 @@
//------------------------------------------------------------------------
// Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_SCANNER_H_
#define _ZBAR_SCANNER_H_
/// @file
/// Scanner C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Scanner.h"
#endif
#include <stdio.h>
namespace zbar {
/// low-level linear intensity sample stream scanner interface.
/// identifies "bar" edges and measures width between them.
/// optionally passes to bar width Decoder
class Scanner {
public:
/// constructor.
/// @param decoder reference to a Decoder instance which will
/// be passed scan results automatically
Scanner (Decoder& decoder)
{
_scanner = zbar_scanner_create(decoder._decoder);
}
/// constructor.
/// @param decoder pointer to a Decoder instance which will
/// be passed scan results automatically
Scanner (Decoder* decoder = NULL)
{
zbar_decoder_t *zdcode = NULL;
if(decoder)
zdcode = decoder->_decoder;
_scanner = zbar_scanner_create(zdcode);
}
~Scanner ()
{
zbar_scanner_destroy(_scanner);
}
/// clear all scanner state.
/// see zbar_scanner_reset()
void reset ()
{
zbar_scanner_reset(_scanner);
}
/// mark start of a new scan pass.
/// see zbar_scanner_new_scan()
zbar_symbol_type_t new_scan ()
{
_type = zbar_scanner_new_scan(_scanner);
return(_type);
}
/// flush scanner pipeline.
/// see zbar_scanner_flush()
zbar_symbol_type_t flush ()
{
_type = zbar_scanner_flush(_scanner);
return(_type);
}
/// process next sample intensity value.
/// see zbar_scan_y()
zbar_symbol_type_t scan_y (int y)
{
_type = zbar_scan_y(_scanner, y);
return(_type);
}
/// process next sample intensity value.
/// see zbar_scan_y()
Scanner& operator<< (int y)
{
_type = zbar_scan_y(_scanner, y);
return(*this);
}
/// process next sample from RGB (or BGR) triple.
/// see zbar_scan_rgb24()
zbar_symbol_type_t scan_rgb24 (unsigned char *rgb)
{
_type = zbar_scan_rgb24(_scanner, rgb);
return(_type);
}
/// process next sample from RGB (or BGR) triple.
/// see zbar_scan_rgb24()
Scanner& operator<< (unsigned char *rgb)
{
_type = zbar_scan_rgb24(_scanner, rgb);
return(*this);
}
/// retrieve last scanned width.
/// see zbar_scanner_get_width()
unsigned get_width () const
{
return(zbar_scanner_get_width(_scanner));
}
/// retrieve last scanned color.
/// see zbar_scanner_get_color()
zbar_color_t get_color () const
{
return(zbar_scanner_get_color(_scanner));
}
/// retrieve last scan result.
zbar_symbol_type_t get_type () const
{
return(_type);
}
/// cast to C scanner
operator zbar_scanner_t* () const
{
return(_scanner);
}
/// retrieve C scanner
const zbar_scanner_t *get_c_scanner () const
{
return(_scanner);
}
private:
zbar_scanner_t *_scanner;
zbar_symbol_type_t _type;
};
}
#endif

View File

@ -0,0 +1,541 @@
//------------------------------------------------------------------------
// Copyright 2007-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_SYMBOL_H_
#define _ZBAR_SYMBOL_H_
/// @file
/// Symbol C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Symbol.h"
#endif
#include <stdlib.h>
#include <string>
#include <ostream>
#include <assert.h>
namespace zbar {
class SymbolIterator;
/// container for decoded result symbols associated with an image
/// or a composite symbol.
class SymbolSet {
public:
/// constructor.
SymbolSet (const zbar_symbol_set_t *syms = NULL)
: _syms(syms)
{
ref();
}
/// copy constructor.
SymbolSet (const SymbolSet& syms)
: _syms(syms._syms)
{
ref();
}
/// destructor.
~SymbolSet ()
{
ref(-1);
}
/// assignment.
SymbolSet& operator= (const SymbolSet& syms)
{
syms.ref();
ref(-1);
_syms = syms._syms;
return(*this);
}
/// truth testing.
bool operator! () const
{
return(!_syms || !get_size());
}
/// manipulate reference count.
void ref (int delta = 1) const
{
if(_syms)
zbar_symbol_set_ref((zbar_symbol_set_t*)_syms, delta);
}
/// cast to C symbol set.
operator const zbar_symbol_set_t* () const
{
return(_syms);
}
int get_size () const
{
return((_syms) ? zbar_symbol_set_get_size(_syms) : 0);
}
/// create a new SymbolIterator over decoded results.
SymbolIterator symbol_begin() const;
/// return a SymbolIterator suitable for ending iteration.
const SymbolIterator symbol_end() const;
private:
const zbar_symbol_set_t *_syms;
};
/// decoded barcode symbol result object. stores type, data, and
/// image location of decoded symbol
class Symbol {
public:
/// image pixel location (x, y) coordinate tuple.
class Point {
public:
int x; ///< x-coordinate.
int y; ///< y-coordinate.
Point () { }
Point(int x, int y)
: x(x), y(y)
{ }
/// copy constructor.
Point (const Point& pt)
: x(pt.x),
y(pt.y)
{ }
/// assignment.
Point& operator= (const Point& pt)
{
x = pt.x;
y = pt.y;
return(*this);
}
};
/// iteration over Point objects in a symbol location polygon.
class PointIterator
: public std::iterator<std::input_iterator_tag, Point> {
public:
/// constructor.
PointIterator (const Symbol *sym = NULL,
int index = 0)
: _sym(sym),
_index(index)
{
if(sym)
sym->ref(1);
if(!sym ||
(unsigned)_index >= zbar_symbol_get_loc_size(*_sym))
_index = -1;
}
/// copy constructor.
PointIterator (const PointIterator& iter)
: _sym(iter._sym),
_index(iter._index)
{
if(_sym)
_sym->ref();
}
/// destructor.
~PointIterator ()
{
if(_sym)
_sym->ref(-1);
}
/// assignment.
PointIterator& operator= (const PointIterator& iter)
{
if(iter._sym)
iter._sym->ref();
if(_sym)
_sym->ref(-1);
_sym = iter._sym;
_index = iter._index;
return(*this);
}
/// truth testing.
bool operator! () const
{
return(!_sym || _index < 0);
}
/// advance iterator to next Point.
PointIterator& operator++ ()
{
unsigned int i = ++_index;
if(!_sym || i >= zbar_symbol_get_loc_size(*_sym))
_index = -1;
return(*this);
}
/// retrieve currently referenced Point.
const Point operator* () const
{
assert(!!*this);
if(!*this)
return(Point());
return(Point(zbar_symbol_get_loc_x(*_sym, _index),
zbar_symbol_get_loc_y(*_sym, _index)));
}
/// test if two iterators refer to the same Point in the same
/// Symbol.
bool operator== (const PointIterator& iter) const
{
return(_index == iter._index &&
((_index < 0) || _sym == iter._sym));
}
/// test if two iterators refer to the same Point in the same
/// Symbol.
bool operator!= (const PointIterator& iter) const
{
return(!(*this == iter));
}
private:
const Symbol *_sym;
int _index;
};
/// constructor.
Symbol (const zbar_symbol_t *sym = NULL)
: _xmlbuf(NULL),
_xmllen(0)
{
init(sym);
ref();
}
/// copy constructor.
Symbol (const Symbol& sym)
: _sym(sym._sym),
_type(sym._type),
_data(sym._data),
_xmlbuf(NULL),
_xmllen(0)
{
ref();
}
/// destructor.
~Symbol () {
if(_xmlbuf)
free(_xmlbuf);
ref(-1);
}
/// assignment.
Symbol& operator= (const Symbol& sym)
{
sym.ref(1);
ref(-1);
_sym = sym._sym;
_type = sym._type;
_data = sym._data;
return(*this);
}
Symbol& operator= (const zbar_symbol_t *sym)
{
if(sym)
zbar_symbol_ref(sym, 1);
ref(-1);
init(sym);
return(*this);
}
/// truth testing.
bool operator! () const
{
return(!_sym);
}
void ref (int delta = 1) const
{
if(_sym)
zbar_symbol_ref((zbar_symbol_t*)_sym, delta);
}
/// cast to C symbol.
operator const zbar_symbol_t* () const
{
return(_sym);
}
/// test if two Symbol objects refer to the same C symbol.
bool operator== (const Symbol& sym) const
{
return(_sym == sym._sym);
}
/// test if two Symbol objects refer to the same C symbol.
bool operator!= (const Symbol& sym) const
{
return(!(*this == sym));
}
/// retrieve type of decoded symbol.
zbar_symbol_type_t get_type () const
{
return(_type);
}
/// retrieve the string name of the symbol type.
const std::string get_type_name () const
{
return(zbar_get_symbol_name(_type));
}
/// retrieve the string name for any addon.
/// @deprecated in 0.11
const std::string get_addon_name () const
{
return(zbar_get_addon_name(_type));
}
/// retrieve data decoded from symbol.
const std::string get_data () const
{
return(_data);
}
/// retrieve length of binary data
unsigned get_data_length () const
{
return((_sym) ? zbar_symbol_get_data_length(_sym) : 0);
}
/// retrieve inter-frame coherency count.
/// see zbar_symbol_get_count()
/// @since 0.5
int get_count () const
{
return((_sym) ? zbar_symbol_get_count(_sym) : -1);
}
/// retrieve loosely defined relative quality metric.
/// see zbar_symbol_get_quality()
/// @since 0.11
int get_quality () const
{
return((_sym) ? zbar_symbol_get_quality(_sym) : 0);
}
SymbolSet get_components () const
{
return(SymbolSet((_sym) ? zbar_symbol_get_components(_sym) : NULL));
}
/// create a new PointIterator at the start of the location
/// polygon.
PointIterator point_begin() const
{
return(PointIterator(this));
}
/// return a PointIterator suitable for ending iteration.
const PointIterator point_end() const
{
return(PointIterator());
}
/// see zbar_symbol_get_loc_size().
int get_location_size () const
{
return((_sym) ? zbar_symbol_get_loc_size(_sym) : 0);
}
/// see zbar_symbol_get_loc_x().
int get_location_x (unsigned index) const
{
return((_sym) ? zbar_symbol_get_loc_x(_sym, index) : -1);
}
/// see zbar_symbol_get_loc_y().
int get_location_y (unsigned index) const
{
return((_sym) ? zbar_symbol_get_loc_y(_sym, index) : -1);
}
/// see zbar_symbol_get_orientation().
/// @since 0.11
int get_orientation () const
{
return(zbar_symbol_get_orientation(_sym));
}
/// see zbar_symbol_xml().
const std::string xml () const
{
if(!_sym)
return("");
return(zbar_symbol_xml(_sym, (char**)&_xmlbuf, (unsigned*)&_xmllen));
}
protected:
/// (re)initialize Symbol from C symbol object.
void init (const zbar_symbol_t *sym = NULL)
{
_sym = sym;
if(sym) {
_type = zbar_symbol_get_type(sym);
_data = std::string(zbar_symbol_get_data(sym),
zbar_symbol_get_data_length(sym));
}
else {
_type = ZBAR_NONE;
_data = "";
}
}
private:
const zbar_symbol_t *_sym;
zbar_symbol_type_t _type;
std::string _data;
char *_xmlbuf;
unsigned _xmllen;
};
/// iteration over Symbol result objects in a scanned Image or SymbolSet.
class SymbolIterator
: public std::iterator<std::input_iterator_tag, Symbol> {
public:
/// default constructor.
SymbolIterator ()
{ }
/// constructor.
SymbolIterator (const SymbolSet &syms)
: _syms(syms)
{
const zbar_symbol_set_t *zsyms = _syms;
if(zsyms)
_sym = zbar_symbol_set_first_symbol(zsyms);
}
/// copy constructor.
SymbolIterator (const SymbolIterator& iter)
: _syms(iter._syms)
{
const zbar_symbol_set_t *zsyms = _syms;
if(zsyms)
_sym = zbar_symbol_set_first_symbol(zsyms);
}
~SymbolIterator ()
{
}
/// assignment.
SymbolIterator& operator= (const SymbolIterator& iter)
{
_syms = iter._syms;
_sym = iter._sym;
return(*this);
}
bool operator! () const
{
return(!_syms || !_sym);
}
/// advance iterator to next Symbol.
SymbolIterator& operator++ ()
{
if(!!_sym)
_sym = zbar_symbol_next(_sym);
else if(!!_syms)
_sym = zbar_symbol_set_first_symbol(_syms);
return(*this);
}
/// retrieve currently referenced Symbol.
const Symbol operator* () const
{
return(_sym);
}
/// access currently referenced Symbol.
const Symbol* operator-> () const
{
return(&_sym);
}
/// test if two iterators refer to the same Symbol
bool operator== (const SymbolIterator& iter) const
{
// it is enough to test the symbols, as they belong
// to only one set (also simplifies invalid case)
return(_sym == iter._sym);
}
/// test if two iterators refer to the same Symbol
bool operator!= (const SymbolIterator& iter) const
{
return(!(*this == iter));
}
const SymbolIterator end () const {
return(SymbolIterator());
}
private:
SymbolSet _syms;
Symbol _sym;
};
__inline SymbolIterator SymbolSet::symbol_begin () const {
return(SymbolIterator(*this));
}
__inline const SymbolIterator SymbolSet::symbol_end () const {
return(SymbolIterator());
}
/// @relates Symbol
/// stream the string representation of a Symbol.
static __inline std::ostream& operator<< (std::ostream& out,
const Symbol& sym)
{
out << sym.get_type_name() << ":" << sym.get_data();
return(out);
}
}
#endif

View File

@ -0,0 +1,170 @@
//------------------------------------------------------------------------
// Copyright 2007-2010 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_VIDEO_H_
#define _ZBAR_VIDEO_H_
/// @file
/// Video Input C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Video.h"
#endif
#include "Image.h"
namespace zbar {
/// mid-level video source abstraction.
/// captures images from a video device
class Video {
public:
/// constructor.
Video (zbar_video_t *video = NULL)
{
if(video)
_video = video;
else
_video = zbar_video_create();
}
/// constructor.
Video (std::string& device)
{
_video = zbar_video_create();
open(device);
}
~Video ()
{
zbar_video_destroy(_video);
}
/// cast to C video object.
operator zbar_video_t* () const
{
return(_video);
}
/// open and probe a video device.
void open (std::string& device)
{
if(zbar_video_open(_video, device.c_str()))
throw_exception(_video);
}
/// close video device if open.
void close ()
{
if(zbar_video_open(_video, NULL))
throw_exception(_video);
}
/// initialize video using a specific format for debug.
/// see zbar_video_init()
void init (unsigned long fourcc)
{
if(zbar_video_init(_video, fourcc))
throw_exception(_video);
}
/// initialize video using a specific format for debug.
/// see zbar_video_init()
void init (std::string& format)
{
unsigned int fourcc = zbar_fourcc_parse(format.c_str());
if(zbar_video_init(_video, fourcc))
throw_exception(_video);
}
/// retrieve file descriptor associated with open *nix video device.
/// see zbar_video_get_fd()
int get_fd ()
{
return(zbar_video_get_fd(_video));
}
/// retrieve current output image width.
/// see zbar_video_get_width()
int get_width ()
{
return(zbar_video_get_width(_video));
}
/// retrieve current output image height.
/// see zbar_video_get_height()
int get_height ()
{
return(zbar_video_get_height(_video));
}
/// start/stop video capture.
/// see zbar_video_enable()
void enable (bool enable = true)
{
if(zbar_video_enable(_video, enable))
throw_exception(_video);
}
/// retrieve next captured image.
/// see zbar_video_next_image()
Image next_image ()
{
zbar_image_t *img = zbar_video_next_image(_video);
if(!img)
throw_exception(_video);
return(Image(img));
}
/// request a preferred size for the video image from the device.
/// see zbar_video_request_size()
/// @since 0.6
void request_size (int width, int height)
{
zbar_video_request_size(_video, width, height);
}
/// request a preferred driver interface version for debug/testing.
/// see zbar_video_request_interface()
/// @since 0.6
void request_interface (int version)
{
zbar_video_request_interface(_video, version);
}
/// request a preferred I/O mode for debug/testing.
/// see zbar_video_request_iomode()
/// @since 0.7
void request_iomode (int iomode)
{
if(zbar_video_request_iomode(_video, iomode))
throw_exception(_video);
}
private:
zbar_video_t *_video;
};
}
#endif

View File

@ -0,0 +1,136 @@
//------------------------------------------------------------------------
// Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
//
// This file is part of the ZBar Bar Code Reader.
//
// The ZBar Bar Code Reader is free software; you can redistribute it
// and/or modify it under the terms of the GNU Lesser Public License as
// published by the Free Software Foundation; either version 2.1 of
// the License, or (at your option) any later version.
//
// The ZBar Bar Code Reader is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser Public License for more details.
//
// You should have received a copy of the GNU Lesser Public License
// along with the ZBar Bar Code Reader; if not, write to the Free
// Software Foundation, Inc., 51 Franklin St, Fifth Floor,
// Boston, MA 02110-1301 USA
//
// http://sourceforge.net/projects/zbar
//------------------------------------------------------------------------
#ifndef _ZBAR_WINDOW_H_
#define _ZBAR_WINDOW_H_
/// @file
/// Output Window C++ wrapper
#ifndef _ZBAR_H_
# error "include zbar.h in your application, **not** zbar/Window.h"
#endif
#include "Image.h"
namespace zbar {
/// mid-level output window abstraction.
/// displays images to user-specified platform specific output window
class Window {
public:
/// constructor.
Window (zbar_window_t *window = NULL)
{
if(window)
_window = window;
else
_window = zbar_window_create();
}
/// constructor.
Window (void *x11_display_w32_hwnd,
unsigned long x11_drawable)
{
_window = zbar_window_create();
attach(x11_display_w32_hwnd, x11_drawable);
}
~Window ()
{
zbar_window_destroy(_window);
}
/// cast to C window object.
operator zbar_window_t* () const
{
return(_window);
}
/// associate reader with an existing platform window.
/// see zbar_window_attach()
void attach (void *x11_display_w32_hwnd,
unsigned long x11_drawable = 0)
{
if(zbar_window_attach(_window,
x11_display_w32_hwnd, x11_drawable) < 0)
throw_exception(_window);
}
/// control content level of the reader overlay.
/// see zbar_window_set_overlay()
void set_overlay (int level)
{
zbar_window_set_overlay(_window, level);
}
/// retrieve current content level of reader overlay.
/// see zbar_window_get_overlay()
/// draw a new image into the output window.
/// see zbar_window_draw()
void draw (Image& image)
{
if(zbar_window_draw(_window, image) < 0)
throw_exception(_window);
}
/// clear the image from the output window.
/// see zbar_window_draw()
void clear ()
{
if(zbar_window_draw(_window, NULL) < 0)
throw_exception(_window);
}
/// redraw the last image.
/// zbar_window_redraw()
void redraw ()
{
if(zbar_window_redraw(_window) < 0)
throw_exception(_window);
}
/// resize the image window.
/// zbar_window_resize()
void resize (unsigned width, unsigned height)
{
if(zbar_window_resize(_window, width, height) < 0)
throw_exception(_window);
}
private:
zbar_window_t *_window;
};
/// select a compatible format between video input and output window.
/// see zbar_negotiate_format()
static inline void negotiate_format (Video& video, Window& window)
{
if(zbar_negotiate_format(video, window) < 0)
throw_exception(video);
}
}
#endif

View File

@ -0,0 +1,215 @@
/*------------------------------------------------------------------------
* Copyright 2008-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
*
* This file is part of the ZBar Bar Code Reader.
*
* The ZBar Bar Code Reader is free software; you can redistribute it
* and/or modify it under the terms of the GNU Lesser Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* The ZBar Bar Code Reader is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser Public License for more details.
*
* You should have received a copy of the GNU Lesser Public License
* along with the ZBar Bar Code Reader; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301 USA
*
* http://sourceforge.net/projects/zbar
*------------------------------------------------------------------------*/
#ifndef __ZBAR_GTK_H__
#define __ZBAR_GTK_H__
/** SECTION:ZBarGtk
* @short_description: barcode reader GTK+ 2.x widget
* @include: zbar/zbargtk.h
*
* embeds a barcode reader directly into a GTK+ based GUI. the widget
* can process barcodes from a video source (using the
* #ZBarGtk:video-device and #ZBarGtk:video-enabled properties) or
* from individual GdkPixbufs supplied to zbar_gtk_scan_image()
*
* Since: 1.5
*/
#include <glib.h>
#include <glib-object.h>
#include <gtk/gtktable.h>
#include <zbar.h>
G_BEGIN_DECLS
#define ZBAR_TYPE_GTK (zbar_gtk_get_type())
#define ZBAR_GTK(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), ZBAR_TYPE_GTK, ZBarGtk))
#define ZBAR_GTK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), ZBAR_TYPE_GTK, ZBarGtkClass))
#define ZBAR_IS_GTK(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), ZBAR_TYPE_GTK))
#define ZBAR_IS_GTK_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE((klass), ZBAR_TYPE_GTK))
#define ZBAR_GTK_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), ZBAR_TYPE_GTK, ZBarGtkClass))
typedef struct _ZBarGtk ZBarGtk;
typedef struct _ZBarGtkClass ZBarGtkClass;
struct _ZBarGtk {
GtkWidget widget;
gpointer *_private;
/* properties */
/**
* ZBarGtk:video-device:
*
* the currently set video device.
*
* setting a new device opens it and automatically sets
* #ZBarGtk:video-enabled. set the empty string ("") or NULL to
* close.
*/
/**
* ZBarGtk:video-enabled:
*
* video device streaming state.
*
* use to pause/resume video scanning.
*/
/**
* ZBarGtk:video-opened:
*
* video device opened state.
*
* (re)setting #ZBarGtk:video-device should eventually cause it
* to be opened or closed. any errors while streaming/scanning
* will also cause the device to be closed
*/
};
struct _ZBarGtkClass {
GtkWidgetClass parent_class;
/* signals */
/**
* ZBarGtk::decoded:
* @widget: the object that received the signal
* @symbol_type: the type of symbol decoded (a zbar_symbol_type_t)
* @data: the data decoded from the symbol
*
* emitted when a barcode is decoded from an image.
* the symbol type and contained data are provided as separate
* parameters
*/
void (*decoded) (ZBarGtk *zbar,
zbar_symbol_type_t symbol_type,
const char *data);
/**
* ZBarGtk::decoded-text:
* @widget: the object that received the signal
* @text: the decoded data prefixed by the string name of the
* symbol type (separated by a colon)
*
* emitted when a barcode is decoded from an image.
* the symbol type name is prefixed to the data, separated by a
* colon
*/
void (*decoded_text) (ZBarGtk *zbar,
const char *text);
/**
* ZBarGtk::scan-image:
* @widget: the object that received the signal
* @image: the image to scan for barcodes
*/
void (*scan_image) (ZBarGtk *zbar,
GdkPixbuf *image);
};
GType zbar_gtk_get_type(void) G_GNUC_CONST;
/**
* zbar_gtk_new:
* create a new barcode reader widget instance.
* initially has no associated video device or image.
*
* Returns: a new #ZBarGtk widget instance
*/
GtkWidget *zbar_gtk_new(void);
/**
* zbar_gtk_scan_image:
*
*/
void zbar_gtk_scan_image(ZBarGtk *zbar,
GdkPixbuf *image);
/** retrieve the currently opened video device.
*
* Returns: the current video device or NULL if no device is opened
*/
const char *zbar_gtk_get_video_device(ZBarGtk *zbar);
/** open a new video device.
*
* @video_device: the platform specific name of the device to open.
* use NULL to close a currently opened device.
*
* @note since opening a device may take some time, this call will
* return immediately and the device will be opened asynchronously
*/
void zbar_gtk_set_video_device(ZBarGtk *zbar,
const char *video_device);
/** retrieve the current video enabled state.
*
* Returns: true if video scanning is currently enabled, false otherwise
*/
gboolean zbar_gtk_get_video_enabled(ZBarGtk *zbar);
/** enable/disable video scanning.
* @video_enabled: true to enable video scanning, false to disable
*
* has no effect unless a video device is opened
*/
void zbar_gtk_set_video_enabled(ZBarGtk *zbar,
gboolean video_enabled);
/** retrieve the current video opened state.
*
* Returns: true if video device is currently opened, false otherwise
*/
gboolean zbar_gtk_get_video_opened(ZBarGtk *zbar);
/** set video camera resolution.
* @width: width in pixels
* @height: height in pixels
*
* @note this call must be made before video is initialized
*/
void zbar_gtk_request_video_size(ZBarGtk *zbar,
int width,
int height);
/**
* utility function to populate a zbar_image_t from a GdkPixbuf.
* @image: the zbar library image destination to populate
* @pixbuf: the GdkPixbuf source
*
* Returns: TRUE if successful or FALSE if the conversion could not be
* performed for some reason
*/
gboolean zbar_gtk_image_from_pixbuf(zbar_image_t *image,
GdkPixbuf *pixbuf);
G_END_DECLS
#endif

View File

@ -0,0 +1,58 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __BARCODE_FORMAT_H__
#define __BARCODE_FORMAT_H__
/*
* BarcodeFormat.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace zxing {
class BarcodeFormat {
public:
// if you update the enum, update BarcodeFormat.cpp
enum Value {
NONE,
AZTEC,
CODABAR,
CODE_39,
CODE_93,
CODE_128,
DATA_MATRIX,
EAN_8,
EAN_13,
ITF,
MAXICODE,
PDF_417,
QR_CODE,
RSS_14,
RSS_EXPANDED,
UPC_A,
UPC_E,
UPC_EAN_EXTENSION
};
BarcodeFormat(Value v) : value(v) {}
const Value value;
operator Value () const { return value; }
static char const* barcodeFormatNames[];
};
}
#endif // __BARCODE_FORMAT_H__

View File

@ -0,0 +1,49 @@
#ifndef BINARIZER_H_
#define BINARIZER_H_
/*
* Binarizer.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/LuminanceSource.h>
#include <zxing/common/BitArray.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/common/Counted.h>
namespace zxing {
class Binarizer : public Counted {
private:
Ref<LuminanceSource> source_;
public:
Binarizer(Ref<LuminanceSource> source);
virtual ~Binarizer();
virtual Ref<BitArray> getBlackRow(int y, Ref<BitArray> row) = 0;
virtual Ref<BitMatrix> getBlackMatrix() = 0;
Ref<LuminanceSource> getLuminanceSource() const;
virtual Ref<Binarizer> createBinarizer(Ref<LuminanceSource> source) = 0;
int getWidth() const;
int getHeight() const;
};
}
#endif /* BINARIZER_H_ */

View File

@ -0,0 +1,55 @@
#ifndef __BINARYBITMAP_H__
#define __BINARYBITMAP_H__
/*
* BinaryBitmap.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/common/Counted.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/common/BitArray.h>
#include <zxing/Binarizer.h>
namespace zxing {
class BinaryBitmap : public Counted {
private:
Ref<Binarizer> binarizer_;
public:
BinaryBitmap(Ref<Binarizer> binarizer);
virtual ~BinaryBitmap();
Ref<BitArray> getBlackRow(int y, Ref<BitArray> row);
Ref<BitMatrix> getBlackMatrix();
Ref<LuminanceSource> getLuminanceSource() const;
int getWidth() const;
int getHeight() const;
bool isRotateSupported() const;
Ref<BinaryBitmap> rotateCounterClockwise();
bool isCropSupported() const;
Ref<BinaryBitmap> crop(int left, int top, int width, int height);
};
}
#endif /* BINARYBITMAP_H_ */

View File

@ -0,0 +1,34 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __CHECKSUM_EXCEPTION_H__
#define __NOT_FOUND_EXCEPTION_H__
/*
* Copyright 20011 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/ReaderException.h>
namespace zxing {
class ChecksumException : public ReaderException {
typedef ReaderException Base;
public:
ChecksumException() throw();
ChecksumException(const char* msg) throw();
~ChecksumException() throw();
};
}
#endif // __CHECKSUM_EXCEPTION_H__

View File

@ -0,0 +1,85 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __DECODEHINTS_H_
#define __DECODEHINTS_H_
/*
* DecodeHintType.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/BarcodeFormat.h>
#include <zxing/ResultPointCallback.h>
namespace zxing {
typedef unsigned int DecodeHintType;
class DecodeHints;
DecodeHints operator | (DecodeHints const&, DecodeHints const&);
class DecodeHints {
private:
DecodeHintType hints;
Ref<ResultPointCallback> callback;
public:
static const DecodeHintType AZTEC_HINT = 1 << BarcodeFormat::AZTEC;
static const DecodeHintType CODABAR_HINT = 1 << BarcodeFormat::CODABAR;
static const DecodeHintType CODE_39_HINT = 1 << BarcodeFormat::CODE_39;
static const DecodeHintType CODE_93_HINT = 1 << BarcodeFormat::CODE_93;
static const DecodeHintType CODE_128_HINT = 1 << BarcodeFormat::CODE_128;
static const DecodeHintType DATA_MATRIX_HINT = 1 << BarcodeFormat::DATA_MATRIX;
static const DecodeHintType EAN_8_HINT = 1 << BarcodeFormat::EAN_8;
static const DecodeHintType EAN_13_HINT = 1 << BarcodeFormat::EAN_13;
static const DecodeHintType ITF_HINT = 1 << BarcodeFormat::ITF;
static const DecodeHintType MAXICODE_HINT = 1 << BarcodeFormat::MAXICODE;
static const DecodeHintType PDF_417_HINT = 1 << BarcodeFormat::PDF_417;
static const DecodeHintType QR_CODE_HINT = 1 << BarcodeFormat::QR_CODE;
static const DecodeHintType RSS_14_HINT = 1 << BarcodeFormat::RSS_14;
static const DecodeHintType RSS_EXPANDED_HINT = 1 << BarcodeFormat::RSS_EXPANDED;
static const DecodeHintType UPC_A_HINT = 1 << BarcodeFormat::UPC_A;
static const DecodeHintType UPC_E_HINT = 1 << BarcodeFormat::UPC_E;
static const DecodeHintType UPC_EAN_EXTENSION_HINT = 1 << BarcodeFormat::UPC_EAN_EXTENSION;
static const DecodeHintType TRYHARDER_HINT = 1 << 31;
static const DecodeHintType CHARACTER_SET = 1 << 30;
// static const DecodeHintType ALLOWED_LENGTHS = 1 << 29;
// static const DecodeHintType ASSUME_CODE_39_CHECK_DIGIT = 1 << 28;
static const DecodeHintType ASSUME_GS1 = 1 << 27;
// static const DecodeHintType NEED_RESULT_POINT_CALLBACK = 1 << 26;
static const DecodeHints PRODUCT_HINT;
static const DecodeHints ONED_HINT;
static const DecodeHints DEFAULT_HINT;
DecodeHints();
DecodeHints(DecodeHintType init);
void addFormat(BarcodeFormat toadd);
bool containsFormat(BarcodeFormat tocheck) const;
bool isEmpty() const { return (hints == 0); }
void clear() { hints = 0; }
void setTryHarder(bool toset);
bool getTryHarder() const;
void setResultPointCallback(Ref<ResultPointCallback> const&);
Ref<ResultPointCallback> getResultPointCallback() const;
friend DecodeHints operator | (DecodeHints const&, DecodeHints const&);
};
}
#endif

View File

@ -0,0 +1,51 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __EXCEPTION_H__
#define __EXCEPTION_H__
/*
* Exception.h
* ZXing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include <exception>
namespace zxing {
class Exception : public std::exception {
private:
char const* const message;
public:
Exception() throw() : message(0) {}
Exception(const char* msg) throw() : message(copy(msg)) {}
Exception(Exception const& that) throw() : std::exception(that), message(copy(that.message)) {}
~Exception() throw() {
if (message) {
deleteMessage();
}
}
char const* what() const throw() { return message ? message : ""; }
private:
static char const* copy(char const*);
void deleteMessage();
};
}
#endif // __EXCEPTION_H__

View File

@ -0,0 +1,37 @@
#ifndef __FORMAT_EXCEPTION_H__
#define __FORMAT_EXCEPTION_H__
/*
* FormatException.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/ReaderException.h>
namespace zxing {
class FormatException : public ReaderException {
public:
FormatException();
FormatException(const char* msg);
~FormatException() throw();
static FormatException const& getFormatInstance();
};
}
#endif // __FORMAT_EXCEPTION_H__

View File

@ -0,0 +1,35 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __ILLEGAL_STATE_EXCEPTION_H__
#define __ILLEGAL_STATE_EXCEPTION_H__
/*
* Copyright 20011 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may illegal use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/ReaderException.h>
namespace zxing {
class IllegalStateException : public ReaderException {
public:
IllegalStateException() throw() {}
IllegalStateException(const char* msg) throw() : ReaderException(msg) {}
~IllegalStateException() throw() {}
};
}
#endif // __ILLEGAL_STATE_EXCEPTION_H__

View File

@ -0,0 +1,48 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __INVERTEDLUMINANCESOURCE_H__
#define __INVERTEDLUMINANCESOURCE_H__
/*
* Copyright 2013 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/ZXing.h>
#include <zxing/LuminanceSource.h>
namespace zxing {
class InvertedLuminanceSource : public LuminanceSource {
private:
typedef LuminanceSource Super;
const Ref<LuminanceSource> delegate;
public:
InvertedLuminanceSource(Ref<LuminanceSource> const&);
ArrayRef<char> getRow(int y, ArrayRef<char> row) const;
ArrayRef<char> getMatrix() const;
boolean isCropSupported() const;
Ref<LuminanceSource> crop(int left, int top, int width, int height) const;
boolean isRotateSupported() const;
virtual Ref<LuminanceSource> invert() const;
Ref<LuminanceSource> rotateCounterClockwise() const;
};
}
#endif /* INVERTEDLUMINANCESOURCE_H_ */

View File

@ -0,0 +1,59 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __LUMINANCESOURCE_H__
#define __LUMINANCESOURCE_H__
/*
* LuminanceSource.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/common/Counted.h>
#include <zxing/common/Array.h>
#include <string.h>
namespace zxing {
class LuminanceSource : public Counted {
private:
const int width;
const int height;
public:
LuminanceSource(int width, int height);
virtual ~LuminanceSource();
int getWidth() const { return width; }
int getHeight() const { return height; }
// Callers take ownership of the returned memory and must call delete [] on it themselves.
virtual ArrayRef<char> getRow(int y, ArrayRef<char> row) const = 0;
virtual ArrayRef<char> getMatrix() const = 0;
virtual bool isCropSupported() const;
virtual Ref<LuminanceSource> crop(int left, int top, int width, int height) const;
virtual bool isRotateSupported() const;
virtual Ref<LuminanceSource> invert() const;
virtual Ref<LuminanceSource> rotateCounterClockwise() const;
operator std::string() const;
};
}
#endif /* LUMINANCESOURCE_H_ */

View File

@ -0,0 +1,48 @@
#ifndef __MULTI_FORMAT_READER_H__
#define __MULTI_FORMAT_READER_H__
/*
* MultiFormatBarcodeReader.h
* ZXing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/Reader.h>
#include <zxing/common/BitArray.h>
#include <zxing/Result.h>
#include <zxing/DecodeHints.h>
namespace zxing {
class MultiFormatReader : public Reader {
private:
Ref<Result> decodeInternal(Ref<BinaryBitmap> image);
std::vector<Ref<Reader> > readers_;
DecodeHints hints_;
public:
MultiFormatReader();
Ref<Result> decode(Ref<BinaryBitmap> image);
Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);
Ref<Result> decodeWithState(Ref<BinaryBitmap> image);
void setHints(DecodeHints hints);
~MultiFormatReader();
};
}
#endif

View File

@ -0,0 +1,35 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __NOT_FOUND_EXCEPTION_H__
#define __NOT_FOUND_EXCEPTION_H__
/*
* Copyright 20011 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/ReaderException.h>
namespace zxing {
class NotFoundException : public ReaderException {
public:
NotFoundException() throw() {}
NotFoundException(const char* msg) throw() : ReaderException(msg) {}
~NotFoundException() throw() {}
};
}
#endif // __NOT_FOUND_EXCEPTION_H__

View File

@ -0,0 +1,40 @@
#ifndef __READER_H__
#define __READER_H__
/*
* Reader.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/BinaryBitmap.h>
#include <zxing/Result.h>
#include <zxing/DecodeHints.h>
namespace zxing {
class Reader : public Counted {
protected:
Reader() {}
public:
virtual Ref<Result> decode(Ref<BinaryBitmap> image);
virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints) = 0;
virtual ~Reader();
};
}
#endif // __READER_H__

View File

@ -0,0 +1,37 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __READER_EXCEPTION_H__
#define __READER_EXCEPTION_H__
/*
* ReaderException.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/Exception.h>
namespace zxing {
class ReaderException : public Exception {
public:
ReaderException() throw() {}
ReaderException(char const* msg) throw() : Exception(msg) {}
~ReaderException() throw() {}
};
}
#endif // __READER_EXCEPTION_H__

View File

@ -0,0 +1,55 @@
#ifndef __RESULT_H__
#define __RESULT_H__
/*
* Result.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string>
#include <zxing/common/Array.h>
#include <zxing/common/Counted.h>
#include <zxing/common/Str.h>
#include <zxing/ResultPoint.h>
#include <zxing/BarcodeFormat.h>
namespace zxing {
class Result : public Counted {
private:
Ref<String> text_;
ArrayRef<char> rawBytes_;
ArrayRef< Ref<ResultPoint> > resultPoints_;
BarcodeFormat format_;
public:
Result(Ref<String> text,
ArrayRef<char> rawBytes,
ArrayRef< Ref<ResultPoint> > resultPoints,
BarcodeFormat format);
~Result();
Ref<String> getText();
ArrayRef<char> getRawBytes();
ArrayRef< Ref<ResultPoint> > const& getResultPoints() const;
ArrayRef< Ref<ResultPoint> >& getResultPoints();
BarcodeFormat getBarcodeFormat() const;
friend std::ostream& operator<<(std::ostream& out, Result& result);
};
}
#endif // __RESULT_H__

View File

@ -0,0 +1,55 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __RESULT_POINT_H__
#define __RESULT_POINT_H__
/*
* ResultPoint.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/common/Counted.h>
#include <vector>
namespace zxing {
class ResultPoint : public Counted {
protected:
const float posX_;
const float posY_;
public:
ResultPoint();
ResultPoint(float x, float y);
ResultPoint(int x, int y);
virtual ~ResultPoint();
virtual float getX() const;
virtual float getY() const;
bool equals(Ref<ResultPoint> other);
static void orderBestPatterns(std::vector<Ref<ResultPoint> >& patterns);
static float distance(Ref<ResultPoint> point1, Ref<ResultPoint> point2);
static float distance(float x1, float x2, float y1, float y2);
private:
static float crossProductZ(Ref<ResultPoint> pointA, Ref<ResultPoint> pointB, Ref<ResultPoint> pointC);
};
}
#endif // __RESULT_POINT_H__

View File

@ -0,0 +1,39 @@
#ifndef __RESULT_POINT_CALLBACK_H__
#define __RESULT_POINT_CALLBACK_H__
/*
* ResultPointCallback.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/common/Counted.h>
namespace zxing {
class ResultPoint;
class ResultPointCallback : public Counted {
protected:
ResultPointCallback() {}
public:
virtual void foundPossibleResultPoint(ResultPoint const& point) = 0;
virtual ~ResultPointCallback();
};
}
#endif // __RESULT_POINT_CALLBACK_H__

View File

@ -0,0 +1,134 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Copyright 2013 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ZXING_H_
#define __ZXING_H_
#define ZXING_ARRAY_LEN(v) ((int)(sizeof(v)/sizeof(v[0])))
#define ZX_LOG_DIGITS(digits) \
((digits == 8) ? 3 : \
((digits == 16) ? 4 : \
((digits == 32) ? 5 : \
((digits == 64) ? 6 : \
((digits == 128) ? 7 : \
(-1))))))
#ifndef ZXING_DEBUG
#define ZXING_DEBUG 0
#endif
namespace zxing {
typedef char byte;
typedef bool boolean;
}
#include <limits>
#if defined(_WIN32) || defined(_WIN64)
#include <float.h>
namespace zxing {
inline bool isnan(float v) { return _isnan(v) != 0; }
inline bool isnan(double v) { return _isnan(v) != 0; }
inline float nan() { return std::numeric_limits<float>::quiet_NaN(); }
}
#else
#include <cmath>
namespace zxing {
inline bool isnan(float v) { return std::isnan(v); }
inline bool isnan(double v) { return std::isnan(v); }
inline float nan() { return std::numeric_limits<float>::quiet_NaN(); }
}
#endif
#if ZXING_DEBUG
#include <iostream>
#include <string>
using std::cout;
using std::cerr;
using std::endl;
using std::flush;
using std::string;
using std::ostream;
#if ZXING_DEBUG_TIMER
#include <sys/time.h>
namespace zxing {
class DebugTimer {
public:
DebugTimer(char const* string_) : chars(string_) {
gettimeofday(&start, 0);
}
DebugTimer(std::string const& string_) : chars(0), string(string_) {
gettimeofday(&start, 0);
}
void mark(char const* string) {
struct timeval end;
gettimeofday(&end, 0);
int diff =
(end.tv_sec - start.tv_sec) * 1000 * 1000 + (end.tv_usec - start.tv_usec);
cerr << diff << " " << string << '\n';
}
void mark(std::string string) {
mark(string.c_str());
}
~DebugTimer() {
if (chars) {
mark(chars);
}
else {
mark(string.c_str());
}
}
private:
char const* const chars;
std::string string;
struct timeval start;
};
}
#define ZXING_TIME(string) DebugTimer __timer__ (string)
#define ZXING_TIME_MARK(string) __timer__.mark(string)
#endif
#endif // ZXING_DEBUG
#ifndef ZXING_TIME
#define ZXING_TIME(string) (void)0
#endif
#ifndef ZXING_TIME_MARK
#define ZXING_TIME_MARK(string) (void)0
#endif
#endif

View File

@ -0,0 +1,47 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* AtztecDetecorResult.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/common/DetectorResult.h>
#ifndef ZXingWidget_AtztecDetecorResult_h
#define ZXingWidget_AtztecDetecorResult_h
namespace zxing {
namespace aztec {
class AztecDetectorResult : public DetectorResult {
private:
bool compact_;
int nbDatablocks_, nbLayers_;
public:
AztecDetectorResult(Ref<BitMatrix> bits,
ArrayRef< Ref<ResultPoint> > points,
bool compact,
int nbDatablocks,
int nbLayers);
bool isCompact();
int getNBDatablocks();
int getNBLayers();
};
}
}
#endif

View File

@ -0,0 +1,49 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* AztecReader.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <zxing/Reader.h>
#include <zxing/aztec/decoder/Decoder.h>
#include <zxing/DecodeHints.h>
#ifndef ZXingWidget_AztecReader_h
#define ZXingWidget_AztecReader_h
namespace zxing {
namespace aztec {
class AztecReader : public Reader {
private:
Decoder decoder_;
protected:
Decoder& getDecoder();
public:
AztecReader();
virtual Ref<Result> decode(Ref<BinaryBitmap> image);
virtual Ref<Result> decode(Ref<BinaryBitmap> image, DecodeHints hints);
virtual ~AztecReader();
};
}
}
#endif

View File

@ -0,0 +1,69 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Decoder.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ZXING_AZTEC_DECODER_DECODER_H__
#define __ZXING_AZTEC_DECODER_DECODER_H__
#include <zxing/common/BitMatrix.h>
#include <zxing/common/Str.h>
#include <zxing/aztec/AztecDetectorResult.h>
namespace zxing {
class DecoderResult;
namespace aztec {
class Decoder : public Counted {
private:
enum Table {
UPPER,
LOWER,
MIXED,
DIGIT,
PUNCT,
BINARY
};
static Table getTable(char t);
static const char* getCharacter(Table table, int code);
int numCodewords_;
int codewordSize_;
Ref<AztecDetectorResult> ddata_;
int invertedBitCount_;
Ref<String> getEncodedData(Ref<BitArray> correctedBits);
Ref<BitArray> correctBits(Ref<BitArray> rawbits);
Ref<BitArray> extractBits(Ref<BitMatrix> matrix);
static Ref<BitMatrix> removeDashedLines(Ref<BitMatrix> matrix);
static int readCode(Ref<BitArray> rawbits, int startIndex, int length);
public:
Decoder();
Ref<DecoderResult> decode(Ref<AztecDetectorResult> detectorResult);
};
}
}
#endif

View File

@ -0,0 +1,92 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
/*
* Detector.h
* zxing
*
* Created by Lukas Stabe on 08/02/2012.
* Copyright 2012 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __ZXING_AZTEC_DETECTOR_DETECTOR_H__
#define __ZXING_AZTEC_DETECTOR_DETECTOR_H__
#include <vector>
#include <zxing/common/BitArray.h>
#include <zxing/ResultPoint.h>
#include <zxing/common/BitMatrix.h>
#include <zxing/DecodeHints.h>
#include <zxing/aztec/AztecDetectorResult.h>
namespace zxing {
namespace aztec {
class Point : public Counted {
private:
const int x;
const int y;
public:
Ref<ResultPoint> toResultPoint() {
return Ref<ResultPoint>(new ResultPoint(float(x), float(y)));
}
Point(int ax, int ay) : x(ax), y(ay) {}
int getX() const { return x; }
int getY() const { return y; }
};
class Detector : public Counted {
private:
Ref<BitMatrix> image_;
bool compact_;
int nbLayers_;
int nbDataBlocks_;
int nbCenterLayers_;
int shift_;
void extractParameters(std::vector<Ref<Point> > bullEyeCornerPoints);
ArrayRef< Ref<ResultPoint> > getMatrixCornerPoints(std::vector<Ref<Point> > bullEyeCornerPoints);
static void correctParameterData(Ref<BitArray> parameterData, bool compact);
std::vector<Ref<Point> > getBullEyeCornerPoints(Ref<Point> pCenter);
Ref<Point> getMatrixCenter();
Ref<BitMatrix> sampleGrid(Ref<BitMatrix> image,
Ref<ResultPoint> topLeft,
Ref<ResultPoint> bottomLeft,
Ref<ResultPoint> bottomRight,
Ref<ResultPoint> topRight);
void getParameters(Ref<BitArray> parameterData);
Ref<BitArray> sampleLine(Ref<Point> p1, Ref<Point> p2, int size);
bool isWhiteOrBlackRectangle(Ref<Point> p1,
Ref<Point> p2,
Ref<Point> p3,
Ref<Point> p4);
int getColor(Ref<Point> p1, Ref<Point> p2);
Ref<Point> getFirstDifferent(Ref<Point> init, bool color, int dx, int dy);
bool isValid(int x, int y);
static float distance(Ref<Point> a, Ref<Point> b);
public:
Detector(Ref<BitMatrix> image);
Ref<AztecDetectorResult> detect();
};
}
}
#endif

View File

@ -0,0 +1,170 @@
// -*- mode:c++; tab-width:2; indent-tabs-mode:nil; c-basic-offset:2 -*-
#ifndef __ARRAY_H__
#define __ARRAY_H__
/*
* Array.h
* zxing
*
* Copyright 2010 ZXing authors All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vector>
#include <zxing/common/Counted.h>
namespace zxing {
template<typename T> class Array : public Counted {
protected:
public:
std::vector<T> values_;
Array() {}
Array(int n) :
Counted(), values_(n, T()) {
}
Array(T const* ts, int n) :
Counted(), values_(ts, ts + n) {
}
Array(T const* ts, T const* te) :
Counted(), values_(ts, te) {
}
Array(T v, int n) :
Counted(), values_(n, v) {
}
Array(std::vector<T>& v) :
Counted(), values_(v) {
}
Array(Array<T>& other) :
Counted(), values_(other.values_) {
}
Array(Array<T>* other) :
Counted(), values_(other->values_) {
}
virtual ~Array() {
}
Array<T>& operator=(const Array<T>& other) {
values_ = other.values_;
return *this;
}
Array<T>& operator=(const std::vector<T>& array) {
values_ = array;
return *this;
}
T const& operator[](int i) const {
return values_[i];
}
T& operator[](int i) {
return values_[i];
}
int size() const {
return values_.size();
}
bool empty() const {
return values_.size() == 0;
}
std::vector<T> const& values() const {
return values_;
}
std::vector<T>& values() {
return values_;
}
};
template<typename T> class ArrayRef : public Counted {
private:
public:
Array<T>* array_;
ArrayRef() :
array_(0) {
}
explicit ArrayRef(int n) :
array_(0) {
reset(new Array<T>(n));
}
ArrayRef(T* ts, int n) :
array_(0) {
reset(new Array<T>(ts, n));
}
ArrayRef(Array<T>* a) :
array_(0) {
reset(a);
}
ArrayRef(const ArrayRef& other) :
Counted(), array_(0) {
reset(other.array_);
}
template<class Y>
ArrayRef(const ArrayRef<Y>& other) :
array_(0) {
reset(static_cast<const Array<T>*>(other.array_));
}
~ArrayRef() {
if (array_) {
array_->release();
}
array_ = 0;
}
T const& operator[](int i) const {
return (*array_)[i];
}
T& operator[](int i) {
return (*array_)[i];
}
void reset(Array<T>* a) {
if (a) {
a->retain();
}
if (array_) {
array_->release();
}
array_ = a;
}
void reset(const ArrayRef<T>& other) {
reset(other.array_);
}
ArrayRef<T>& operator=(const ArrayRef<T>& other) {
reset(other);
return *this;
}
ArrayRef<T>& operator=(Array<T>* a) {
reset(a);
return *this;
}
Array<T>& operator*() const {
return *array_;
}
Array<T>* operator->() const {
return array_;
}
operator bool() const {
return array_ != 0;
}
bool operator ! () const {
return array_ == 0;
}
};
} // namespace zxing
#endif // __ARRAY_H__

Some files were not shown because too many files have changed in this diff Show More