paidiver / paidiverpy

Create pipelines for preprocessing image data for biodiversity analysis.
Apache License 2.0
3 stars 0 forks source link

Addressing blur #17

Open soutobias opened 2 months ago

soutobias commented 2 months ago

What:

Blurring refers to the reduction in image sharpness and detail due to out-of-focus effects, camera motion, or inadequate shutter speed calibration. It can also occur when extracting images from deinterlaced videos. The effect results in a loss of distinctness between pixels, making important features less discernible. Common causes of blurring include camera shake, focus issues, and subject movement. To address blurring, especially without prior knowledge of the blur's cause, blind image deblurring techniques are used [ZHA].

The degradation model for a blurry image can be represented by the equation:

[ S = H \ast U + N ]

where:

A common approximation for out-of-focus distortion is a circular PSF characterized by its radius ( R ).

Why:

Blurring reduces image resolution and can hinder feature detection, impacting the precision of biodiversity assessments and other image-based analyses.

How:

Blurring can be diagnosed using algorithms to understand how blur spreads within an image set and to set a blur threshold for removing blurred images.

Several techniques can restore a blurred image by estimating the original image from the degraded version:

  1. Wiener Filter: This method is used to de-blur an image by reducing the effects of noise and blur, assuming known parameters such as the signal-to-noise ratio (SNR) and the characteristics of the blur kernel.

  2. Blind Image Deblurring: Techniques that estimate the blur kernel and use it to restore the original image without prior knowledge of the blur specifics.

Python Code Examples:

  1. Blur Detection:

    import cv2
    import numpy as np
    
    def detect_blur(image_path, threshold=100):
        image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
        laplacian = cv2.Laplacian(image, cv2.CV_64F)
        variance = laplacian.var()
    
        if variance < threshold:
            return True  # Image is likely blurred
        return False  # Image is sharp
    
    # Example usage:
    is_blurry = detect_blur('example_image.jpg')
    print(f"Image is {'blurry' if is_blurry else 'sharp'}")
  2. Wiener Filter for De-blurring:

    import cv2
    import numpy as np
    from scipy.signal import convolve2d
    
    def wiener_filter(image, psf, noise_var, estimated_noise_var):
        psf_fft = np.fft.fft2(psf, s=image.shape)
        image_fft = np.fft.fft2(image)
        psf_fft_conj = np.conj(psf_fft)
        result_fft = (psf_fft_conj / (np.abs(psf_fft) ** 2 + noise_var / estimated_noise_var)) * image_fft
        result = np.fft.ifft2(result_fft).real
        return np.clip(result, 0, 255).astype(np.uint8)
    
    def create_psf(radius, size):
        psf = np.zeros((size, size))
        center = size // 2
        y, x = np.ogrid[:size, :size]
        mask = (x - center) ** 2 + (y - center) ** 2 <= radius ** 2
        psf[mask] = 1
        psf /= psf.sum()
        return psf
    
    # Example usage:
    image = cv2.imread('blurry_image.jpg', cv2.IMREAD_GRAYSCALE)
    psf = create_psf(radius=5, size=image.shape[0])
    restored_image = wiener_filter(image, psf, noise_var=0.1, estimated_noise_var=0.2)
    
    cv2.imshow('Restored Image', restored_image)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

What to expect:

What makes it difficult:

Success Metrics:

soutobias commented 2 months ago

@Mojtabamsd , take a look on the develop branch. I perform some changes in the blur method. I also apply several changes in the code, mainly related on how we call the functions and in the configuration file.