How to detect if an image is partially occluded?
Asked Answered
M

2

9

I have a large number of aerial images. Some of them have the lens partially occluded. For example:

enter image description here

and

enter image description here

I'm trying to automatically detect which of the images have this using OpenCV. My initial though was to check how much of the image is black across multiple images. But hopefully there is a smarted way to do it for images in isolation.

Mcwhirter answered 20/8, 2014 at 3:7 Comment(1)
Can you define partially occluded ? is the occlusion likely to be circular (or at least parts of a circle). Can their ever be occlusion that doesn't connect with the edges ? If you can answer these questions, it might help with a solution.Compunction
C
2

An idea is to determine how many black pixels are on the image. We can do this by creating a blank mask and then coloring all detected black pixels white on the mask using np.where. From here we can count the number of white pixels on the mask with cv2.countNonZero then calculate the pixel percentage. If the calculated percentage is greater than some threshold (say 2%) then the image is partially occluded. Here's the results:

Input image -> mask

Pixel Percentage: 3.33%
Occluded: True

Pixel Percentage: 2.54%
Occluded: True

Code

import cv2
import numpy as np

def detect_occluded(image, threshold=2):
    """Determines occlusion percentage and returns 
       True for occluded or False for not occluded"""

    # Create mask and find black pixels on image
    # Color all found pixels to white on the mask
    mask = np.zeros(image.shape, dtype=np.uint8)
    mask[np.where((image <= [15,15,15]).all(axis=2))] = [255,255,255]

    # Count number of white pixels on mask and calculate percentage
    mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
    h, w = image.shape[:2]
    percentage = (cv2.countNonZero(mask)/ (w * h)) * 100
    if percentage < threshold:
        return (percentage, False)
    else:
        return (percentage, True)

image = cv2.imread('2.jpg')
percentage, occluded = detect_occluded(image)
print('Pixel Percentage: {:.2f}%'.format(percentage))
print('Occluded:', occluded)
Cheesecake answered 24/1, 2020 at 23:29 Comment(0)
M
0

I'd recommend using some sort of floodfill algorithm with black pixels. By checking large (connected) black area's, you could indentify these. This approach has the advantage that you can tweak the parameters for aggressiveness (eg; When is a pixel labled as black, how large must the connected area be, etc).

Marozik answered 20/8, 2014 at 11:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.