mirror of
https://github.com/status-im/qzxing.git
synced 2025-01-25 18:29:18 +00:00
Reimplemented CameraImageWrapper to internally use GreyscaleLuminanceSource.
Enhanced QZXing, in case of decode failure, it now reties with "tryHarder" added decode hint. These changes have the following increment on success rates when decoding (numbers generated by test application): CODE_128: was 44/48, is 47/48 EAN_8: was 7/8, is 8/8 EAN_13: was 101/157, is 119/157 ITF: was 18/27, is 22/27 QR_CODE: was 135/178, is 137/178 UPC_A: was 80/167, is 99/167 UPC_E: was 40/55, is 47/55
This commit is contained in:
parent
5de6bf853f
commit
41ebf93087
@ -10,11 +10,14 @@ CameraImageWrapper::CameraImageWrapper() : LuminanceSource(0,0), image(NULL)
|
||||
CameraImageWrapper::CameraImageWrapper(const QImage &sourceImage) : LuminanceSource(sourceImage.width(), sourceImage.height())
|
||||
{
|
||||
image = grayScaleImage( &sourceImage );
|
||||
delegate = Ref<GreyscaleLuminanceSource>(
|
||||
new GreyscaleLuminanceSource(getMatrixP(),image->width(), image->height(),0, 0, image->width(), image->height()));
|
||||
}
|
||||
|
||||
CameraImageWrapper::CameraImageWrapper(CameraImageWrapper& otherInstance) : LuminanceSource(otherInstance.getWidth(), otherInstance.getHeight())
|
||||
{
|
||||
image = new QImage(otherInstance.getOriginalImage());
|
||||
delegate = otherInstance.getDelegate();
|
||||
}
|
||||
|
||||
CameraImageWrapper::~CameraImageWrapper()
|
||||
@ -25,7 +28,7 @@ CameraImageWrapper::~CameraImageWrapper()
|
||||
|
||||
CameraImageWrapper *CameraImageWrapper::Factory(const QImage &sourceImage, int maxWidth, int maxHeight, bool smoothTransformation)
|
||||
{
|
||||
if((maxWidth != 1 || maxHeight != 1) && (sourceImage.width() > maxWidth || sourceImage.height() > maxHeight))
|
||||
if((maxWidth != 1 && sourceImage.width() > maxWidth) || (maxHeight != 1 && sourceImage.height() > maxHeight))
|
||||
{
|
||||
QImage image;
|
||||
image = sourceImage.scaled(
|
||||
@ -39,33 +42,6 @@ CameraImageWrapper *CameraImageWrapper::Factory(const QImage &sourceImage, int m
|
||||
return new CameraImageWrapper(sourceImage);
|
||||
}
|
||||
|
||||
int CameraImageWrapper::getWidth() const
|
||||
{
|
||||
return image->width();
|
||||
}
|
||||
|
||||
int CameraImageWrapper::getHeight() const
|
||||
{
|
||||
return image->height();
|
||||
}
|
||||
|
||||
unsigned char CameraImageWrapper::getPixel(int x, int y) const
|
||||
{
|
||||
return image->pixel(x,y);
|
||||
}
|
||||
|
||||
unsigned char* CameraImageWrapper::copyMatrix() const
|
||||
{
|
||||
unsigned char* newMatrix = (unsigned char*)malloc(image->width() * image->height() * sizeof(unsigned char));
|
||||
|
||||
int cnt = 0;
|
||||
for(int i=0; i<image->width(); i++)
|
||||
for(int j=0; j<image->height(); j++)
|
||||
newMatrix[cnt++] = getPixel(i,j);
|
||||
|
||||
return newMatrix;
|
||||
}
|
||||
|
||||
QImage* CameraImageWrapper::grayScaleImage(const QImage *origin)
|
||||
{
|
||||
QImage *tmp = new QImage(origin->width(), origin->height(), QImage::Format_Grayscale8);
|
||||
@ -89,6 +65,62 @@ QImage CameraImageWrapper::getOriginalImage()
|
||||
}
|
||||
|
||||
ArrayRef<char> CameraImageWrapper::getRow(int y, ArrayRef<char> row) const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->getRow(y, row);
|
||||
else
|
||||
return getRowP(y, row);
|
||||
}
|
||||
|
||||
ArrayRef<char> CameraImageWrapper::getMatrix() const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->getMatrix();
|
||||
else
|
||||
return getMatrixP();
|
||||
}
|
||||
|
||||
bool CameraImageWrapper::isCropSupported() const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->isCropSupported();
|
||||
else
|
||||
return LuminanceSource::isCropSupported();
|
||||
}
|
||||
|
||||
Ref<LuminanceSource> CameraImageWrapper::crop(int left, int top, int width, int height) const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->crop(left, top, width, height);
|
||||
else
|
||||
return LuminanceSource::crop(left, top, width, height);
|
||||
}
|
||||
|
||||
bool CameraImageWrapper::isRotateSupported() const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->isRotateSupported();
|
||||
else
|
||||
return LuminanceSource::isRotateSupported();
|
||||
}
|
||||
|
||||
Ref<LuminanceSource> CameraImageWrapper::invert() const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->invert();
|
||||
else
|
||||
return LuminanceSource::invert();
|
||||
}
|
||||
|
||||
Ref<LuminanceSource> CameraImageWrapper::rotateCounterClockwise() const
|
||||
{
|
||||
if(delegate)
|
||||
return delegate->rotateCounterClockwise();
|
||||
else
|
||||
return LuminanceSource::rotateCounterClockwise();
|
||||
}
|
||||
|
||||
ArrayRef<char> CameraImageWrapper::getRowP(int y, ArrayRef<char> row) const
|
||||
{
|
||||
int width = getWidth();
|
||||
|
||||
@ -96,12 +128,12 @@ ArrayRef<char> CameraImageWrapper::getRow(int y, ArrayRef<char> row) const
|
||||
row.reset(ArrayRef<char>(width));
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
row[x] = getPixel(x,y);
|
||||
row[x] = image->pixel(x,y);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
ArrayRef<char> CameraImageWrapper::getMatrix() const
|
||||
ArrayRef<char> CameraImageWrapper::getMatrixP() const
|
||||
{
|
||||
int width = getWidth();
|
||||
int height = getHeight();
|
||||
@ -113,7 +145,7 @@ ArrayRef<char> CameraImageWrapper::getMatrix() const
|
||||
|
||||
for(int y=0; y<height; y++)
|
||||
{
|
||||
tmpRow = getRow(y, tmpRow);
|
||||
tmpRow = getRowP(y, tmpRow);
|
||||
#if __cplusplus > 199711L
|
||||
memcpy(m, tmpRow->values().data(), width);
|
||||
#else
|
||||
@ -125,6 +157,31 @@ ArrayRef<char> CameraImageWrapper::getMatrix() const
|
||||
return arr;
|
||||
}
|
||||
|
||||
//bool CameraImageWrapper::isCropSupported() const
|
||||
//{
|
||||
// return true;
|
||||
//}
|
||||
|
||||
//Ref<LuminanceSource> CameraImageWrapper::crop(int left, int top, int width, int height) const
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//bool CameraImageWrapper::isRotateSupported() const
|
||||
//{
|
||||
// return true;
|
||||
//}
|
||||
|
||||
//Ref<LuminanceSource> CameraImageWrapper::invert() const
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
//Ref<LuminanceSource> CameraImageWrapper::rotateCounterClockwise() const
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
QImage *CameraImageWrapper::sharpen(const QImage *origin)
|
||||
{
|
||||
QImage * newImage = new QImage(* origin);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <QImage>
|
||||
#include <QString>
|
||||
#include <zxing/zxing/LuminanceSource.h>
|
||||
#include <zxing/zxing/common/GreyscaleLuminanceSource.h>
|
||||
|
||||
using namespace zxing;
|
||||
|
||||
@ -17,23 +17,27 @@ public:
|
||||
|
||||
static CameraImageWrapper* Factory(const QImage& image, int maxWidth=-1, int maxHeight=-1, bool smoothTransformation=false);
|
||||
|
||||
int getWidth() const;
|
||||
int getHeight() const;
|
||||
|
||||
unsigned char getPixel(int x, int y) const;
|
||||
unsigned char* copyMatrix() const;
|
||||
|
||||
QImage* grayScaleImage(const QImage *origin);
|
||||
QImage getOriginalImage();
|
||||
Ref<GreyscaleLuminanceSource> getDelegate() { return delegate; }
|
||||
|
||||
// Callers take ownership of the returned memory and must call delete [] on it themselves.
|
||||
ArrayRef<char> getRow(int y, ArrayRef<char> row) const;
|
||||
ArrayRef<char> getMatrix() const;
|
||||
|
||||
bool isCropSupported() const;
|
||||
Ref<LuminanceSource> crop(int left, int top, int width, int height) const;
|
||||
bool isRotateSupported() const;
|
||||
Ref<LuminanceSource> invert() const;
|
||||
Ref<LuminanceSource> rotateCounterClockwise() const;
|
||||
|
||||
private:
|
||||
ArrayRef<char> getRowP(int y, ArrayRef<char> row) const;
|
||||
ArrayRef<char> getMatrixP() const;
|
||||
QImage* grayScaleImage(const QImage *origin);
|
||||
|
||||
QImage* sharpen(const QImage *origin);
|
||||
|
||||
QImage* image;
|
||||
Ref<GreyscaleLuminanceSource> delegate;
|
||||
};
|
||||
|
||||
#endif //CAMERAIMAGE_H
|
||||
|
@ -190,12 +190,13 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo
|
||||
}
|
||||
|
||||
CameraImageWrapper *ciw = NULL;
|
||||
try {
|
||||
|
||||
if ((maxWidth > 0) || (maxHeight > 0))
|
||||
ciw = CameraImageWrapper::Factory(image, maxWidth, maxHeight, smoothTransformation);
|
||||
else
|
||||
ciw = CameraImageWrapper::Factory(image, 999, 999, true);
|
||||
|
||||
try {
|
||||
Ref<LuminanceSource> imageRef(ciw);
|
||||
GlobalHistogramBinarizer *binz = new GlobalHistogramBinarizer(imageRef);
|
||||
|
||||
@ -204,7 +205,19 @@ QString QZXing::decodeImage(const QImage &image, int maxWidth, int maxHeight, bo
|
||||
|
||||
Ref<BinaryBitmap> ref(bb);
|
||||
|
||||
res = decoder->decode(ref, DecodeHints((int)enabledDecoders));
|
||||
DecodeHints hints((int)enabledDecoders);
|
||||
|
||||
bool hasSucceded = false;
|
||||
try {
|
||||
res = decoder->decode(ref, hints);
|
||||
hasSucceded = true;
|
||||
}catch(zxing::Exception &e){}
|
||||
|
||||
if(!hasSucceded)
|
||||
{
|
||||
hints.setTryHarder(true);
|
||||
res = decoder->decode(ref, hints);
|
||||
}
|
||||
|
||||
QString string = QString(res->getText()->getText().c_str());
|
||||
if (!string.isEmpty() && (string.length() > 0)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user