Image Detection

DMSDK provides detection of Digimarc Barcode (Product Packaging, Thermal Label, Print Media, and Audio) the most common 1D barcodes, and QR codes. There are several integration paths for applications, depending on a developer’s needs.

DMSDetectorViewController is a prebuilt view controller that can handle the needs of most basic applications. It’s the recommended starting point for applications with basic needs. This document covers how to integrate DMSDK with an existing view controller, or frameworks like AVFoundation, CoreGraphics, and ARKit.

Refer to the DMSDetectorViewController documentation for more information on adding a prebuilt view controller to your application.

Integrating with AVFoundation

DMSDK can integrate with a AVCaptureSession supplied by your application. This gives you full control of capture, including devices and preview layers, while DMSDK handles barcode detection. This functionality is provided via the DMSVideoCaptureReader/VideoCaptureReader class. It shares a similar design to Apple’s AVCaptureMetadataOutput class, and can be used side by side or as a replacement to Apple’s metadata detector.

For more information on how to configure AVCaptureSession, refer to Apple’s documentation or the AVCam sample.

Creating a video capture reader is simple. It must be initialized with the different types of symbols it should detect, and then added to a capture session. Digimarc Barcodes for Print (imageDigimarc) is a required option.

Swift
//captureSession is an existing capture session with a camera device
captureSession.beginConfiguration()

//Create the video capture reader
let videoCaptureReader = try VideoCaptureReader(symbologies: [ .imageDigimarc, .UPCA, .UPCE, .EAN13, .EAN8, .dataBar ])
//The video capture reader needs a delegate for returning results
//Queue is the dispatch queue results will be returned on
videoCaptureReader.setResultsDelegate(self, queue: DispatchQueue.main)

//Add the video capture reader to the capture session
captureSession.addOutput(videoCaptureReader.captureOutput)

//Commit the configuration
captureSession.commitConfiguration()

Obj-C
NSError *error = nil;
//captureSession is an existing capture session with a camera device
[captureSession beginConfiguration];

//Create the video capture reader
DMSSymbologies symbologies = DMSSymbologyImageDigimarc | DMSSymbologyUPCA | DMSSymbologyUPCE | DMSSymbologyEAN13 | DMSSymbologyEAN8 | DMSSymbologyDataBar;
DMSVideoCaptureReader *videoCaptureReader = [[DMSVideoCaptureReader alloc] initWithSymbologies: symbologies options:@{} error:&error];
//The video capture reader needs a delegate for returning results
//Queue is the dispatch queue results will be returned on
[videoCaptureReader setResultsDelegate:self queue:dispatch_get_main_queue()];

//Add the video capture reader to the capture session
[captureSession addOutput: videoCaptureReader];

//Commit the configuration
[captureSession commitConfiguration];

Implement the didOutputResult function in your delegate to receive results from the capture reader.

Swift
func videoCaptureReader(_ videoCaptureReader: VideoCaptureReader, didOutputResult result: ReaderResult)
{
     // check result.payloads or result.newPayloads for detected payloads
     if result.newPayloads.count > 0
     {
          //handle results here
         print("Result: \(result.newPayloads)")
     }
}
Obj-C
-(void)videoCaptureReader:(DMSVideoCaptureReader *)videoCaptureReader didOutputResult:(DMSReaderResult *)result {
     // check result.payloads or result.newPayloads for detected payloads
     if(result.newPayloads.count > 0) {
          //handle results here
          NSLog(@"Result: %@", result.newPayloads);
     }
}

Result is a DMSReaderResult/ReaderResult type that will contain zero or more Payloads. Each Payload represents a code that was found in a video frame. A result with zero Payloads means that no codes were detected in that video frame. A Reader Result will contain metadata and other information, regardless of if any Payloads were found.

DMSDK contains a variety of options for how to extract information from Payloads, such as the GTIN or UPCA value. Payloads can also be delivered to a Digimarc cloud service that can return relevant web content and more. For more information, see the “Payload Handling” section for more.

A DMSDemo sample application is also included that demonstrates a complete implementation of a Video Capture Reader.

Passing Images and Video Frames Directly To DMSDK

Some applications may want to manage video frames directly, or may not be using camera based detection at all. Frameworks like ARKit may even prevent direct access to a AVCaptureSession. For these types of scenarios, DMSDK provides DMSImageReader/ImageReader.

An Image Reader is a synchronous API that can perform detections in the following image formats:

  • CVPixelBuffer
  • CGImage
  • CMSampleBuffer

DMSDK prefers data in a 420YpCbCr 8 bit bi-planar format. These formats are defined by CoreVideo as:

  • kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange
  • kCVPixelFormatType_420YpCbCr8BiPlanarFullRange

If your data is not in a preferred format, DMSDK may attempt a conversion. For formats that cannot contain 420YpCbCr data, like CGImage, a conversion will always be performed. More optimal performance for non-420YpCbCr formats may be provided in future releases.

Configuring an Image Reader

An Image Reader needs a few extra details about how detections should be performed:

  • An Image Reader will need to know if processing every input image is necessary. For frames coming from sources like live video feeds, an Image Reader may skip images in order to preserve device responsiveness and battery live. Frame skipping should be disabled in applications where DMSDK should always return a result.
  • The Detection Type is used to configure how much effort an Image Reader should make looking for codes. A more robust Detection Type is more likely to return a result, or return results more consistantly, at the expense of CPU. Applications doing processing of live video feeds will likely desire a quicker and more efficient detection. A more expensive detection type might be desired by more analytical applications, or applications that are looking for consistant results on still images. If your application is doing live video processing, and you are unsure of which detection type to use, pick the default detection type.

The following code will create an Image Reader with the default detection type suitable for live video, but with frame skipping disabled.

Swift

self.imageReader = try ImageReader(symbologies: [ .imageDigimarc], detectionType: .default, allowFrameSkipping: false)
self.imageReader = [[DMSImageReader alloc] initWithSymbologies:DMSSymbologyImageDigimarc 
                                           detectionType:DMSImageDetectionTypeDefault 
                                           allowFrameSkipping:YES 
                                           options:@{} 
                                           error:&error];

Image detection can then be performed with one of the detection functions:

Swift

let imageReaderResult = try imageReader.process(pixelBuffer: myPixelBuffer)

Obj-C

NSError *error = nil;
[imageReader processPixelBuffer:myPixelBuffer error:&error];

The result is a ReaderResult type that behaves identically to what was described in the the AVFoundation Integration section.

Integrating With ARKit

ARKit can be configured to provide an DMSDK Image Reader with CVPixelBuffers. The result returned can then be mapped back into ARKit, enabling integration of Digimarc Barcode with ARKit content. See the ARDemo sample for more information.

  • Image readers synchronously process images and will return an array of payload classes that reflect the results found in the image. An image reader takes a CMSampleBuffer as input, which is the native media type of camera and video frames on iOS. The image will accept CMSampleBufferRefs that contain any image format, but the reader will work the most efficiently when the sample buffers contain an image in a YpCbCr8:420 Bi Planar format. AVFoundation can be configured to return CMSampleBufferRefs in this format directly.

    See more

    Declaration

    Objective-C

    
    @interface DMSImageReader : DMSReader

    Swift

    class ImageReader : Reader
  • The video capture reader interface is ideal for real time capture from an image source such as a camera. It vends a capture output that can be hooked to an existing AVFoundation capture tree. A video capture reader will automatically perform buffering and optimization necessary for a capture source. For situations in which a developer wants to have deeper control of how images are buffered or staged for detection, the synchronous image reader interface should be used.

    See more

    Declaration

    Objective-C

    
    @interface DMSVideoCaptureReader : DMSCaptureReader

    Swift

    class VideoCaptureReader : CaptureReader