mirror of
https://github.com/status-im/qzxing.git
synced 2025-01-12 03:54:24 +00:00
refactoring in qzxing.cpp to remove uneeded references
This commit is contained in:
parent
3798e89fb6
commit
00d0e8d8d0
@ -157,45 +157,6 @@ ArrayRef<char> CameraImageWrapper::getMatrixP() const
|
|||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QImage *CameraImageWrapper::sharpen(const QImage *origin)
|
|
||||||
{
|
|
||||||
QImage * newImage = new QImage(* origin);
|
|
||||||
|
|
||||||
int kernel [3][3]= {{0,-1,0},
|
|
||||||
{-1,5,-1},
|
|
||||||
{0,-1,0}};
|
|
||||||
int kernelSize = 3;
|
|
||||||
int sumKernel = 1;
|
|
||||||
int r,g,b;
|
|
||||||
QColor color;
|
|
||||||
|
|
||||||
for(int x=kernelSize/2; x<newImage->width()-(kernelSize/2); x++){
|
|
||||||
for(int y=kernelSize/2; y<newImage->height()-(kernelSize/2); y++){
|
|
||||||
|
|
||||||
r = 0;
|
|
||||||
g = 0;
|
|
||||||
b = 0;
|
|
||||||
|
|
||||||
for(int i = -kernelSize/2; i<= kernelSize/2; i++){
|
|
||||||
for(int j = -kernelSize/2; j<= kernelSize/2; j++){
|
|
||||||
color = QColor(origin->pixel(x+i, y+j));
|
|
||||||
r += color.red()*kernel[kernelSize/2+i][kernelSize/2+j];
|
|
||||||
g += color.green()*kernel[kernelSize/2+i][kernelSize/2+j];
|
|
||||||
b += color.blue()*kernel[kernelSize/2+i][kernelSize/2+j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
r = qBound(0, r/sumKernel, 255);
|
|
||||||
g = qBound(0, g/sumKernel, 255);
|
|
||||||
b = qBound(0, b/sumKernel, 255);
|
|
||||||
|
|
||||||
newImage->setPixel(x,y, qRgb(r,g,b));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int CameraImageWrapper::gray(unsigned int r, unsigned int g, unsigned int b)
|
unsigned int CameraImageWrapper::gray(unsigned int r, unsigned int g, unsigned int b)
|
||||||
{
|
{
|
||||||
//values based on http://entropymine.com/imageworsener/grayscale/
|
//values based on http://entropymine.com/imageworsener/grayscale/
|
||||||
|
@ -34,8 +34,6 @@ private:
|
|||||||
ArrayRef<char> getMatrixP() const;
|
ArrayRef<char> getMatrixP() const;
|
||||||
QImage* grayScaleImage(const QImage *origin);
|
QImage* grayScaleImage(const QImage *origin);
|
||||||
|
|
||||||
QImage* sharpen(const QImage *origin);
|
|
||||||
|
|
||||||
unsigned int gray(unsigned int r, unsigned int g, unsigned int b);
|
unsigned int gray(unsigned int r, unsigned int g, unsigned int b);
|
||||||
|
|
||||||
QImage* image;
|
QImage* image;
|
||||||
|
@ -198,25 +198,21 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Ref<LuminanceSource> imageRef(ciw);
|
Ref<LuminanceSource> imageRef(ciw);
|
||||||
GlobalHistogramBinarizer *binz = new GlobalHistogramBinarizer(imageRef);
|
Ref<GlobalHistogramBinarizer> binz( new GlobalHistogramBinarizer(imageRef) );
|
||||||
|
Ref<BinaryBitmap> bb( new BinaryBitmap(binz) );
|
||||||
Ref<Binarizer> bz(binz);
|
|
||||||
BinaryBitmap *bb = new BinaryBitmap(bz);
|
|
||||||
|
|
||||||
Ref<BinaryBitmap> ref(bb);
|
|
||||||
|
|
||||||
DecodeHints hints((int)enabledDecoders);
|
DecodeHints hints((int)enabledDecoders);
|
||||||
|
|
||||||
bool hasSucceded = false;
|
bool hasSucceded = false;
|
||||||
try {
|
try {
|
||||||
res = decoder->decode(ref, hints);
|
res = decoder->decode(bb, hints);
|
||||||
hasSucceded = true;
|
hasSucceded = true;
|
||||||
}catch(zxing::Exception &e){}
|
}catch(zxing::Exception &e){}
|
||||||
|
|
||||||
if(!hasSucceded)
|
if(!hasSucceded)
|
||||||
{
|
{
|
||||||
hints.setTryHarder(true);
|
hints.setTryHarder(true);
|
||||||
res = decoder->decode(ref, hints);
|
res = decoder->decode(bb, hints);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString string = QString(res->getText()->getText().c_str());
|
QString string = QString(res->getText()->getText().c_str());
|
||||||
|
@ -22,49 +22,53 @@ using zxing::BitArray;
|
|||||||
using zxing::BitMatrix;
|
using zxing::BitMatrix;
|
||||||
using zxing::LuminanceSource;
|
using zxing::LuminanceSource;
|
||||||
using zxing::BinaryBitmap;
|
using zxing::BinaryBitmap;
|
||||||
|
|
||||||
// VC++
|
// VC++
|
||||||
using zxing::Binarizer;
|
using zxing::Binarizer;
|
||||||
|
|
||||||
BinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : binarizer_(binarizer) {
|
BinaryBitmap::BinaryBitmap(Ref<Binarizer> binarizer) : binarizer_(binarizer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryBitmap::~BinaryBitmap() {
|
BinaryBitmap::~BinaryBitmap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BitArray> BinaryBitmap::getBlackRow(int y, Ref<BitArray> row) {
|
Ref<BitArray> BinaryBitmap::getBlackRow(int y, Ref<BitArray> row) {
|
||||||
return binarizer_->getBlackRow(y, row);
|
return binarizer_->getBlackRow(y, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BitMatrix> BinaryBitmap::getBlackMatrix() {
|
Ref<BitMatrix> BinaryBitmap::getBlackMatrix() {
|
||||||
return binarizer_->getBlackMatrix();
|
return binarizer_->getBlackMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryBitmap::getWidth() const {
|
int BinaryBitmap::getWidth() const {
|
||||||
return getLuminanceSource()->getWidth();
|
return getLuminanceSource()->getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
int BinaryBitmap::getHeight() const {
|
int BinaryBitmap::getHeight() const {
|
||||||
return getLuminanceSource()->getHeight();
|
return getLuminanceSource()->getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<LuminanceSource> BinaryBitmap::getLuminanceSource() const {
|
Ref<LuminanceSource> BinaryBitmap::getLuminanceSource() const {
|
||||||
return binarizer_->getLuminanceSource();
|
return binarizer_->getLuminanceSource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool BinaryBitmap::isCropSupported() const {
|
bool BinaryBitmap::isCropSupported() const {
|
||||||
return getLuminanceSource()->isCropSupported();
|
return getLuminanceSource()->isCropSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BinaryBitmap> BinaryBitmap::crop(int left, int top, int width, int height) {
|
Ref<BinaryBitmap> BinaryBitmap::crop(int left, int top, int width, int height) {
|
||||||
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->crop(left, top, width, height))));
|
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->crop(left, top, width, height))));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinaryBitmap::isRotateSupported() const {
|
bool BinaryBitmap::isRotateSupported() const {
|
||||||
return getLuminanceSource()->isRotateSupported();
|
return getLuminanceSource()->isRotateSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BinaryBitmap> BinaryBitmap::rotateCounterClockwise() {
|
Ref<BinaryBitmap> BinaryBitmap::rotateCounterClockwise() {
|
||||||
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise())));
|
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise())));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<zxing::BinaryBitmap> BinaryBitmap::rotateCounterClockwise45()
|
||||||
|
{
|
||||||
|
return Ref<BinaryBitmap> (new BinaryBitmap(binarizer_->createBinarizer(getLuminanceSource()->rotateCounterClockwise45())));
|
||||||
}
|
}
|
||||||
|
@ -45,10 +45,10 @@ namespace zxing {
|
|||||||
|
|
||||||
bool isRotateSupported() const;
|
bool isRotateSupported() const;
|
||||||
Ref<BinaryBitmap> rotateCounterClockwise();
|
Ref<BinaryBitmap> rotateCounterClockwise();
|
||||||
|
Ref<BinaryBitmap> rotateCounterClockwise45();
|
||||||
|
|
||||||
bool isCropSupported() const;
|
bool isCropSupported() const;
|
||||||
Ref<BinaryBitmap> crop(int left, int top, int width, int height);
|
Ref<BinaryBitmap> crop(int left, int top, int width, int height);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,12 @@ bool LuminanceSource::isRotateSupported() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ref<LuminanceSource> LuminanceSource::rotateCounterClockwise() const {
|
Ref<LuminanceSource> LuminanceSource::rotateCounterClockwise() const {
|
||||||
throw IllegalArgumentException("This luminance source does not support rotation.");
|
throw IllegalArgumentException("This luminance source does not support rotation.");
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<zxing::LuminanceSource> LuminanceSource::rotateCounterClockwise45() const
|
||||||
|
{
|
||||||
|
throw IllegalArgumentException("This luminance source does not support rotation 45.");
|
||||||
}
|
}
|
||||||
|
|
||||||
LuminanceSource::operator std::string() const {
|
LuminanceSource::operator std::string() const {
|
||||||
|
@ -51,6 +51,8 @@ class LuminanceSource : public Counted {
|
|||||||
|
|
||||||
virtual Ref<LuminanceSource> rotateCounterClockwise() const;
|
virtual Ref<LuminanceSource> rotateCounterClockwise() const;
|
||||||
|
|
||||||
|
virtual Ref<LuminanceSource> rotateCounterClockwise45() const;
|
||||||
|
|
||||||
operator std::string () const;
|
operator std::string () const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -33,180 +33,181 @@ using zxing::BitMatrix;
|
|||||||
using zxing::LuminanceSource;
|
using zxing::LuminanceSource;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const int LUMINANCE_BITS = 5;
|
const int LUMINANCE_BITS = 5;
|
||||||
const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
|
const int LUMINANCE_SHIFT = 8 - LUMINANCE_BITS;
|
||||||
const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
|
const int LUMINANCE_BUCKETS = 1 << LUMINANCE_BITS;
|
||||||
const ArrayRef<char> EMPTY (0);
|
const ArrayRef<char> EMPTY (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalHistogramBinarizer::GlobalHistogramBinarizer(Ref<LuminanceSource> source)
|
GlobalHistogramBinarizer::GlobalHistogramBinarizer(Ref<LuminanceSource> source)
|
||||||
: Binarizer(source), luminances(EMPTY), buckets(LUMINANCE_BUCKETS) {}
|
: Binarizer(source), luminances(EMPTY), buckets(LUMINANCE_BUCKETS) {}
|
||||||
|
|
||||||
GlobalHistogramBinarizer::~GlobalHistogramBinarizer() {}
|
GlobalHistogramBinarizer::~GlobalHistogramBinarizer() {}
|
||||||
|
|
||||||
void GlobalHistogramBinarizer::initArrays(int luminanceSize) {
|
void GlobalHistogramBinarizer::initArrays(int luminanceSize) {
|
||||||
if (luminances->size() < luminanceSize) {
|
if (luminances->size() < luminanceSize) {
|
||||||
luminances = ArrayRef<char>(luminanceSize);
|
luminances = ArrayRef<char>(luminanceSize);
|
||||||
}
|
}
|
||||||
for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
|
// for (int x = 0; x < LUMINANCE_BUCKETS; x++) {
|
||||||
buckets[x] = 0;
|
// buckets[x] = 0;
|
||||||
}
|
// }
|
||||||
|
memset(&buckets[0], 0, sizeof(int) * LUMINANCE_BUCKETS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<BitArray> GlobalHistogramBinarizer::getBlackRow(int y, Ref<BitArray> row) {
|
Ref<BitArray> GlobalHistogramBinarizer::getBlackRow(int y, Ref<BitArray> row) {
|
||||||
// std::cerr << "gbr " << y << std::endl;
|
// std::cerr << "gbr " << y << std::endl;
|
||||||
LuminanceSource& source = *getLuminanceSource();
|
LuminanceSource& source = *getLuminanceSource();
|
||||||
int width = source.getWidth();
|
int width = source.getWidth();
|
||||||
if (row == NULL || static_cast<int>(row->getSize()) < width) {
|
if (row == NULL || static_cast<int>(row->getSize()) < width) {
|
||||||
row = new BitArray(width);
|
row = new BitArray(width);
|
||||||
} else {
|
} else {
|
||||||
row->clear();
|
row->clear();
|
||||||
}
|
|
||||||
|
|
||||||
initArrays(width);
|
|
||||||
ArrayRef<char> localLuminances = source.getRow(y, luminances);
|
|
||||||
if (false) {
|
|
||||||
std::cerr << "gbr " << y << " r ";
|
|
||||||
for(int i=0, e=localLuminances->size(); i < e; ++i) {
|
|
||||||
std::cerr << 0+localLuminances[i] << " ";
|
|
||||||
}
|
}
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
ArrayRef<int> localBuckets = buckets;
|
|
||||||
for (int x = 0; x < width; x++) {
|
|
||||||
int pixel = localLuminances[x] & 0xff;
|
|
||||||
localBuckets[pixel >> LUMINANCE_SHIFT]++;
|
|
||||||
}
|
|
||||||
int blackPoint = estimateBlackPoint(localBuckets);
|
|
||||||
// std::cerr << "gbr bp " << y << " " << blackPoint << std::endl;
|
|
||||||
|
|
||||||
int left = localLuminances[0] & 0xff;
|
initArrays(width);
|
||||||
int center = localLuminances[1] & 0xff;
|
ArrayRef<char> localLuminances = source.getRow(y, luminances);
|
||||||
for (int x = 1; x < width - 1; x++) {
|
if (false) {
|
||||||
int right = localLuminances[x + 1] & 0xff;
|
std::cerr << "gbr " << y << " r ";
|
||||||
// A simple -1 4 -1 box filter with a weight of 2.
|
for(int i=0, e=localLuminances->size(); i < e; ++i) {
|
||||||
int luminance = ((center << 2) - left - right) >> 1;
|
std::cerr << 0+localLuminances[i] << " ";
|
||||||
if (luminance < blackPoint) {
|
}
|
||||||
row->set(x);
|
std::cerr << std::endl;
|
||||||
}
|
}
|
||||||
left = center;
|
ArrayRef<int> localBuckets = buckets;
|
||||||
center = right;
|
|
||||||
}
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ref<BitMatrix> GlobalHistogramBinarizer::getBlackMatrix() {
|
|
||||||
LuminanceSource& source = *getLuminanceSource();
|
|
||||||
int width = source.getWidth();
|
|
||||||
int height = source.getHeight();
|
|
||||||
Ref<BitMatrix> matrix(new BitMatrix(width, height));
|
|
||||||
|
|
||||||
// Quickly calculates the histogram by sampling four rows from the image.
|
|
||||||
// This proved to be more robust on the blackbox tests than sampling a
|
|
||||||
// diagonal as we used to do.
|
|
||||||
initArrays(width);
|
|
||||||
ArrayRef<int> localBuckets = buckets;
|
|
||||||
for (int y = 1; y < 5; y++) {
|
|
||||||
int row = height * y / 5;
|
|
||||||
ArrayRef<char> localLuminances = source.getRow(row, luminances);
|
|
||||||
int right = (width << 2) / 5;
|
|
||||||
for (int x = width / 5; x < right; x++) {
|
|
||||||
int pixel = localLuminances[x] & 0xff;
|
|
||||||
localBuckets[pixel >> LUMINANCE_SHIFT]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int blackPoint = estimateBlackPoint(localBuckets);
|
|
||||||
|
|
||||||
ArrayRef<char> localLuminances = source.getMatrix();
|
|
||||||
for (int y = 0; y < height; y++) {
|
|
||||||
int offset = y * width;
|
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
int pixel = localLuminances[offset + x] & 0xff;
|
int pixel = localLuminances[x] & 0xff;
|
||||||
if (pixel < blackPoint) {
|
localBuckets[pixel >> LUMINANCE_SHIFT]++;
|
||||||
matrix->set(x, y);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
int blackPoint = estimateBlackPoint(localBuckets);
|
||||||
|
// std::cerr << "gbr bp " << y << " " << blackPoint << std::endl;
|
||||||
return matrix;
|
|
||||||
|
int left = localLuminances[0] & 0xff;
|
||||||
|
int center = localLuminances[1] & 0xff;
|
||||||
|
for (int x = 1; x < width - 1; x++) {
|
||||||
|
int right = localLuminances[x + 1] & 0xff;
|
||||||
|
// A simple -1 4 -1 box filter with a weight of 2.
|
||||||
|
int luminance = ((center << 2) - left - right) >> 1;
|
||||||
|
if (luminance < blackPoint) {
|
||||||
|
row->set(x);
|
||||||
|
}
|
||||||
|
left = center;
|
||||||
|
center = right;
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ref<BitMatrix> GlobalHistogramBinarizer::getBlackMatrix() {
|
||||||
|
LuminanceSource& source = *getLuminanceSource();
|
||||||
|
int width = source.getWidth();
|
||||||
|
int height = source.getHeight();
|
||||||
|
Ref<BitMatrix> matrix(new BitMatrix(width, height));
|
||||||
|
|
||||||
|
// Quickly calculates the histogram by sampling four rows from the image.
|
||||||
|
// This proved to be more robust on the blackbox tests than sampling a
|
||||||
|
// diagonal as we used to do.
|
||||||
|
initArrays(width);
|
||||||
|
ArrayRef<int> localBuckets = buckets;
|
||||||
|
for (int y = 1; y < 5; y++) {
|
||||||
|
int row = height * y / 5;
|
||||||
|
ArrayRef<char> localLuminances = source.getRow(row, luminances);
|
||||||
|
int right = (width << 2) / 5;
|
||||||
|
for (int x = width / 5; x < right; x++) {
|
||||||
|
int pixel = localLuminances[x] & 0xff;
|
||||||
|
localBuckets[pixel >> LUMINANCE_SHIFT]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int blackPoint = estimateBlackPoint(localBuckets);
|
||||||
|
|
||||||
|
ArrayRef<char> localLuminances = source.getMatrix();
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
int offset = y * width;
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
int pixel = localLuminances[offset + x] & 0xff;
|
||||||
|
if (pixel < blackPoint) {
|
||||||
|
matrix->set(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return matrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
int GlobalHistogramBinarizer::estimateBlackPoint(ArrayRef<int> const& buckets) {
|
int GlobalHistogramBinarizer::estimateBlackPoint(ArrayRef<int> const& buckets) {
|
||||||
// Find tallest peak in histogram
|
// Find tallest peak in histogram
|
||||||
int numBuckets = buckets->size();
|
int numBuckets = buckets->size();
|
||||||
int maxBucketCount = 0;
|
int maxBucketCount = 0;
|
||||||
int firstPeak = 0;
|
int firstPeak = 0;
|
||||||
int firstPeakSize = 0;
|
int firstPeakSize = 0;
|
||||||
if (false) {
|
if (false) {
|
||||||
|
for (int x = 0; x < numBuckets; x++) {
|
||||||
|
cerr << buckets[x] << " ";
|
||||||
|
}
|
||||||
|
cerr << endl;
|
||||||
|
}
|
||||||
for (int x = 0; x < numBuckets; x++) {
|
for (int x = 0; x < numBuckets; x++) {
|
||||||
cerr << buckets[x] << " ";
|
if (buckets[x] > firstPeakSize) {
|
||||||
|
firstPeak = x;
|
||||||
|
firstPeakSize = buckets[x];
|
||||||
|
}
|
||||||
|
if (buckets[x] > maxBucketCount) {
|
||||||
|
maxBucketCount = buckets[x];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cerr << endl;
|
|
||||||
}
|
// Find second-tallest peak -- well, another peak that is tall and not
|
||||||
for (int x = 0; x < numBuckets; x++) {
|
// so close to the first one
|
||||||
if (buckets[x] > firstPeakSize) {
|
int secondPeak = 0;
|
||||||
firstPeak = x;
|
int secondPeakScore = 0;
|
||||||
firstPeakSize = buckets[x];
|
for (int x = 0; x < numBuckets; x++) {
|
||||||
|
int distanceToBiggest = x - firstPeak;
|
||||||
|
// Encourage more distant second peaks by multiplying by square of distance
|
||||||
|
int score = buckets[x] * distanceToBiggest * distanceToBiggest;
|
||||||
|
if (score > secondPeakScore) {
|
||||||
|
secondPeak = x;
|
||||||
|
secondPeakScore = score;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (buckets[x] > maxBucketCount) {
|
|
||||||
maxBucketCount = buckets[x];
|
if (firstPeak > secondPeak) {
|
||||||
|
int temp = firstPeak;
|
||||||
|
firstPeak = secondPeak;
|
||||||
|
secondPeak = temp;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Find second-tallest peak -- well, another peak that is tall and not
|
// Kind of arbitrary; if the two peaks are very close, then we figure there is
|
||||||
// so close to the first one
|
// so little dynamic range in the image, that discriminating black and white
|
||||||
int secondPeak = 0;
|
// is too error-prone.
|
||||||
int secondPeakScore = 0;
|
// Decoding the image/line is either pointless, or may in some cases lead to
|
||||||
for (int x = 0; x < numBuckets; x++) {
|
// a false positive for 1D formats, which are relatively lenient.
|
||||||
int distanceToBiggest = x - firstPeak;
|
// We arbitrarily say "close" is
|
||||||
// Encourage more distant second peaks by multiplying by square of distance
|
// "<= 1/16 of the total histogram buckets apart"
|
||||||
int score = buckets[x] * distanceToBiggest * distanceToBiggest;
|
// std::cerr << "! " << secondPeak << " " << firstPeak << " " << numBuckets << std::endl;
|
||||||
if (score > secondPeakScore) {
|
if (secondPeak - firstPeak <= numBuckets >> 4) {
|
||||||
secondPeak = x;
|
throw NotFoundException();
|
||||||
secondPeakScore = score;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (firstPeak > secondPeak) {
|
// Find a valley between them that is low and closer to the white peak
|
||||||
int temp = firstPeak;
|
int bestValley = secondPeak - 1;
|
||||||
firstPeak = secondPeak;
|
int bestValleyScore = -1;
|
||||||
secondPeak = temp;
|
for (int x = secondPeak - 1; x > firstPeak; x--) {
|
||||||
}
|
int fromFirst = x - firstPeak;
|
||||||
|
// Favor a "valley" that is not too close to either peak -- especially not
|
||||||
// Kind of arbitrary; if the two peaks are very close, then we figure there is
|
// the black peak -- and that has a low value of course
|
||||||
// so little dynamic range in the image, that discriminating black and white
|
int score = fromFirst * fromFirst * (secondPeak - x) *
|
||||||
// is too error-prone.
|
(maxBucketCount - buckets[x]);
|
||||||
// Decoding the image/line is either pointless, or may in some cases lead to
|
if (score > bestValleyScore) {
|
||||||
// a false positive for 1D formats, which are relatively lenient.
|
bestValley = x;
|
||||||
// We arbitrarily say "close" is
|
bestValleyScore = score;
|
||||||
// "<= 1/16 of the total histogram buckets apart"
|
}
|
||||||
// std::cerr << "! " << secondPeak << " " << firstPeak << " " << numBuckets << std::endl;
|
|
||||||
if (secondPeak - firstPeak <= numBuckets >> 4) {
|
|
||||||
throw NotFoundException();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find a valley between them that is low and closer to the white peak
|
|
||||||
int bestValley = secondPeak - 1;
|
|
||||||
int bestValleyScore = -1;
|
|
||||||
for (int x = secondPeak - 1; x > firstPeak; x--) {
|
|
||||||
int fromFirst = x - firstPeak;
|
|
||||||
// Favor a "valley" that is not too close to either peak -- especially not
|
|
||||||
// the black peak -- and that has a low value of course
|
|
||||||
int score = fromFirst * fromFirst * (secondPeak - x) *
|
|
||||||
(maxBucketCount - buckets[x]);
|
|
||||||
if (score > bestValleyScore) {
|
|
||||||
bestValley = x;
|
|
||||||
bestValleyScore = score;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// std::cerr << "bps " << (bestValley << LUMINANCE_SHIFT) << std::endl;
|
// std::cerr << "bps " << (bestValley << LUMINANCE_SHIFT) << std::endl;
|
||||||
return bestValley << LUMINANCE_SHIFT;
|
return bestValley << LUMINANCE_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Binarizer> GlobalHistogramBinarizer::createBinarizer(Ref<LuminanceSource> source) {
|
Ref<Binarizer> GlobalHistogramBinarizer::createBinarizer(Ref<LuminanceSource> source) {
|
||||||
return Ref<Binarizer> (new GlobalHistogramBinarizer(source));
|
return Ref<Binarizer> (new GlobalHistogramBinarizer(source));
|
||||||
}
|
}
|
||||||
|
@ -107,9 +107,7 @@ bool FinderPatternFinder::foundPatternCross(int* stateCount) {
|
|||||||
float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal) {
|
float FinderPatternFinder::crossCheckVertical(size_t startI, size_t centerJ, int maxCount, int originalStateCountTotal) {
|
||||||
|
|
||||||
int maxI = image_->getHeight();
|
int maxI = image_->getHeight();
|
||||||
int stateCount[5] = {0};
|
int *stateCount = getCrossCheckStateCount();
|
||||||
// for (int i = 0; i < 5; i++)
|
|
||||||
// stateCount[i] = 0;
|
|
||||||
|
|
||||||
|
|
||||||
// Start counting up from center
|
// Start counting up from center
|
||||||
@ -175,9 +173,7 @@ float FinderPatternFinder::crossCheckHorizontal(size_t startJ, size_t centerI, i
|
|||||||
int originalStateCountTotal) {
|
int originalStateCountTotal) {
|
||||||
|
|
||||||
int maxJ = image_->getWidth();
|
int maxJ = image_->getWidth();
|
||||||
int stateCount[5] = {0};
|
int *stateCount = getCrossCheckStateCount();
|
||||||
// for (int i = 0; i < 5; i++)
|
|
||||||
// stateCount[i] = 0;
|
|
||||||
|
|
||||||
int j = startJ;
|
int j = startJ;
|
||||||
while (j >= 0 && image_->get(j, centerI)) {
|
while (j >= 0 && image_->get(j, centerI)) {
|
||||||
@ -312,7 +308,7 @@ bool FinderPatternFinder::haveMultiplyConfirmedCenters() {
|
|||||||
// and that we need to keep looking. We detect this by asking if the estimated module sizes
|
// and that we need to keep looking. We detect this by asking if the estimated module sizes
|
||||||
// vary too much. We arbitrarily say that when the total deviation from average exceeds
|
// vary too much. We arbitrarily say that when the total deviation from average exceeds
|
||||||
// 5% of the total module size estimates, it's too much.
|
// 5% of the total module size estimates, it's too much.
|
||||||
float average = totalModuleSize / max;
|
float average = totalModuleSize / (float)max;
|
||||||
float totalDeviation = 0.0f;
|
float totalDeviation = 0.0f;
|
||||||
for (size_t i = 0; i < max; i++) {
|
for (size_t i = 0; i < max; i++) {
|
||||||
Ref<FinderPattern> pattern = possibleCenters_[i];
|
Ref<FinderPattern> pattern = possibleCenters_[i];
|
||||||
@ -536,8 +532,17 @@ Ref<FinderPatternInfo> FinderPatternFinder::find(DecodeHints const& hints) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Ref<FinderPattern> > patternInfo = selectBestPatterns();
|
vector< Ref <FinderPattern> > patternInfo = selectBestPatterns();
|
||||||
patternInfo = orderBestPatterns(patternInfo);
|
vector< Ref <ResultPoint> > patternInfoResPoints;
|
||||||
|
|
||||||
|
for(size_t i=0; i<patternInfo.size(); i++)
|
||||||
|
patternInfoResPoints.push_back(Ref<ResultPoint>(patternInfo[i]));
|
||||||
|
|
||||||
|
ResultPoint::orderBestPatterns(patternInfoResPoints);
|
||||||
|
|
||||||
|
patternInfo.clear();
|
||||||
|
for(size_t i=0; i<patternInfoResPoints.size(); i++)
|
||||||
|
patternInfo.push_back(Ref<FinderPattern>(static_cast<FinderPattern*>( &*patternInfoResPoints[i] )));
|
||||||
|
|
||||||
Ref<FinderPatternInfo> result(new FinderPatternInfo(patternInfo));
|
Ref<FinderPatternInfo> result(new FinderPatternInfo(patternInfo));
|
||||||
return result;
|
return result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user