ftylitak/qzxing

unable to decode Qr code or barcode via QZXingLive on Linux

Opened this issue · 8 comments

Hello to all,
I am developing a barcode reader with your library, I want to say that you have done a great job. In my project, the decoding part via an image works perfectly, so I decided to upgrade it with a live decoding. To start, I wanted to test the QZxinglive example on QT, but I can't detect any barcode. My operating system is ubuntu 18 with QT 5.15 and as camera a webcam. I would like to know if someone could help me to solve this problem?

I went through all the solved problems and noticed that it was handled on a branch with the name 86-Fix-QZXingFilter-linux, but even when I go to that branch and run it, I still have the same problem.

I would like to solve this; any help would be appreciated.

Thanks

Hello @Batiana226 , thank you for your kind words.

QZXingLive on master branch should be working out-of-the-box for Ubuntu. For the moment I run it on Ubuntu 21.04 with Qt 5.15.

To narrow down your issue:

  • Does the camera view starts normally?
  • Do you get any logs in the console output?
  • Does it start working if in main.qml, at QZXingFilter element, you change the tryHarder: false to tryHarder: true?

Even when I switch to the master branch, I still can't decode a barcode
The camera view starts, I get data on the output console and the tryharder is false

In most cases, this means that it has to do with the image decoding and the image format. It can be fixed.

I would suggest to add the following line:

qDebug() << "format:" << videoFrame.pixelFormat;

in line 278:

qzxing/src/QZXingFilter.cpp

Lines 274 to 280 in 2fd4dd6

const uint32_t *yuvPtr = reinterpret_cast<const uint32_t *>(data);
/// Create QImage from QVideoFrame.
QImage *image_ptr = ZXING_NULLPTR;
switch (videoFrame.pixelFormat) {
case QVideoFrame::Format_RGB32:

to print the image format. It would help a lot if you could send this information.

In my console i have this format: Format_YUYV

Greetings, today I have setup a machine with Ubuntu 18.04 and Qt 5.15.2. QZXingLive worked as expected without any need of fixing normally decoding Qr Codes.

I would recommend to download a clean copy of the QZXing code and retry. Keep in mind that this example, by default has enabled the decoding of Qr Code, EAN 13 and Code 39. Should you need any other barcode decoding, add the appropriate macro in the main.qml file :

enabledDecoders: QZXing.DecoderFormat_EAN_13 | QZXing.DecoderFormat_CODE_39 | QZXing.DecoderFormat_QR_CODE

If this still does not work, it would be helpful to enable frame saving to local disk form further examination. To do this, uncomment the following lines

qzxing/src/QZXingFilter.cpp

Lines 383 to 387 in 2fd4dd6

//qDebug() << "image.size()" << image_ptr->size();
//qDebug() << "image.format()" << image_ptr->format();
//qDebug() << "videoFrame.pixelFormat" << videoFrame.pixelFormat;
//const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i % 100) + ".png";
//qDebug() << "saving image" << i << "at:" << path << image_ptr->save(path);

Start the application, place a Qr Code in front of the camera and send here a representative image from the saved frames to see if there is something wrong.

EDIT: Minor Note: create the output folder before running the frame saving:

mkdir -p ~/Pictures/qrtest

Hello, the first suggestion did not work and the second one gives an image like this one. Do you think we can fix this?
test_75

Yes it can be fixed though since I am not yet able to reproduce it, it will take some time. It is related to the parsing of the frame data into a QImage. The responsible code is:

qzxing/src/QZXingFilter.cpp

Lines 341 to 360 in 2fd4dd6

case QVideoFrame::Format_YUYV:
image_ptr = new QImage(captureRect.targetWidth, captureRect.targetHeight, QImage::Format_Grayscale8);
pixel = image_ptr->bits();
for (int y = captureRect.startY; y < captureRect.endY; y++){
const uint32_t *row = &yuvPtr[y*(width/2)];
int end = captureRect.startX/2 + (captureRect.endX - captureRect.startX)/2;
for (int x = captureRect.startX/2; x < end; x++){
const uint8_t *pxl = reinterpret_cast<const uint8_t *>(&row[x]);
const uint8_t y0 = pxl[0];
const uint8_t u = pxl[1];
const uint8_t v = pxl[3];
const uint8_t y1 = pxl[2];
*pixel = yuvToGray2(y0, u, v);
++pixel;
*pixel = yuvToGray2(y1, u, v);
++pixel;
}
}

Sorry for the long delay, though I am a bit puzzled because the frames report that their format is YUYV though the above process can not decode it properly.

Could you provide the following information for your camera hopping that it would solve a part of the puzzle?

sudo apt install v4l-utils

v4l2-ctl v4l2-ctl --list-formats-ext