Digital image processing: brightness contrast-geometric transformation-noise processing

digital image enhancement

Brightness and Contrast Conversion

Image transformation can be divided into the following two types:

  • Point operator: Based on pixel transformation, in this type of image transformation, the corresponding output pixel value is calculated only based on the input pixel value.
  • Neighborhood operator: Transform based on image area

Two commonly used point operators use constants to multiply or add point pixel values, which can be expressed as:

g ( i , j ) = α ∗ f ( i , j ) + β g(i, j) = \alpha * f(i, j) + \beta g(i,j)=af(i,j)+b

Among them, the position of the midpoint of the image is (i, j) (i, j)(i,j ) ,αthe value represents the gain, andβthe value represents the offset. Transforming the brightness and contrast of the image is a point operator. These two parameters can be used to control contrast and brightness respectively. You can adjust the contrast or brightness of the image by adjusting the values ​​of these two parameters. That is, adding a bias constant to each pixel in the original image can make the image brighter. Similarly, multiplying the pixels in the original image by a gain coefficient can adjust the contrast of the image.

Notice

The pixel value range of the image pixels is [0, 255]. Be sure not to let it overflow. You can use np.cliptruncation

Example image:

Insert image description here

import cv2
import numpy as np


#  方法1: 基于addWeighted()函数实现
def convert_img1(img, alpha, beta):
    blank = np.zeros(img.shape, img.dtype)
    return cv2.addWeighted(img, alpha, blank, 0, beta)


# 方法2: 通过for循环手动实现
def convert_img2(img, alpha, beta):
    rows, cols, chs = img.shape
    new_img = np.zeros(img.shape, img.dtype)
    for i in range(rows):
        for j in range(cols):
            for k in range(chs):
                new_img[i, j, k] = np.clip(alpha * img[i, j, k] + beta, 0, 255)
    return new_img

img = cv2.imread('woman.png')
cv2.imwrite('convert_img1.jpg', convert_img1(img, 2.2, 50))
cv2.imwrite('convert_img2.jpg', convert_img2(img, 2.2, 50))

Insert image description here

In the above code, the parameter lists of the functions convert_img1()in the function addWeighted()are: [img1,alpha,img2,beta,gamma], which means that the two pictures are calculated as follows:

n e w _ i m g = a l p h a ∗ i m g 1 + b e t a ∗ i m g 2 + g a m m a new\_img = alpha * img1 + beta * img2 + gamma new_img=alphaimg1+betaimg2+gamma

The process of function convert_img2()implementation is to modify the pixel value of the original image through a for loop, which convert_img1()is the same as the function process, except that the pixel values ​​of the image in the img2 parameter of the convert_img1()function call are all 0.addWeighted()

geometric transformation

The geometric transformation of an image refers to an operation that transforms the positions of image pixels in a picture. It maps the coordinate positions in an image to new coordinate positions, that is, changes the spatial position of the pixels, and also changes the spatial position of the pixels. Estimate the pixel value at the new spatial location.

Image cropping

Cut out part of the matrix from the matrix of image data as new image data, thereby realizing cropping of the image.

import cv2
import numpy as np

# 图像裁剪
img = cv2.imread('woman.png')
print(img.shape)

new_img = img[20:300, 20:400]
cv2.imwrite('crop_img.jpg', new_img)

Insert image description here

The process implemented by the above code is to crop the original image from (20,20)the position of the pixel (300,400)to everywhere and the cropped shape is a rectangle.

size transformation

Modifying the size of the image means modifying the size of the image. OpenCV resize()functions can achieve this function. When resizing an image, some pixels will inevitably be lost or added. It is recommended to use regional interpolation when zooming cv2.INTER_AREAto avoid ripples; it is recommended to use cubic spline interpolation when zooming in cv2.INTER_CUBIC, but its calculation speed is relatively slow. You can also use linear interpolation cv2.INTER_LINEAR. By default, all operations that change the image size use linear interpolation.

# 图像缩放
small_resize_img = cv2.resize(img, (200, 200), interpolation=cv2.INTER_AREA)
cv2.imwrite('small_resize.jpg', small_resize_img)

small_resize_img2 = cv2.resize(img, None, fx=0.5, fy=0.6, interpolation=cv2.INTER_AREA)  # 图像的宽对应的是列数,高对应的是行数
cv2.imwrite('small_resize2.jpg', small_resize_img2)

Insert image description here
Insert image description here

image rotation

Rotation is getRotationMatrix2D()implemented through functions.

# 图像旋转
img = cv2.imread('woman.png')
rows, cols, _ = img.shape
rotated_mat = cv2.getRotationMatrix2D((cols/2, rows/2), 45, 1)  # 第一个参数是旋转中心,第2个为旋转角度,第3个为旋转后的缩放因子
rotated_img = cv2.warpAffine(img, rotated_mat, dsize=(cols, rows))
cv2.imwrite('rot45.jpg', rotated_img)

Insert image description here

Noise processing

Adding an appropriate amount of noise to the training data can make the trained model more robust and help improve the performance of the model. Eliminating noise can increase image quality.

add noise

There are two common ways to add noise to images:

  • salt and pepper noise
  • Gaussian noise
import cv2
import random
import numpy as np

# 添加椒盐噪声
def salt_and_pepper_noise(img, percentage):
    rows, cols, chs = img.shape
    num = int(percentage * rows * cols)
    for i in range(num):
        x = random.randint(0, rows-1)
        y = random.randint(0, cols-1)
        z = random.randint(0, chs-1)
        if random.randint(0, 1) == 0:
            img[x, y, z] = 0  # 黑色噪点
        else:
            img[x, y, z] = 255  # 白色噪点
    return img

# 添加高斯随机噪声
def gaussian_noise(img, mu, sigma, delta):
    rows, cols, chs = img.shape
    for i in range(rows):
        for j in range(cols):
            for k in range(chs):
                # 生成高斯分布的随机数,与原始数据相加要取整
                value = int(img[i, j, k] + delta*random.gauss(mu=mu, sigma=sigma))
                value = np.clip(a_max=255, a_min=0, a=value)
                img[i, j, k] = value
    return img


img = cv2.imread('woman.png')

cv2.imwrite('saltPepper.jpg', salt_and_pepper_noise(img, 0.3))
cv2.imwrite('gaussain.jpg', gaussian_noise(img, 0, 1, 100))

Insert image description here

Insert image description here

You can see the above methods of adding salt and pepper noise and Gaussian noise to images. For Gaussian noise, the parameter gaussian_noise()in the function murepresents the mean of the Gaussian distribution of random numbers, sigmarepresents the standard deviation of the Gaussian distribution of random numbers, and the parameter deltarepresents a coefficient indicating the intensity of adding Gaussian noise.

Dealing with noise

OpenCV provides several filtering methods, such as median filtering, bilateral filtering, Gaussian blur, two-dimensional convolution, etc.

import cv2
import random
import numpy as np

# 模糊与滤波
salt_and_pepper_img = cv2.imread('saltPepper.jpg')
gaussain_img = cv2.imread('gaussain.jpg')

# 二维卷积
kernel = np.ones((5, 5), np.float32) / 25  # 每个值是0.04
conv_2d_img = cv2.filter2D(salt_and_pepper_img, -1, kernel)
cv2.imwrite('filter_2d_img.jpg', conv_2d_img)

# 中值滤波
median_blur_img = cv2.medianBlur(salt_and_pepper_img, 5)  # 参数5表示大小为5x5的区域像素值进行计算
cv2.imwrite('median_blur_img.jpg', median_blur_img)

# 高斯模糊
gaussian_blur_img = cv2.GaussianBlur(gaussain_img, (5, 5), 0)
cv2.imwrite('gaussian_blur_img.jpg', gaussian_blur_img)

# 双边滤波
bilateral_filter_img = cv2.bilateralFilter(gaussain_img, 9, 75, 75)  # 9代表邻域直径,两个参数75分别代表值域与空域标准差
cv2.imwrite('bilateral_filter_img.jpg', bilateral_filter_img)

Insert image description here

Insert image description here

Insert image description here

Insert image description here

It can be seen that the median filter has the best effect.

Guess you like

Origin blog.csdn.net/uncle_ll/article/details/132698298