OpenCV advanced - adjust image brightness contrast

image transformation

Image transformation is to find a function to convert the original image matrix into the target image matrix after being processed by the function. 
Can be divided into two ways, namely pixel-level transformation and region-level transformation

  • Point operators (pixel transforms)
  • Neighborhood (area-based) operators

Pixel-level transformation is equivalent to P_{after}(i,j)=f(P_{before}(i,j))that each pixel value after transformation has a functional mapping relationship with the pixel value at the same position before transformation.

linear transformation

The most commonly used is the linear transformation. That is, g(i,j)=\alpha \cdot f(i,j)+\beta
f(i, j) is the original pixel value, and g(i, j) is the transformed pixel value.
α adjusts the contrast, and β adjusts the brightness. Sometimes it is also called the gain and bias parameters.

Contrast and Brightness

What is contrast? Isn't it "the difference between light and dark"? That is, the difference in the size of the pixel value. Then I multiply it by an alpha coefficient. When the alpha is large, the difference in brightness value is enlarged, that is, the contrast is improved. When the alpha is small, the difference in brightness is reduced, that is, the contrast is reduced.

Beta is better understood. Add a number directly to the brightness value of the pixel. A positive number increases the brightness, and a negative number decreases the brightness.

Take a look at an example of the code below:

from __future__ import print_function
from builtins import input
import cv2 as cv
import numpy as np
import argparse

# Read image given by user
parser = argparse.ArgumentParser(description='Code for Changing the contrast and brightness of an image! tutorial.')
parser.add_argument('--input', help='Path to input image.', default='lena.jpg')
args = parser.parse_args()
image = cv.imread(cv.samples.findFile(args.input))
if image is None:
    print('Could not open or find the image: ', args.input)
    exit(0)
new_image = np.zeros(image.shape, image.dtype)
alpha = 1.0 # Simple contrast control
beta = 0    # Simple brightness control
# Initialize values
print(' Basic Linear Transforms ')
print('-------------------------')
try:
    alpha = float(input('* Enter the alpha value [1.0-3.0]: '))
    beta = int(input('* Enter the beta value [0-100]: '))
except ValueError:
    print('Error, not a number')
# Do the operation new_image(i,j) = alpha*image(i,j) + beta
# Instead of these 'for' loops we could have used simply:
# new_image = cv.convertScaleAbs(image, alpha=alpha, beta=beta)
# but we wanted to show you how to access the pixels :)
for y in range(image.shape[0]):
    for x in range(image.shape[1]):
        for c in range(image.shape[2]):
            new_image[y,x,c] = np.clip(alpha*image[y,x,c] + beta, 0, 255)
cv.imshow('Original Image', image)
cv.imshow('New Image', new_image)
# Wait until user press some key
cv.waitKey()

Execute: python change_brightness_contrast.py --input ./lights.jpeg

The picture above is a rendering of alpha=2, beta=20.

nonlinear transformation

There is a problem with linear transformation, as shown in the above picture, α=1.3 and β=40, while increasing the brightness of the original image, the cloud is almost invisible. If you want to see the clouds, the brightness of the building is not enough.

At this time, a nonlinear transformation is introduced. It is called Gamma correction

O = (\frac{1}{255})^\gamma \times 255
Different from linear transformation, the intensity of change is different for different original brightness values, which is non-linear.


When γ<1, the image brightness will be increased. When >1, reduce brightness.

The transformation effect diagram of γ=0.4 is as above. It can be seen that the clouds and buildings are brightened while maintaining the contrast so that the image is still clear.


You can see it if you look at the grayscale histograms under different transformations. In the middle is the grayscale histogram of the original image. You can see that there are many pixels with low brightness values.
The left side is linearly transformed, the overall histogram is shifted to the right, and a peak appears at 255. Because each pixel increases the brightness. As a result, the white clouds and the blue sky are too bright to be distinguished.
On the right, the gamma-corrected image has a relatively uniform brightness distribution, which means that the parts with low brightness values ​​can be strengthened, but it will not be overexposed so that white clouds cannot be distinguished.

The code to implement Gamma correction is as follows.

    lookUpTable = np.empty((1,256), np.uint8)
    for i in range(256):
        lookUpTable[0,i] = np.clip(pow(i / 255.0, gamma) * 255.0, 0, 255)
    res = cv.LUT(img_original, lookUpTable)

Where cv.LUT is a transformation function. Find the transformation relationship from lookUpTable and generate a new image matrix.

Guess you like

Origin blog.csdn.net/qq_39312146/article/details/130137970