2

I am trying to implement a barcode scanner that can handle dirty or slightly blurred barcodes. We have successfully implemented this in our Android app by applying filters to a camera input image to sharpen it, then using GoogleML to scan the resulting image. Unfortunately in iOS we are running into many problems.

After obtaining an image via the device camera, I am trying to run a sharpen filter on it like this:

if let inputImage = CIImage(image: image) {
    let sharpFilter = CIFilter(name: "CIUnsharpMask")!
    sharpFilter.setValue(inputImage, forKey: kCIInputImageKey)
    sharpFilter.setValue(2.0, forKey: "inputIntensity")
    sharpFilter.setValue(1.0, forKey: "inputRadius")
    let outputImage = sharpFilter.outputImage!
    let outputUIImage = UIImage(ciImage: outputImage)
    self.detectBarcodes(image: outputUIImage)
}

My detectBarcodes function takes the sharpened UIImage as a paramater. Inside that method, I am creating an instance of VisionImage. The VisionImage constructor is as follows:

VisionImage(image: UIImage)

Inside my detectBarcodes function, I am creating an instance of VisionImage like this:

func detectBarcodes(image: UIImage?) {

    guard let image = image else { return }
    let format = VisionBarcodeFormat.all
    let barcodeOptions = VisionBarcodeDetectorOptions(formats: format)
    let barcodeDetector = vision.barcodeDetector(options: barcodeOptions)
    let imageMetadata = VisionImageMetadata()
    imageMetadata.orientation = UIUtilities.visionImageOrientation(from: image.imageOrientation)

    let visionImage = VisionImage(image: image) // crashes here
    visionImage.metadata = imageMetadata

    //...

}

I have verified that the image being passed into the constructor is a valid UIImage, however, the call to the VisionImage constructor fails with the following log:

Terminating app due to uncaught exception 'FIRInvalidImage', reason: 'Invalid image. UIImage.CGImage must not be NULL.'

Oddly, this error only occurs if the image has been processed by the sharpening filter. If I pass the image to the detectBarcodes function before the sharpenFilter is run, then the VisionImage constructor succeeds, but the image is too blurred to get a scan.

Can anyone share any info on why this is happening? Or does anyone have any better suggestions for scanning a blurred barcode (when the customer won't pay for a dependable third part lib)?

Thanks!

Pheepster
  • 6,045
  • 6
  • 41
  • 75

1 Answers1

3

It seems that some code inside VisionImage wants to use the CGImage image data, however the documentation for the cgImage property states:

If the UIImage object was initialized using a CIImage object, the value of the property is NULL.

In your case, this is exactly what has happened, since your UIImage was created from a Core Image filter result.

You can use the techniques suggested in this question to create the required CGImage

Paulw11
  • 108,386
  • 14
  • 159
  • 186