5

So, I have to scan different barcodes with various colours. For example, a yellow barcode on black background or yellow barcode on white background.

I don't have any issues with them being recognized by traditional linear and CCD barcode scanners. I have tried using Apple Vision framework but it doesn't work on them. They work perfectly fine on black barcodes with white background.

My barcodes are all Code 128 so I use this code for it:

var barcodeObservations: [String : VNBarcodeObservation] = [:]

for barcode in barcodes {

    if let detectedBarcode = barcode as? VNBarcodeObservation {

        if detectedBarcode.symbology == .code128 {
            barcodeObservations[detectedBarcode.payloadStringValue!] = detectedBarcode
        }
    }
}

And in 'captureOutput' function under AVCaptureVideoDataOutputSampleBufferDelegate, I use this to filter my live feed as black and white which helps in the recognition of the golden barcode on silver background (The first image):

let context = CIContext(options: nil)

let currentFilter = CIFilter(name: "CIPhotoEffectMono")
currentFilter!.setValue(CIImage(cvImageBuffer: pixelBuffer), forKey: kCIInputImageKey)
let output = currentFilter!.outputImage!

context.render(output, to: pixelBuffer)

How can I make the Vision Framework detect barcodes with invert colors?

The 'CIColorInvert' filter doesn't work.

Edit: These are the barcodes:

enter image description here

enter image description here

curiously77
  • 225
  • 1
  • 4
  • 24
  • 3
    Can you add an image to your question with a sample barcode thaTyiu can't detect – Paulw11 Mar 13 '20 at 05:13
  • 1
    @curiously77 here you can mentioned like `My barcodes are all Code 128 so I use this code for it` - so `to accept barcodes of different colours` means I think you need to use all supportedSymbologies - https://developer.apple.com/documentation/vision/vndetectbarcodesrequest/2879281-supportedsymbologies – Ram Mar 17 '20 at 08:35

1 Answers1

5

Theory

By default, Apple Vision, CoreML, ARKit and RealityKit frameworks are designed to detect barcodes that must be seen through a camera as a high-contrast black-and-white images (with a predictable weights for channels: r=30%, g=59%, b=11%). In your case a yellow barcode on a white background has the lowest contrast, so no one real barcode scanner can read it, including rgb camera feed for Vision.

Let's see what Best and Worst Colors for Barcode Labels article tells us:

One reason why barcodes can be hard to scan is color, or more specifically, the lack of contrast in colors. If there isn’t enough contrast between the background and bar colors, barcode scanners will have a hard time reading it.


Avoid the following colours' combination because they are in low-contrast greyscale spectre:

enter image description here


Practical Solution

(only if barcode was printed on planar surface with diffuse paint)

Although if you wanna successfully detect a chromatic barcode on a chromatic background using Vision, you definitely need to apply a grayscale filter to color CVPixelBuffer stream before Vision starts recognizing barcodes. For this use AVFoundation and CoreImage frameworks.

Please read these three posts to find out how you can do it:

P.S.

Metallic Paints

Barcodes printed with metallic paints (gold, silver, copper, etc) are the worst instances for barcode readers. This is due to the fact that metallic paint catches reflections and it has environment lights' speculars. So barcodes printed with metallic paints are barely read.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 1
    I will definitely give it a try. – curiously77 Mar 18 '20 at 12:52
  • Unfortunately, it doesn't work. I converted the image to grayscale but only the golden barcode is being detected once out of ten attempts. – curiously77 Mar 20 '20 at 16:34
  • Sorry, what do you mean saying `golden` if you converted it into grayscale? And have you set a contrast for grayscale to maximum? – Andy Jazz Mar 20 '20 at 17:13
  • 1
    If you look at the barcodes uploaded by me in my question, the barcode (golden coloured) with silver background was recognized. – curiously77 Mar 20 '20 at 18:12
  • 1
    I see. Your images show the worst possible situation – metallic paint on cylindrical surface. IMHO, you can't improve the reading process for this type of barcode. The situation is complicated by the fact that the transparent film glares! – Andy Jazz Mar 20 '20 at 18:18
  • 1
    I know. Several apps on both the App Store and Play Store were able to recognize the barcodes perfectly in different lighting environments. Hence, I thought I could develop a solution based on Vision framework or Core ML. – curiously77 Mar 20 '20 at 18:36
  • 1
    You can improve a reading process for a iOS Vision app only if your barcode is printed with diffuse paint (non-metallic one), if it's printed on a planar surface (not rough, not cylindrical), and if it's not covered with glare film. Although barcode scanners (not phones) could read such barcodes... – Andy Jazz Mar 20 '20 at 18:36