Note

This is the documentation for the latest development branch and may refer to features that are not available in released versions. If you are looking for the documentation for a specific release, use the drop-down menu on the left and select the desired version.

Image Processing Routine Explanation#

Overview#

In OpenMV, there are many image processing functions for different image operations and feature processing. These functions can help you implement various visual tasks, such as image enhancement, noise reduction, binarization, edge detection, and more.

CanMV supports OpenMV algorithms and can also use these functions.

Image Processing Function Description#

Image Enhancement and Correction#

  • histeq: Histogram Equalization

    • Used to enhance the contrast of an image, making the histogram distribution more uniform.

    img = sensor.snapshot()
    img.histeq()
    
  • gamma_corr: Gamma Correction

    • Adjusts the brightness and contrast of an image. A Gamma value greater than 1 increases contrast, while a Gamma value less than 1 decreases contrast.

    img = sensor.snapshot()
    img.gamma_corr(1.5)  # Gamma value is 1.5
    
  • rotation_corr: Rotation Correction

    • Corrects rotation errors in the image.

    img = sensor.snapshot()
    img.rotation_corr(0.5)  # Correct rotation error, correction angle is 0.5 radians
    
  • lens_corr: Lens Distortion Correction

    • Corrects geometric distortion of the lens, typically used to correct fisheye lens distortion.

    img = sensor.snapshot()
    img.lens_corr(1.0)  # Correct distortion, correction coefficient is 1.0
    

Filtering and Noise Reduction#

  • gaussian: Gaussian Filtering

    • Used to smooth the image and reduce noise. Gaussian filtering performs weighted averaging through mean filtering.

    img = sensor.snapshot()
    img.gaussian(2)  # Gaussian filtering, filter kernel size is 2
    
  • bilateral: Bilateral Filtering

    • Aims to smooth the image while preserving edges. Bilateral filtering combines smoothing in both the spatial domain and color domain.

    img = sensor.snapshot()
    img.bilateral(5, 75, 75)  # Bilateral filtering, standard deviations of spatial domain and color domain are 5 and 75 respectively
    
  • median: Median Filtering

    • Removes noise from the image, especially salt-and-pepper noise.

    img = sensor.snapshot()
    img.median(3)  # Median filtering, window size is 3x3
    
  • mean: Mean Filtering

    • Smooths the image by calculating the mean of neighboring pixels to reduce noise.

    img = sensor.snapshot()
    img.mean(3)  # Mean filtering, window size is 3x3
    

Binarization and Morphological Operations#

  • binary: Binarization

    • Converts the image to a binary image, dividing pixels into black and white based on a threshold.

    img = sensor.snapshot()
    img.binary([(100, 255)])  # Binarization, threshold range is (100, 255)
    
  • dilate: Dilation

    • A morphological operation that expands white areas in the image, typically used to fill holes.

    img = sensor.snapshot()
    img.dilate(2)  # Dilation operation, dilation count is 2
    
  • erode: Erosion

    • A morphological operation that shrinks white areas in the image, typically used to remove small noise.

    img = sensor.snapshot()
    img.erode(2)  # Erosion operation, erosion count is 2
    
  • morph: Morphological Operation

    • Performs complex morphological operations, such as opening, closing, etc.

    img = sensor.snapshot()
    img.morph(2, morph.MORPH_CLOSE)  # Morphological operation, closing
    

Edge Detection#

  • laplacian: Laplacian Edge Detection

    • Used to detect edges in the image.

    img = sensor.snapshot()
    img.laplacian(3)  # Laplacian edge detection, window size is 3
    
  • sobel: Sobel Edge Detection

    • Another filter used for edge detection.

    img = sensor.snapshot()
    img.sobel(3)  # Sobel edge detection, window size is 3
    

Polar Coordinate Conversion#

  • linpolar: Linear Polar Coordinate Conversion

    • Converts the image from Cartesian coordinate system to polar coordinate system.

    img = sensor.snapshot()
    img.linpolar(10)  # Linear polar coordinate conversion, radius step is 10
    
  • logpolar: Logarithmic Polar Coordinate Conversion

    • Converts the image from Cartesian coordinate system to logarithmic polar coordinate system.

    img = sensor.snapshot()
    img.logpolar(10)  # Logarithmic polar coordinate conversion, radius step is 10
    

Image Inversion and Modes#

  • negate: Invert Image

    • Inverts all pixel values in the image.

    img = sensor.snapshot()
    img.negate()  # Invert image
    
  • midpoint: Midpoint Mode

    • Returns the midpoint pixel value in the image.

    img = sensor.snapshot()
    img.midpoint()
    
  • mode: Mode Value

    • Returns the most common pixel value in the image.

    img = sensor.snapshot()
    img.mode()
    

Summary#

These functions can be used to perform various image processing tasks:

  • Image Enhancement and Correction: histeq, gamma_corr, rotation_corr, lens_corr

  • Filtering and Noise Reduction: gaussian, bilateral, median, mean

  • Binarization and Morphological Operations: binary, dilate, erode, morph

  • Edge Detection: laplacian, sobel

  • Polar Coordinate Conversion: linpolar, logpolar

  • Image Inversion and Modes: negate, midpoint, mode

You can select the appropriate image processing functions to process and analyze images based on actual needs.

Example#

Only one image binarization demo is listed here. For specific demos, please refer to the routines in the virtual USB drive that comes with the firmware.

# Color Binarization Filtering Example
#
# This script demonstrates binarized image filtering. You can pass any number of thresholds to segment the image.
import time, os, gc, sys

from media.sensor import *
from media.display import *
from media.media import *

DETECT_WIDTH = ALIGN_UP(640, 16)
DETECT_HEIGHT = 480

# Use Tools -> Machine Vision -> Threshold Editor to select better thresholds.
red_threshold = (0,100,   0,127,   0,127) # L A B
green_threshold = (0,100,   -128,0,   0,127) # L A B
blue_threshold = (0,100,   -128,127,   -128,0) # L A B

sensor = None

def camera_init():
    global sensor

    # Construct a Sensor object using default configuration
    sensor = Sensor(width=DETECT_WIDTH,height=DETECT_HEIGHT)
    # sensor reset
    sensor.reset()
    # Set horizontal mirror
    # sensor.set_hmirror(False)
    # Set vertical flip
    # sensor.set_vflip(False)

    # Set channel 0 output size
    sensor.set_framesize(width=DETECT_WIDTH,height=DETECT_HEIGHT)
    # Set channel 0 output format
    sensor.set_pixformat(Sensor.RGB565)

    # Use the IDE as the display output. If the selected screen cannot be lit, please refer to the k230_canmv_display_module_api_manual in the API documentation to configure it yourself
    Display.init(Display.VIRT, width= DETECT_WIDTH, height = DETECT_HEIGHT,fps=100,to_ide = True)
    # Initialize the media manager
    MediaManager.init()
    # sensor starts running
    sensor.run()

def camera_deinit():
    global sensor

    # sensor stops running
    sensor.stop()
    # Destroy the display
    Display.deinit()
    # Sleep
    os.exitpoint(os.EXITPOINT_ENABLE_SLEEP)
    time.sleep_ms(100)
    # Release the media buffer
    MediaManager.deinit()

def capture_picture():

    frame_count = 0
    fps = time.clock()
    while True:
        fps.tick()
        try:
            os.exitpoint()

            global sensor
            img = sensor.snapshot()

            # Test red threshold
            if frame_count < 100:
                img.binary([red_threshold])
            # Test green threshold
            elif frame_count < 200:
                img.binary([green_threshold])
            # Test blue threshold
            elif frame_count < 300:
                img.binary([blue_threshold])
            # Test non-red threshold
            elif frame_count < 400:
                img.binary([red_threshold], invert = 1)
            # Test non-green threshold
            elif frame_count < 500:
                img.binary([green_threshold], invert = 1)
            # Test non-blue threshold
            elif frame_count < 600:
                img.binary([blue_threshold], invert = 1)
            else:
                frame_count = 0
            frame_count = frame_count + 1
            # Draw the result on the screen
            Display.show_image(img)
            img = None
            gc.collect()
            #print(fps.fps())
        except KeyboardInterrupt as e:
            print("user stop: ", e)
            break
        except BaseException as e:
            print(f"Exception {e}")
            break

def main():
    os.exitpoint(os.EXITPOINT_ENABLE)
    camera_is_init = False
    try:
        print("camera init")
        camera_init()
        camera_is_init = True
        print("camera capture")
        capture_picture()
    except Exception as e:
        print(f"Exception {e}")
    finally:
        if camera_is_init:
            print("camera deinit")
            camera_deinit()

if __name__ == "__main__":
    main()

Tip

For the specific interface definition, please refer to image

Comments list
Comments
Log in