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!