QR Code Scanning: Zoom From a Distance

Have you had such an experience that you need to scan a QR code displayed on a screen in the front of a meeting room, but you sat in the back? You opened the barcode scanning app and aimed it at the code, but it just couldn’t read the code. Of course, it is better to make the QR code big enough for long-range scanning. But in many cases, the size is limited.

We generalized that there are two aspects to which we can pay attention to improve long-range barcode scanning:

  1. Zoom-in
  2. A higher resolution

We will discuss them in two articles. In this article, we will talk about how to optimize the performance of scanning QR codes at a distance via zoom-in.

An Android barcode scanning app using Dynamsoft Barcode Reader is made for illustration as shown below (In the image, the app finds the code, zooms in, and runs super resolution to achieve successful decoding).

Demo app

Getting started with Dynamsoft Barcode Reader

DOWNLOAD THE SDK WITH A 30-DAY LICENSE
REQUEST A 30-DAY LICENSE

We can zoom in for a close-up of QR codes. The code can become clearer and it will take a larger portion of the image so that there will be less interference. There are two kinds of zoom: optical zoom and digital zoom.

Digital Zoom

Digital zoom uses image processing algorithms to achieve the zoom-in effect. It is available on every modern mobile device. This is not lossless so the image will become blurry. Refocusing at the region of interest will be easier after digital zoom. So it is a bit different from cropping images already taken.

One of the top phone manufacturers boasts a 100x state-of-art digital zoom.

Zoom In to Better Find a Region of Interest

In CameraX, zoom can be controlled using the following code:

camera.getCameraControl().setLinearZoom((float) 80/100);

The linear zoom value ranges from 0f to 1.0f. LinearZoom 0f represents the minimum zoom while linearZoom 1.0f represents the maximum zoom.

Localize a Region of Interest and Then Auto Zoom

Barcode scanning can be divided to two steps: detection of barcode zones and decoding of these possible barcodes. Even though a code is not read successfully, we can use the detection result to perform digital zoom afterward.

Dynamsoft Barcode Reader can store intermediate results like the localization results of detected barcodes for such a purpose.

Set the runtime settings related to intermediate results:

PublicRuntimeSettings rs = dbr.getRuntimeSettings();
rs.intermediateResultTypes = EnumIntermediateResultType.IRT_TYPED_BARCODE_ZONE;
rs.intermediateResultSavingMode = EnumIntermediateResultSavingMode.IRSM_MEMORY;
rs.resultCoordinateType = EnumResultCoordinateType.RCT_PIXEL;
dbr.updateRuntimeSettings(rs);

Get the barcode localization result which has the highest confidence:

public static Point[] getResultsPointsWithHighestConfidence(IntermediateResult[] intermediateResults){
    for (IntermediateResult ir:intermediateResults){
        if (ir.resultType == EnumIntermediateResultType.IRT_TYPED_BARCODE_ZONE){
            int maxConfidence = 0;
            for (Object result:ir.results)
            {
                LocalizationResult lr = (LocalizationResult) result;
                maxConfidence = Math.max(lr.confidence,maxConfidence);
                Log.d("DBR", "confidence: "+lr.confidence);
            }
            Log.d("DBR", "max confidence: "+maxConfidence);
            for (Object result:ir.results)
            {
                LocalizationResult lr = (LocalizationResult) result;
                if (lr.confidence == maxConfidence && maxConfidence>80){
                    return lr.resultPoints;
                }
            }
        }
    }
    return null;
}

The zoom value can be calculated by dividing the image’s top/left position by the height/width of the barcode.

int minX;
minX=resultPoints[0].x;
for (Point point:resultPoints){
    minX=Math.min(point.x,minX);
}

double percent = Math.min((double) minX/bitmap.getWidth(),(double) minY/bitmap.getHeight());
int progress = (int) (percent*100);
int finalProgress = 100-progress;
camera.getCameraControl().setLinearZoom((float) finalProgress/100);

If a code is detected but not successfully decoded, the camera will zoom in for a better scanning success rate.

Before auto zoom:

before zoom

After auto zoom:

after zoom

Optical Zoom

Optical zoom gives a lossless result since it directly manipulates rays of light.

Some smartphones, like iPhone 7 Plus, have built-in optical zoom. The magnification factor supported by different devices can range from 2x to 10x.

iPhone

Image Source: https://osxdaily.com/2016/12/27/use-optical-zoom-lens-iphone-plus-camera/

But not all devices have the optical zoom feature. Although there are accessories which can bring optical zoom to phones without it built-in, it is not convenient.

Image Source: https://www.amazon.com/Youniker-Telephoto-Including-Aluminum-Telescope/dp/B06XPYKXNK/

It is not easy to utilize the phone’s optical zoom ability in our own applications since it may rely on the OEM’s SDK. A multi-camera API is introduced in Android 9, making it possible to use all the physical cameras, as phones with the optical zoom feature have multiple cameras with various focal lengths. We can achieve an optical zoom effect by switching to the long focal length camera. (See the official doc for details)

The phone camera technology is evolving. Some phone manufacturers have adopted liquid lens to achieve optical zoom and make macro shots with one single camera. Optical zoom may become more available in the future.

Next: resolution.

Source Code

https://github.com/xulihang/Faraway_Scan