图像中最高和最低灰度级之间的灰度差为对比度。
伽马变换主要目的是对比度拉伸,将图像灰度较低的部分进行修正
伽马变换针对的是对单个像素点的变换,也就是点对点的映射
import cv2
import numpy as np
def grammar(x, r):
"""
γ > 1 的时候,会压缩暗区的对比度,抬高亮区的对比度。并且γ越大,效果越明显
γ < 1 的时候,会提升暗区的对比度,压缩亮区的对比度。并且γ越小,效果越明显
γ = 1 的时候,图像的灰度不变(c 也为1)
"""
y = pow(x / 255, r) * 255
return y.astype(np.uint8)
img = cv2.imread('./butterfly.png', 0)
img_grammar = grammar(img, 0.6)
np.hstack((img, img_grammar))
hh=np.hstack((img, img_grammar))
cv2.imshow('img', hh)
cv2.waitKey()
cv2.destroyAllWindows()
对数变换可以提升原图中暗区的对比度,同时可以压缩明亮区的对比度。
import numpy as np
import cv2
def log(x):
y = np.log(1 + x)
ym = y - y.min()
dst = (ym / ym.max()) * 255
return dst.astype(np.uint8)
img = cv2.imread('./butterfly.png', 0)
dst = log(img)
cv2.imshow('img', np.hstack((img, dst)))
cv2.waitKey()
cv2.destroyAllWindows()
import numpy as np
import cv2
def linear_transform(img):
height, width = img.shape[:2]
r1, s1 = 80, 10
r2, s2 = 140, 200
k1 = s1 / r1 # 第一段斜率
k2 = (s2 - s1) / (r2 - r1) # 第二段斜率
k3 = (255 - s2) / (255 - r2) # 第三段斜率
img_copy = np.zeros_like(img)
for i in range(height):
for j in range(width):
if img[i, j] < r1:
img_copy[i, j] = k1 * img[i, j]
elif r1 <= img[i, j] <= r2:
img_copy[i, j] = k2 * (img[i, j] - r1) + s1
else:
img_copy[i, j] = k3 * (img[i, j] - r2) + s2
return img_copy
img = cv2.imread('./img.png', 0)
ret = linear_transform(img)
cv2.imshow('img', np.hstack((img, ret)))
cv2.waitKey()
cv2.destroyAllWindows()
灰度切割:增强特定范围的对比度,突出图像中特定范围的亮度
灰度切割的特殊使用:阈值处理
将感兴趣的物体从背景中分离出来,也叫二值化处理,是第一种方法的变体
import cv2
import numpy as np
def transform1(x):
a, b = 150, 240 # 定义两个阈值,中间部分变换为255
dst = x.copy()
dst[(x[:, :] >= a) & (x[:, :] <= b)] = 255 # 中间变换为255
dst[(x[:, :] < a) | (x[:, :] > b)] = 0 # 其余的变换为0
return dst
def transform2(x):
a, b = 150, 240 # 定义两个阈值,中间部分变换为255
dst = x.copy()
dst[(x[:, :] >= a) & (x[:, :] <= b)] = 255 # 中间变换255,其余的不变
return dst
gray = cv2.imread('./img.png', 0)
dst1 = transform1(gray)
dst2 = transform2(gray)
hh=np.hstack((gray, dst1, dst2))
cv2.imshow('img', hh)
cv2.imwrite('./image.png',hh)
cv2.waitKey()
cv2.destroyAllWindows()
import cv2
import numpy as np
a = np.arange(0, 256).reshape(1, -1).astype(np.uint8) # 0-255
img = cv2.resize(a, (800, 100), interpolation=cv2.INTER_AREA) # 创建渐变图像
"""
cv2.THRESH_BINARY 二值化阈值处理:超出thresh,为255;否则为0
cv2.THRESH_BINARY_INV 反二值化阈值处理:超出thresh,为0;否则为255
cv2.THRESH_TOZERO 低于阈值零处理:低于thresh,为0;否则灰度值不变
cv2.THRESH_TOZERO_INV 超出阈值零处理:低于thresh,为255;否则为0
cv2.THRESH_TRUNC(truncate截断) 截断阈值处理:超过thresh,为thresh;否则不变
"""
ret1, img1 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY) # 二值化阈值处理
ret2, img2 = cv2.threshold(img, 100, 255, cv2.THRESH_BINARY_INV) # 反二值化阈值处理
ret3, img3 = cv2.threshold(img, 100, 255, cv2.THRESH_TOZERO) # 低于阈值零处理
ret4, img4 = cv2.threshold(img, 100, 255, cv2.THRESH_TOZERO_INV) # 超出阈值零处理
ret5, img5 = cv2.threshold(img, 100, 255, cv2.THRESH_TRUNC) # 截断阈值处理
hh=np.vstack((img, img1, img2, img3, img4, img5))
print('ret1',ret1)
print('ret2',ret2)
print('ret3',ret3)
print('ret4',ret4)
print('ret5',ret5)
cv2.imshow('img', hh)
cv2.imwrite('./image.png',hh)
cv2.waitKey()
cv2.destroyAllWindows()
参考文献:
灰度变换 - 灰度切割(灰度级分层)+threshold函数_Henry_zs的博客-CSDN博客_灰度切割