python 灰度变换

伽马变换

图像中最高和最低灰度级之间的灰度差为对比度。

伽马变换主要目的是对比度拉伸,将图像灰度较低的部分进行修正

伽马变换针对的是对单个像素点的变换,也就是点对点的映射

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()

python 灰度变换_第1张图片

阈值处理

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()

python 灰度变换_第2张图片

 

参考文献:

灰度变换 - 灰度切割(灰度级分层)+threshold函数_Henry_zs的博客-CSDN博客_灰度切割

你可能感兴趣的:(python)