Article directory
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)=a∗f(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.clip
truncation
Example image:
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))
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=alpha∗img1+beta∗img2+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)
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_AREA
to 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)
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)
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))
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 mu
represents the mean of the Gaussian distribution of random numbers, sigma
represents the standard deviation of the Gaussian distribution of random numbers, and the parameter delta
represents 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)
It can be seen that the median filter has the best effect.