Skip to main content

Filters and Image Processing | Android Document Scanner

Image Processing And Filters

The ImageProcessor class applies a chain of operations to the input image. The operations are applied according to the given order and applied step-by-step.

To make use of the ImageProcessor features for Page objects, use a PageProcessor instance. An example of this approach can be found here

Instance of ImageProcessor can be created with a Bitmap image, JPEG byte array, NV21 byte array or image path as an original image input.
The operations are applied according to the given order and applied step-by-step.

The resultant image can be obtained in a few ways:

  • as a Bitmap using the ImageProcessor#processedBitmap(): Bitmap method.
  • as a JPEG byte array using the ImageProcessor#encodedProcessedImage(extension: String): ByteArray method.
  • the resultant image can be saved to a file using the ImageProcessor#saveProcessedImage(path: String) method.

Supported types of operations

  • ImageProcessor#crop(polygon: List<PointF>) - crop the image according to a given polygon
  • ImageProcessor#rotate(rotation: ImageProcessor.ImageRotation) - rotate the image by a given type. ROTATION_NONE, ROTATION_90_CLOCKWISE, ROTATION_180, ROTATION_90_COUNTERCLOCKWISE are supported
  • ImageProcessor#rotate(degrees: Int) - rotate the image by a given angle. 0, 90, 180, 270 are supported
  • ImageProcessor#resize(maxSize: Int) - resize the image with a given max size
  • ImageProcessor#applyFilter(filter: ParametricFilter) - apply the given 'ParametricFilter'

Cropping

To crop the document image from the original image based on a detected polygon, use one of the detect(..) methods of the ContourDetector and then apply the Crop operation of ImageProcessor:

val result = contourDetector.detect(originalBitmap)
val polygonToCrop = result.polygonF
val imageProcessor = ImageProcessor(originalBitmap)
imageProcessor.crop(polygonToCrop)
val documentBitmap = imageProcessor.processedBitmap()

Note that the originalBitmap image will not be modified.

The resultant documentBitmap is a cropped document image.

Rotation

To rotate the document image apply the Rotation operation of ImageProcessor:

val rotation = ImageProcessor.ImageRotation.ROTATION_90_CLOCKWISE
val documentBitmap = ImageProcessor(originalBitmap).rotate(rotation).processedBitmap()

The parameters are:

  • originalBitmap - The original Bitmap image as the input to process the document image from. This input image will not be modified.
  • rotation - The rotation type to apply. ROTATION_NONE, ROTATION_90_CLOCKWISE, ROTATION_180, ROTATION_90_COUNTERCLOCKWISE are supported.

The resultant documentBitmap is a rotated document image.

Resize

To resize the document image use the Resize operation of ImageProcessor:

val documentBitmap = ImageProcessor(originalBitmap).resize(maxSize).processedBitmap()

The parameters are:

  • originalBitmap - The original Bitmap image as the input to process the document image from. This input image will not be modified.
  • maxSize - The maximum size of the image for width and height.

The resultant documentBitmap is a resized document image.

Filter

Apply filters

To apply a filter to the document image use the ImageProcessor#applyFilter() method:

val documentBitmap = ImageProcessor(originalBitmap).applyFilter(filter).processedBitmap()

The parameters are:

  • originalBitmap - The original Bitmap image as the input to process the document image from. This input image will not be modified.
  • filter - the selected io.scanbot.imagefilters.ParametricFilter filter.

The resultant documentBitmap is a filtered document image.

Supported parametric image filters

  • ColorDocumentFilter - Color document filter. This filter is a good starting point for most use cases.
  • ScanbotBinarizationFilter - Automatic binarization filter. This filter is a good starting point for most use cases. It has outputMode: OutputMode parameter which can be set to OutputMode.BINARY or OutputMode.ANTIALIASED.
  • CustomBinarizationFilter - Customizable binarization filter. It has a few presets for specific use cases:
    • BinarizationFilterPreset.PRESET_1 - Usually performs well if there is no shadow.
    • BinarizationFilterPreset.PRESET_2, BinarizationFilterPreset.PRESET_3, BinarizationFilterPreset.PRESET_4 - Usually performs well even if there are shadows.
  • BrightnessFilter - Brightness adjustment filter.
  • ContrastFilter - Contrast adjustment filter.
  • GrayscaleFilter - Converts color images to grayscale, optionally applying auto-contrast.
  • WhiteBlackPointFilter - Maps image value channel so that all the pixels darker than the black point are set to 0, all the pixels brighter than the white point are set to 255, and the pixels in between are linearly scaled.
  • LegacyFilter - A filter that applies a legacy filter to the image. This filter is used for compatibility with older versions of the Scanbot SDK. It takes one of the old filter types as a parameter:
    • ImageFilterType.NONE - Do not apply an image filter, keep the original colors.
    • ImageFilterType.COLOR_ENHANCED - Optimizes the colors, contrast and brightness.
    • ImageFilterType.GRAYSCALE - Grayscale filter.
    • ImageFilterType.BINARIZED - Standard binarization filter with contrast optimization. Creates an 8-bit grayscale image with mostly black or white pixels.
    • ImageFilterType.COLOR_DOCUMENT - MagicColor filter. Fixes the white-balance and cleans up the background.
    • ImageFilterType.PURE_BINARIZED - A filter for binarizing an image. Creates an image with pixel values set to either pure black or pure white.
    • ImageFilterType.BLACK_AND_WHITE - Black and white filter with background cleaning. Creates an 8-bit grayscale image with mostly black or white pixels.
    • ImageFilterType.BACKGROUND_CLEAN - Cleans up the background and tries to preserve photos within the image.
    • ImageFilterType.OTSU_BINARIZATION - A filter for black and white conversion using OTSU binarization.
    • ImageFilterType.DEEP_BINARIZATION - A filter for black and white conversion primary used for low-contrast documents.
    • ImageFilterType.EDGE_HIGHLIGHT - A filter that enhances edges in low-contrast documents.
    • ImageFilterType.LOW_LIGHT_BINARIZATION - Binarization filter primarily intended to use on low-contrast documents with hard shadows.
    • ImageFilterType.LOW_LIGHT_BINARIZATION_2 - Binarization filter primarily intended to use on low-contrast documents with hard shadows.
    • ImageFilterType.SENSITIVE_BINARIZATION - Binarization filter for poor quality printed papers. See important info about this type below!

Using ImageFilterType.SENSITIVE_BINARIZATION filter

If you plan to use this filter or add it to the supported list in your app you need to take one additional step:

  • add implementation("io.scanbot:sdk-ml-imageprocessor-assets:$scanbotSdkVersion") dependency to your build.gradle file

Chains of operations

It is possible to apply different operations using ImageProcessor

val documentBitmap = ImageProcessor(originalBitmap)
.crop(polygonToCrop)
.rotate(rotation)
.applyFilter(filter)
.processedBitmap()

The parameters are:

  • originalBitmap - The original Bitmap image as the input to apply operations of the image processor to. This input image will not be modified.
  • polygonToCrop - The polygon to crop the image.
  • rotation - The rotation type to apply.
  • filter - A filter in the chain.

The resultant documentBitmap is a filtered document image.

Page Processing

The Scanbot SDK provides a set of processing operations which can be performed directly on io.scanbot.sdk.persistence.Page objects. All these operations are collected in the io.scanbot.sdk.docprocessing.PageProcessor class.

val pageProcessor = ScanbotSDK(context).createPageProcessor()

Operations overview

  • applyFilter(page: Page, parametricFilter: ParametricFilter): Page - Applies an image filter on the provided page based on the existing unfiltered document image. The filtered image result will be stored as a document image of the page. The current document image of the page will be overwritten. The original image of the page will not be modified. More info about ParametricFilter can be found here.

Example:

val pageProcessor = ScanbotSDK(context).createPageProcessor()

val binarizedPage: Page = pageProcessor.applyFilter(yourPage, ScanbotBinarizationFilter())
  • applyFilter(page: Page, parametricFilters: List<ParametricFilter>): Page - Applies a list of image filters one-by-one on the provided page based on the existing unfiltered document image. The filtered image result will be stored as a document image of the page. The current document image of the page will be overwritten. The original image of the page will not be modified.

  • generateFilteredPreview(page: Page, parametricFilter: ParametricFilter): Bitmap - generates a filtered preview image based on the unfiltered document preview image and caches it in the file system.

  • detectDocument(page: Page): Page - performs document detection on the original image of the provided page. The page must contain the original image. Creates and stores the document (cropped) image file based on the document detection result (polygon) and optionally defined filter in the page object. If the source Page contains some filter (page.filter) or tunes (page.tunes) options they will be applied. page - existing page with the original image. Returns a new Page instance with updated fields Page.polygon and Page.detectionStatus. More info about Document Detection can be found here.

  • rotate(page: Page, times: Int): Page - rotates all images (and previews) of the given Page X times. The original image is required, other images (document, unfiltered document) are optional. The direction of rotation is counterclockwise if the times value is positive and clockwise if times value is negative (e.g. -2 = rotates twice to the right).

  • cropAndRotate(page: Page, times: Int, polygon: List<PointF>): Page - crops the polygon from the original image and rotates all images (and previews) of the given Page X times. The original image is required, other images (document, unfiltered document) are optional. If the source Page contains some filter (page.filter) or tunes (page.tunes) options they will be applied. The direction of rotation is counterclockwise if the times value is positive and clockwise if times value is negative (e.g. -2 = rotates twice to the right).

Want to scan longer than one minute?

Generate your free "no-strings-attached" Trial License and properly test the Scanbot SDK.

Get your free Trial License

What do you think of this documentation?