图像灰度变换

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

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

结果如下图所示:

相关推荐
一点一木2 小时前
深度体验TRAE SOLO移动端7天:作为独立开发者,我把工作流揣进了兜里
前端·人工智能·trae
Lee川3 小时前
mini-cursor 揭秘:从 Tool 定义到 Agent 循环的完整实现
前端·人工智能·后端
weelinking4 小时前
【产品】00_产品经理用Claude实现产品系列介绍
数据库·人工智能·sql·数据挖掘·github·产品经理
Agent产品评测局4 小时前
制造业模具管理AI系统,主流产品能力对比详解:2026年智能制造选型深度洞察
人工智能·ai·chatgpt·制造
研华科技Advantech4 小时前
如何用一套实训设备,打通工业AI预测性维护技术全流程?
人工智能
Lab_AI4 小时前
AI for Science: MaXFlow AI Agent+ 报告体验双升级,让AI智能体更高效易用!
人工智能·ai for science·ai agent·ai智能体
李坤5 小时前
让 Codex 和 Claude 互相 Review:告别手动复制
人工智能·openai·claude
南屹川5 小时前
【API设计】GraphQL实战:从REST到GraphQL的演进
人工智能
KJ_BioMed5 小时前
当计算生物学遇上生成式AI:从头设计生物分子的“新范式”初探
人工智能·从头设计·生命科学·生物医药·科研干货·科晶生物
明月醉窗台5 小时前
深度学习(17)YOLO训练中的超参数详解
人工智能·深度学习·yolo