python 基于opencv去除图片阴影

1. Introduction

Image processing is the technique of altering the characteristics of an image by manipulating its pixels values. One of the most common image processing techniques is Image Enhancement. Image enhancement aims to improve the visual appearance of an image by increasing the level of detail that can be perceived by the human eye. A common problem in images is the presence of shadows. Shadows can greatly affect the quality and visual appeal of an image. This tutorial will discuss how to remove shadows from images using OpenCV and Python.

2. Removing Shadows using OpenCV

OpenCV (Open Source Computer Vision) is an open source library of computer vision and machine learning algorithms. It is used for tasks such as image processing, object detection, and more. In order to remove shadows from an image using OpenCV, we first need to understand how shadows are formed. Shadows are formed when an object obstructs the path of light. This obstruction causes a decrease in the amount of light that reaches certain areas of the image, resulting in darker areas which we perceive as shadows.

One technique for removing shadows is to use the normalised cut algorithm in conjunction with a Gaussian mixture model. The normalised cut algorithm provides a way to segment an image into multiple regions based on its color and texture. A Gaussian mixture model is used to model the pixel distribution of each region.

2.1 Normalised Cut Algorithm

The normalized cut algorithm is a graph-based image segmentation algorithm which can be used to segment the image into multiple regions. The algorithm utilises the graph structure of the image to group pixels together based on similarity criteria. The algorithm takes as input an image and outputs a set of segments which are represented by nodes in the graph. The algorithm attempts to minimise the cut distance between the segments while maximising the distance within the segments. The algorithm works as follows:

A graph is constructed from the image where each pixel is represented by a node in the graph.

An edge is created between each pair of nodes in the graph. The edge weight is a function of the pixel color and texture differences between the two pixels being connected.

The algorithm searches for the optimal cut by partitioning the graph into two disjoint sets while minimising the cut distance between the two sets.

The algorithm repeats step 3 for all possible partitionings until it finds the optimal cut.

2.2 Gaussian Mixture Model

A Gaussian mixture model (GMM) is a probabilistic model that assumes the presence of a finite number of Gaussian distributions in the data. The GMM is used to characterise the pixel distribution of each segment obtained from the normalised cut algorithm. Each segment is modelled using a mixture of K Gaussian distributions, where K is pre-defined based on the image characteristics. The GMM is trained on the pixel values of each segment, providing a probability distribution for each pixel belonging to each Gaussian.

3. Removing Shadows using Python

Removing shadows from an image can be accomplished using Python and OpenCV. The following is a Python code snippet that employs the normalised cut algorithm and the Gaussian mixture model to remove shadows from an image.

import cv2

import numpy as np

def normalize_cut(img):

# Convert image to L*a*b* color space

img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)

# Convert image to double precision

img_lab = img_lab.astype(np.float64)

# Normalize image

img_lab /= 255.0

# Obtain height and width of image

height, width, _ = img_lab.shape

# Reshape image to 2D array

img_lab_2d = img_lab.reshape((height * width, 3))

# Set number of components for GMM

num_components = 5

# Create GMM object

gmm = cv2.ml.EM_create()

# Set number of components

gmm.setClustersNumber(num_components)

# Set GMM covariance type

gmm.setCovarianceMatrixType(cv2.ml.EM_COV_MAT_DIAGONAL)

# Set termination criteria

gmm.setTermCriteria((cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 5, 0.1))

# Train GMM on image

gmm.trainEM(np.float32(img_lab_2d))

# Obtain probabilities of pixels belonging to each Gaussian component

probs = gmm.predict2(np.float32(img_lab_2d))[1]

# Reshape probabilities to image shape

probs_2d = probs.reshape((height, width, num_components))

# Obtain maximum probability for each pixel

max_probs = np.max(probs_2d, axis=2)

# Convert probabilities to mask

mask = (max_probs > 0.5)

# Obtain mean pixel values for each segment

means = gmm.getMeans()

# Obtain image without shadow

img_no_shadow = np.zeros_like(img_lab)

for i in range(num_components):

img_no_shadow[mask, 0] = means[i][0]

img_no_shadow[mask, 1] = means[i][1]

img_no_shadow[mask, 2] = means[i][2]

# Convert image to RGB color space

img_no_shadow = cv2.cvtColor(np.uint8(img_no_shadow * 255), cv2.COLOR_LAB2BGR)

return img_no_shadow

# Load image

img = cv2.imread('image.jpg')

# Remove shadows from image

img_no_shadow = normalize_cut(img)

# Display image without shadow

cv2.imshow('Image Without Shadow', img_no_shadow)

cv2.waitKey(0)

cv2.destroyAllWindows()

Conclusion

In conclusion, removing shadows from an image is an important task in image processing. OpenCV and python provide a powerful toolkit for developing image processing algorithms. In this tutorial, we discussed how to remove shadows from an image using the normalised cut algorithm and the Gaussian mixture model in OpenCV and Python. The code provided is a starting point for applications such as object recognition and image segmentation.

后端开发标签