1、线性变换
图像增强线性变换主要可以对图像的对比度和亮度进行调整,线性变换公式如下:
参数 a 影响图像的对比度,参数 b 影响图像的亮度,具体分为可分为以下几种情况:
a>1: 增强图像的对比度,图像看起来更加清晰
a<1: 减小了图像的对比度, 图像看起来变暗
a<0 and b=0:图像的亮区域变暗,暗区域变亮
a=1 and b≠0:图像整体的灰度值上移或者下移,也就是图像整体变亮或者变暗,不会改变图像的对比度,b>0时图像变亮,b<0时图像变暗
a=-1 and b=255:图像翻转
import cv2
import random
# import imutils
import numpy as np
# 彩色图像每个像素值是[x,y,z], 灰度图像每个像素值便是一个np.uint8
path = './img/0.jpg' # 路径二维码
# path = './img/sachin.jpg' # 路径
image = cv2.imread(path)
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 图像大小调整
ori_h, ori_w = image.shape[:2]
height, width = gray_img.shape[:2]
image = cv2.resize(image, (int(ori_w / ori_h * 400), 400), interpolation=cv2.INTER_CUBIC)
gray_img = cv2.resize(gray_img, (int(width / height * 400), 400), interpolation=cv2.INTER_CUBIC)
# a<0 and b=0: 图像的亮区域变暗,暗区域变亮
a, b = -0.5, 0
new_img1 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
for i in range(new_img1.shape[0]):
for j in range(new_img1.shape[1]):
new_img1[i][j] = gray_img[i][j] * a + b
# a>1: 增强图像的对比度,图像看起来更加清晰
a, b = 1.5, 20
new_img2 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
for i in range(new_img2.shape[0]):
for j in range(new_img2.shape[1]):
if gray_img[i][j] * a + b > 255:
new_img2[i][j] = 255
else:
new_img2[i][j] = gray_img[i][j] * a + b
# a<1: 减小了图像的对比度, 图像看起来变暗
a, b = 0.5, 0
new_img3 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
for i in range(new_img3.shape[0]):
for j in range(new_img3.shape[1]):
new_img3[i][j] = gray_img[i][j] * a + b
# a=1且b≠0, 图像整体的灰度值上移或者下移, 也就是图像整体变亮或者变暗, 不会改变图像的对比度
a, b = 1, -50
new_img4 = np.ones((gray_img.shape[0], gray_img.shape[1]), dtype=np.uint8)
for i in range(new_img4.shape[0]):
for j in range(new_img4.shape[1]):
pix = gray_img[i][j] * a + b
if pix > 255:
new_img4[i][j] = 255
elif pix < 0:
new_img4[i][j] = 0
else:
new_img4[i][j] = pix
# a=-1, b=255, 图像翻转
new_img5 = 255 - gray_img
cv2.imshow('origin', image)
cv2.imshow('gray', gray_img)
cv2.imshow('a<0 and b=0', new_img1)
cv2.imshow('a>1 and b>=0',new_img2)
cv2.imshow('a<1 and b>=0',new_img3)
cv2.imshow('a=1 and b><0',new_img4)
cv2.imshow('a=-1 and b=255',new_img5)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
# 原文链接:https: // blog.csdn.net / feilong_csdn / article / details / 82780664
##############
对比度拉伸实例演示
# 分段线性变换应用之对比度拉伸、阈值处理
# 低对比度图像一般由光照不足,成像传感器动态范围太小,图像获取过程中镜头光圈设置错误引起,对比度拉伸是扩展图像灰度级动态范围的处理。变换算子
# 下面令(r1, s1) = (rmin,0)、(r2, s2) = (rmax,L-1),其中
# rmin、rmax
# 分别代表数字图像中最小灰度级和最大灰度级,此变换函数将灰度级由原来范围线性拉伸到整个范围[0,L - 1]
# import cv2
# import imutils
import numpy as np
path = './img/0.jpg' # 路径二维码
# path = './img/sachin.jpg' # 路径
image = cv2.imread(path)
gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 直接在原图上进行分段线性对比度拉伸
# 此种方式变换函数把灰度级由原来的线性拉伸到整个范围[0, 255]
r_min, r_max = 255, 0
for i in range(image.shape[0]):
for j in range(image.shape[1]):
for k in range(image.shape[2]):
if image[i, j, k] > r_max:
r_max = image[i, j, k]
if image[i, j, k] < r_min:
r_min = image[i, j, k]
r1, s1 = r_min, 0
r2, s2 = r_max, 255
k1 = s1 / r1
k3 = (255 - s2) / (255 - r2)
k2 = (s2 - s1) / (r2 - r1)
precewise_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
for k in range(image.shape[2]):
if r1 <= image[i, j, k] <= r2:
precewise_img[i, j, k] = k2 * (image[i, j, k] - r1)
elif image[i, j, k] < r1:
precewise_img[i, j, k] = k1 * gray_img[i, j, k]
elif image[i, j, k] > r2:
precewise_img[i, j, k] = k3 * (gray_img[i, j, k] - r2)
# 原图中做分段线性变化后需要对图像进行归一化操作,并将数据类型转换到np.uint8
cv2.normalize(precewise_img, precewise_img, 0, 255, cv2.NORM_MINMAX)
precewise_img = cv2.convertScaleAbs(precewise_img)
cv2.imshow('origin image',image)
cv2.imshow('precewise image', precewise_img)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
#######################
“”"
对数变换将图像的低灰度值部分扩展,将其高灰度值部分压缩
,以达到强调图像低灰度部分的目的;同时可以很好的压缩像素值变化较大的图像的动态范围,
目的是突出我们需要的细节。反对数变换则与对数函数不同的是,强调的是图像的高灰度部分,对数变换公式如下
:return:
“”"
import cv2
import math
path = './img/0.jpg' # 路径二维码
# path = './img/sachin.jpg' # 路径
image = cv2.imread(path)
log_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
log_img[i, j, 0] = math.log(1 + image[i, j, 0])
log_img[i, j, 1] = math.log(1 + image[i, j, 1])
log_img[i, j, 2] = math.log(1 + image[i, j, 2])
cv2.normalize(log_img, log_img, 0, 255, cv2.NORM_MINMAX)
log_img = cv2.convertScaleAbs(log_img)
cv2.imshow('image', image)
cv2.imshow('log transform', log_img)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
4、幂律变换
幂律变换主要用于图像的校正,对漂白的图片或者是过黑的图片进行修正,幂律变换的公式如下:根据 φ 的大小,主要可分为一下两种情况:
φ > 1: 处理漂白的图片,进行灰度级压缩
φ < 1: 处理过黑的图片,对比度增强,使得细节看的更加清楚
path = './img/0.jpg' # 路径二维码
# path = './img/sachin.jpg' # 路径
image = cv2.imread(path)
log_img = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
# 幂律变换 φ>1
min_min=0.4 #上面是5
gamma_img1 = np.zeros((image.shape[0], image.shape[1], 3), dtype=np.float32)
for i in range(image.shape[0]):
for j in range(image.shape[1]):
gamma_img1[i, j, 0] = math.pow(image[i, j, 0], min_min)
gamma_img1[i, j, 1] = math.pow(image[i, j, 1],min_min)
gamma_img1[i, j, 2] = math.pow(image[i, j, 2], min_min)
cv2.normalize(gamma_img1, gamma_img1, 0, 255, cv2.NORM_MINMAX)
gamma_img1 = cv2.convertScaleAbs(gamma_img1)
cv2.imshow('image', image)
cv2.imshow('gamma1 transform', gamma_img1)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()
import cv2
import math
import matplotlib.pyplot as plt
path = './img/0.jpg' # 路径二维码
# path = './img/sachin.jpg' # 路径
image = cv2.imread(path)
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 对图像进行均衡化处理,增强图像对比度
image_equ = cv2.equalizeHist(image_gray)
hist = cv2.calcHist([image_gray], [0], None, [256], [0, 256])
equ_hist = cv2.calcHist([image_equ], [0], None, [256], [0, 256])
fig = plt.figure()
ax1 = fig.add_subplot(1, 2, 1)
ax1.plot(hist)
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot(equ_hist)
plt.show()
cv2.imshow('wiki_origin', image)
cv2.imshow('wiki_gray', image_gray)
cv2.imshow('wiki_equ', image_equ)
if cv2.waitKey(0) == 27:
cv2.destroyAllWindows()