图像灰度变换

灰度变换是数字图像处理中一项基础且关键的技术,它通过特定的规则独立地改变图像中每个像素的灰度值,以达到改善图像质量的目的。其主要作用有:改善图像中质量,调整图像对比度,兴趣区域突出,显示校正等。

1.灰度线性变换.

全局调整图像的对比度和亮度。用于解决曝光不足或过度的图像矫正。通过一个线性函数 g(x,y) = alpha * f(x,y) + beta全局调整图像像素值。

python 复制代码
def linear_transform(image_path, alpha=1.5, beta=50):
	"""
	对图像进行线性变换
	:param image_path: 图像路径
	:param alpha: 对比度系数 (>1增强对比度, <1减弱对比度)
	:param beta: 亮度调整量
	:return: 变换后的图像
	"""
	# 读取图像,0表示以灰度模式读取
	img = cv2.imread(image_path, 0)
	if img is None:
		print("错误:无法加载图像,请检查路径是否正确")
		return None

	# 进行线性变换并确保像素值在0-255之间
	transformed_img = np.clip(alpha * img + beta, 0, 255).astype(np.uint8)

	# 显示结果
	cv2.imshow('Original Image', img)
	cv2.imshow('Linear Transformed Image', transformed_img)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

	return transformed_img


# 使用示例
linear_transform('D:\\photo\\lena.tif', alpha=1.5, beta=20)

2.图像分段线性变换。

指对不同灰度区间采用不同的线性变换,从而有针对性地增强图像特定部分。

python 复制代码
def piecewise_linear_transform(image_path, points):
	"""
	分段线性变换
	:param image_path: 图像路径
	:param points: 分段点列表,格式为 [(r1, s1), (r2, s2), ...]
	:return: 变换后的图像
	"""
	img = cv2.imread(image_path, 0)
	if img is None:
		print("错误:无法加载图像")
		return None

	# 创建查找表(LUT),提高运算效率[6](@ref)
	lut = np.zeros(256, dtype=np.uint8)
	points = sorted(points)  # 按输入灰度值排序
	points = [(0, 0)] + points + [(255, 255)]  # 确保覆盖整个0-255范围

	for i in range(len(points) - 1):
		r1, s1 = points[i]
		r2, s2 = points[i + 1]
		# 对每个区间进行线性变换
		if r1 != r2:
			k = (s2 - s1) / (r2 - r1)
			for r in range(r1, r2 + 1):
				lut[r] = np.clip(s1 + k * (r - r1), 0, 255)

	transformed_img = cv2.LUT(img, lut)  # 应用查找表

	cv2.imshow('Original', img)
	cv2.imshow('Piecewise Linear', transformed_img)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

	return transformed_img


# 使用示例:突出中间灰度区域(50-150),将其拉伸到0-255
piecewise_linear_transform('D:\\photo\\lena.tif', [(50, 0), (150, 255)])

3. 直方图均衡化。

将图像的直方图分布拉伸得更加均匀,有效增强图像整体对比度,尤其适用于灰度集中在一个狭窄范围的图像。

python 复制代码
def histogram_equalization(image_path):
    """
    直方图均衡化
    :param image_path: 图像路径
    """
    img = cv2.imread(image_path, 0)
    if img is None:
        print("错误:无法加载图像")
        return

    # 使用OpenCV内置函数进行直方图均衡化[10,11](@ref)
    equalized_img = cv2.equalizeHist(img)
    
    # 显示原图与均衡化后的图像及其直方图
    plt.figure(figsize=(10, 8))
    
    plt.subplot(2, 2, 1)
    plt.imshow(img, cmap='gray')
    plt.title('Original Image')
    
    plt.subplot(2, 2, 2)
    plt.imshow(equalized_img, cmap='gray')
    plt.title('Equalized Image')
    
    plt.subplot(2, 2, 3)
    plt.hist(img.ravel(), 256, [0, 256])
    plt.title('Original Histogram')
    
    plt.subplot(2, 2, 4)
    plt.hist(equalized_img.ravel(), 256, [0, 256])
    plt.title('Equalized Histogram')
    
    plt.tight_layout()
    plt.show()

# 使用示例
histogram_equalization('your_image.jpg')

4. 灰度级分层。

将特定灰度区间内的像素值设置为最大值(如白色),其他区域保持不变,用于突出显示图像中的特定目标。

python 复制代码
def gray_level_slicing(image_path, r_left=100, r_right=200, highlight_max=255):
    """
    灰度级分层:突出显示特定灰度范围
    :param image_path: 图像路径
    :param r_left: 目标灰度区间下限
    :param r_right: 目标灰度区间上限
    :param highlight_max: 突出显示的灰度值(通常为255,白色)
    :return: 变换后的图像
    """
    img = cv2.imread(image_path, 0)
    if img is None:
        print("错误:无法加载图像")
        return None

    # 创建与原始图像相同尺寸的输出图像
    result_img = np.zeros_like(img)
    
    # 遍历每个像素,进行分层处理
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            if r_left <= img[i, j] <= r_right:
                result_img[i, j] = highlight_max  # 在目标区间内,置为突出值(如白色)
            else:
                result_img[i, j] = img[i, j]      # 不在目标区间,保留原值[3](@ref)
    
    cv2.imshow('Original Image', img)
    cv2.imshow('Gray Level Slicing Result', result_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    return result_img

# 使用示例:突出灰度值在100到200之间的区域
gray_level_slicing('your_image.jpg', r_left=100, r_right=200)

5. 阈值处理。

将灰度图像转换为黑白二值图像,常用于图像分割和轮廓提取。

python 复制代码
import cv2
import numpy as np


def threshold_processing(image_path, thresh=127, maxval=255, mode=cv2.THRESH_BINARY):
	"""
	图像阈值处理
	:param image_path: 图像路径
	:param thresh: 阈值
	:param maxval: 超过阈值时赋予的新值
	:param mode: 阈值化类型,如cv2.THRESH_BINARY(最常用)[4](@ref)
	:return: 二值化后的图像
	"""
	img = cv2.imread(image_path, 0)
	if img is None:
		print("错误:无法加载图像")
		return None

	# 应用阈值处理[4](@ref)
	_, binary_img = cv2.threshold(img, thresh, maxval, mode)

	cv2.imshow('Original Image', img)
	cv2.imshow('Binary Image', binary_img)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

	return binary_img


# 使用示例
threshold_processing('your_image.jpg', thresh=127)


# 自适应阈值处理(适合光照不均的图像)[4](@ref)
def adaptive_threshold_processing(image_path):
	img = cv2.imread(image_path, 0)
	if img is None:
		print("错误:无法加载图像")
		return None

	# 自适应阈值处理,根据图像局部区域亮度动态确定阈值[4](@ref)
	adaptive_binary = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
	                                        cv2.THRESH_BINARY, 11, 2)

	cv2.imshow('Original', img)
	cv2.imshow('Adaptive Binary', adaptive_binary)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

	return adaptive_binary


# 使用自适应阈值
adaptive_threshold_processing('D:\\photo\\bf.jpg')

结果如下图所示:

相关推荐
AI导出鸭PC端16 小时前
智谱清言怎么生成word文档?AI导出鸭终结乱码烦恼
人工智能·ai·c#·word·豆包·ai导出鸭
格桑阿sir16 小时前
17-大模型智能体开发工程师:深入学习Agent记忆系统
人工智能·记忆存储·记忆系统·agent记忆·嵌入式数据库·agent进化·记忆检索
数据仓库搬砖人16 小时前
LangGraph 原理深度解析:为什么它是目前最适合构建 Agent 的框架
人工智能
孟陬16 小时前
国外技术周刊 #139:LLM 正在杀死程序员的「懒惰美德」
前端·人工智能·后端
Peter·Pan爱编程16 小时前
23. 算法库:用算法代替手写循环
c++·人工智能·算法
Nile16 小时前
Claude Code-Dynamic Workflows:1.为什么用工作流?
人工智能·ai·ai编程·ai-native
狂炫冰美式16 小时前
AI 生成 Draw.io,导入飞书/Lark 画板后可编辑
前端·人工智能·后端
我最爱吃鱼香茄子16 小时前
终极方案:JetBrains IDE永久解放C盘空间
计算机视觉·性能优化·电脑·笔记本电脑·intellij-idea·程序员创富·webstorm
战族狼魂16 小时前
从零构建企业级Hermes-Agent:复杂任务拆解、工具协同与安全落地实践
开发语言·人工智能·python
o561-6o623o7鹿16 小时前
陈,生理实验系统虚实结合型 生理学实验系统 生理学实验系统软件
人工智能