opencv之图像亮度变换和形态学变换(八)

opencv之图像亮度变换和形态学变换(八)

文章目录

  • opencv之图像亮度变换和形态学变换(八)
  • 一、图像亮度变换
    • [1.1 亮度变换](#1.1 亮度变换)
    • [1.2 线性变换](#1.2 线性变换)
    • [1.3 直接像素值修改](#1.3 直接像素值修改)
    • 案例
  • 二、形态学变换
    • [2.1 核](#2.1 核)
    • [**2.2 腐蚀(Erosion)**](#2.2 腐蚀(Erosion))
    • [**2.3 膨胀(Dilation)**](#2.3 膨胀(Dilation))
    • [**2.4 开运算(Opening)**](#2.4 开运算(Opening))
    • [**2.5 闭运算(Closing)**](#2.5 闭运算(Closing))
    • [**2.6 礼帽运算(Top Hat)**](#2.6 礼帽运算(Top Hat))
    • [**2.7 黑帽运算(Black Hat)**](#2.7 黑帽运算(Black Hat))
    • [**2.8 形态学梯度(Morphological Gradient)**](#2.8 形态学梯度(Morphological Gradient))
    • **核心总结**
    • 案例

一、图像亮度变换

1.1 亮度变换

在讲解亮度时,需要和对比度一起来进行解释。

对比度调整:图像暗处像素强度变低,图像亮处像素强度变高,从而拉大中间某个区域范围的显示精度。

亮度调整:图像像素强度整体变高或者变低。

上图中,(a)把亮度调高,就是图片中的所有像素值加上了一个固定值;(b)把亮度调低,就是图片中的所有像素值减去了一个固定值;©增大像素对比度(白的地方更白,黑的地方更黑);(d)减小像素对比度(整幅图都趋于一个颜色);

OpenCV调整图像对比度和亮度时,公式为: g ( i , j ) = α f ( i , j ) + β g(i,j)=\alpha f(i,j)+\beta g(i,j)=αf(i,j)+β。但是不能浅显的讲 α \alpha α是控制对比度, β \beta β是控制亮度的。

对比度:需要通过 α 、 β \alpha、\beta α、β一起控制。

亮度:通过 β \beta β控制。

1.2 线性变换

使用 cv2.addWeighted() 函数,可以对图像的像素值进行加权平均,进而改变图像的整体亮度。亮度增益可以通过向每个像素值添加一个正值来实现。

cv2.addWeighted(src1, alpha, src2, beta, gamma)

  • src1:第一张输入图像,它将被赋予权重 alpha

  • alpha:第一个输入图像的权重。

  • src2:第二张输入图像,它将被赋予权重 beta

  • beta:第二个输入图像的权重。

  • gamma:一个标量,将被添加到权重求和的结果上,可用于调整总体亮度。

    计算公式为: dst = src1 * alpha + src2 * beta + gamma

1.3 直接像素值修改

如果只需要增加或减少固定的亮度值,可以直接遍历图像像素并对每个像素值进行加减操作。

使用的API:

numpy.clip(a, a_min, a_max)

用于对数组中的元素进行限定,将超出指定范围的元素值截断至指定的最小值和最大值之间

  • a:输入数组。

  • a_min:指定的最小值,数组中所有小于 a_min 的元素将被替换为 a_min

  • a_max:指定的最大值,数组中所有大于 a_max 的元素将被替换为 a_max

案例

案例一

py 复制代码
import numpy as np
import cv2 as cv

img = cv.imread("images/1.jpg")
# 使用cv2.addWeihted(src1, alpha, src2, beta, gamma)实现线性变换
"""
np.zeros_like(img) 生成与img相同形状的零矩阵
np.ones_like(img) 生成与img相同形状的1矩阵
np.full_like(img, n) 生成与img相同形状的n矩阵
"""
dst = cv.addWeighted(img, 1, np.zeros_like(img), 0, 50)

cv.imshow("dst", dst)
cv.imshow("img", img)
cv.waitKey(0)
cv.destroyAllWindows()

案例二

py 复制代码
import cv2 as cv
import numpy as np

window_name = 'Trackbar'
cv.namedWindow(window_name)

# 写一个改变图像亮度的方法
def change(p):
    img = cv.imread('images/1.jpg')
    if img is None:
        print("图像加载失败,请检查路径!")
        return
    # 把滑条范围映射到-255~255
    p = int(p)  # 确保 p 是整数
    p = p / 255 * (255 - (-255)) - 255
    # 亮度变换
    dst = np.uint8(img + p)
    dst = np.clip(dst, 0, 255)
    cv.imshow(window_name, dst)

# 创建滑条
cv.createTrackbar('p', 'Trackbar', 0, 255, change)

# 初始化显示
change(0)  # 初始化时调用一次,确保图像显示

cv.waitKey(0)
cv.destroyAllWindows()

二、形态学变换

形态学变换(Morphological Transformations)是一种基于形状的简单变换,它的处理对象通常是二值化图像。形态学变换有两个输入,一个输出:输入为原图像、核(结构化元素),输出为形态学变换后的图像。其基本操作有腐蚀和膨胀,这两种操作是相反的,即较亮的像素会被腐蚀和膨胀。下面我们来说一下核、腐蚀与膨胀的概念。

2.1 核

自适应二值化中,我们已经接触过核了,还记得吗?就是那个在原图中不断滑动计算的3*3的小区域,那其实就是一个3*3的核。

核(kernel)其实就是一个小区域,通常为3*3、5*5、7*7大小,有着其自己的结构,比如矩形结构、椭圆结构、十字形结构,如下图所示。通过不同的结构可以对不同特征的图像进行形态学操作的处理。

2.2 腐蚀(Erosion)

  • 作用:收缩白色区域(前景),消除小噪点、细线
  • 原理 :结构元素覆盖区域内有黑即黑(取最小值)
  • 效果:目标"变瘦",边缘平滑

2.3 膨胀(Dilation)

  • 作用:扩展白色区域,填补空洞、断裂
  • 原理 :结构元素覆盖区域内有白即白(取最大值)
  • 效果:目标"变胖",轮廓连通

2.4 开运算(Opening)

  • 操作:先腐蚀后膨胀
  • 作用:消除孤立噪点、分离粘连物体
  • 特点:保留原主体,去除小干扰

2.5 闭运算(Closing)

  • 操作:先膨胀后腐蚀
  • 作用:填充内部孔洞、闭合缝隙
  • 特点:平滑轮廓,保持主体完整性

2.6 礼帽运算(Top Hat)

  • 公式:原图 - 开运算结果
  • 作用:提取比背景亮的细节(如微小亮斑)
  • 应用:背景均匀时的前景增强

2.7 黑帽运算(Black Hat)

  • 公式:闭运算结果 - 原图
  • 作用:提取比背景暗的细节(如暗色缺陷)
  • 应用:检测深色区域或空洞

2.8 形态学梯度(Morphological Gradient)

  • 公式:膨胀图 - 腐蚀图
  • 作用:突出边缘轮廓
  • 效果:类似边缘检测,但更平滑

核心总结

操作 关键作用 典型应用场景
腐蚀 消除噪点、细化物体 去除胡椒噪声
膨胀 连接断裂、填充孔洞 文字修复
开运算 去噪+保形 分离粘连细胞
闭运算 补洞+平滑 填充指纹断裂
礼帽 提取亮细节 显微图像亮斑提取
黑帽 提取暗细节 工业缺陷检测
形态学梯度 边缘增强 目标轮廓提取

:所有操作均依赖**结构元素(核)**的形状和大小选择!

案例

案例一:腐蚀和膨胀

py 复制代码
import cv2 as cv
import numpy as np

long = cv.imread("images/long.png")
# 定义一个5×5的卷积核
kernel = np.ones((5,5),np.uint8)
# 腐蚀操作cv.erode(src, kernel, dst, anchor, iterations, borderType, borderValue)
# iterations表示迭代次数
dst_erode = cv.erode(long,kernel,iterations=1)

# 膨胀操作cv.dilate(src, kernel, dst, anchor, iterations, borderType, borderValue)
dst_dilate = cv.dilate(long,kernel,iterations=5)

cv.imshow("long",long)
cv.imshow("dst_erode",dst_erode)
cv.imshow("dst_dilate",dst_dilate)
cv.waitKey(0)
cv.destroyAllWindows()

案例二

py 复制代码
import cv2 as cv
import numpy as np

car = cv.imread("images/car4.png")
car = cv.resize(car,(640,480))
# 定义一个5×5的卷积核
kernel = np.ones((5,5),np.uint8)
# 开运算 cv.morphologyEx(src,op,kernel) # 先腐蚀再膨胀
open = cv.morphologyEx(car,cv.MORPH_OPEN,kernel)
# 闭运算 cv.morphologyEx(src,op,kernel) # 先膨胀再腐蚀
close = cv.morphologyEx(car,cv.MORPH_CLOSE,kernel)

# 显示图像
cv.imshow("car",car)
cv.imshow("open",open)
cv.imshow("close",close)
cv.waitKey(0)
cv.destroyAllWindows()

案例三

py 复制代码
import cv2 as cv
import numpy as np

car = cv.imread("images/car4.png")
car = cv.resize(car,(640,480))
# 定义一个5×5的卷积核
kernel = np.ones((5,5),np.uint8)
# 礼帽运算cv.morphologyEx(src,op,kernel) 原图减"开运算"
dst_top = cv.morphologyEx(car,cv.MORPH_TOPHAT,kernel)

# 黑帽运算cv.morphologyEx(src,op,kernel) "闭运算"的结果图与原图像之差
dst_black = cv.morphologyEx(car,cv.MORPH_BLACKHAT,kernel)

cv.imshow("car",car)
cv.imshow("dst_top",dst_top)
cv.imshow("dst_black",dst_black)
cv.waitKey(0)
cv.destroyAllWindows()

案例四

py 复制代码
import cv2 as cv
import numpy as np

car = cv.imread("images/car4.png")
car = cv.resize(car,(640,480))
# 定义一个5×5的卷积核
kernel = np.ones((5,5),np.uint8)
# 形态学梯度 cv2.morphologyEx(src,op,kernel) 像素点在膨胀后的图像值与其在腐蚀后的图像值之差
gradient = cv.morphologyEx(car,cv.MORPH_GRADIENT,kernel)
cv.imshow("gradient",gradient)
cv.imshow("car",car)
cv.waitKey(0)
cv.destroyAllWindows()
相关推荐
当当狸6 分钟前
当当狸智能天文望远镜 TW2 | 用科技触摸星辰,让探索触手可及
人工智能·科技·内容运营
geneculture7 分钟前
金融的本质是智融、融资的实质是融智、投资的关键是投智,颠覆传统金融学的物质资本中心论,构建了以智力资本为核心的新范式
大数据·人工智能·算法·金融·系统工程融智学
极小狐9 分钟前
极狐Gitlab 如何创建并使用子群组?
数据库·人工智能·git·机器学习·gitlab
jndingxin3 小时前
OpenCV 图形API(78)图像与通道拼接函数-----调整图像大小的函数resize()
opencv
MonkeyKing_sunyuhua6 小时前
6.5 行业特定应用:金融、医疗、制造等行业的定制化解决方案
人工智能·agent
god_Zeo6 小时前
从头训练小模型: 4 lora 微调
人工智能·机器学习
开心的AI频道7 小时前
GPT-4o 图像生成与八个示例指南
人工智能
%d%d27 小时前
RuntimeError: CUDA error: __global__ function call is not configured
人工智能·深度学习·机器学习
白熊1887 小时前
【计算机视觉】pyrealsense2:Intel RealSense 深度相机的 Python 接口实战指南
python·数码相机·计算机视觉
阿维的博客日记7 小时前
ϵ-prediction和z0-prediction是什么意思
人工智能·深度学习·机器学习