数字图像基础操作(基于opencv)

一.数字图像基本定义

一幅单通道灰度图像定义为一个二元连续函数f(x,y),其中各分量x和y是对应的平面坐标。对于这样的空间曲面函数,在任意位置(x,y)处的函数值就是单通道数字图像在该点处的灰度值或者强度值。当x,y和f(x,y)都是有限的离散量时,就是数字图像。简单来说,数字图像是由二维离散像素点组成的,每个像素点都具有特定的颜色和亮度值。

数字图像根据颜色信息(通道数)可以分为:

  1. 灰度数字图像:每个像素点只有一个亮度值(强度值),通常是0到255之间的整数,其中0代表黑色,255代表白色,中间的值则表示不同的灰度级别。
  2. 彩色数字图像:每个像素点由多个通道(通常为红色、绿色和蓝色,即RGB)组成,每个通道分别存储不同颜色的强度值,通过混合不同的颜色通道来表示各种颜色。

二.数字图像读取操作

1. 读取

cv2.imread是 OpenCV 库中的一个函数,用于从文件中读取图像,并将其加载为一个 NumPy 数组。这个函数能够加载不同格式的图像,如 JPEG、PNG、BMP 等。返回值是一个多维 NumPy 数组,表示读取到的图像。如果加载失败,函数将返回None。

cv2.imread(filename, flags)
"""
filename:字符串类型,表示要读取的图像文件的路径。可以是相对路径或绝对路径
flags:整数类型,可选参数,用于指定图像的读取方式
常用的读取方式:
cv2.IMREAD_COLOR(彩色图像)
cv2.IMREAD_GRAYSCALE(灰度图像)
cv2.IMREAD_UNCHANGED(保持原始通道数)

"""

使用opencv的库函数cv2.imread()进行图像读取

image_grey = cv2.imread(r'D:\pythonwork\imagepro\data\Fig0001.tif', cv2.IMREAD_GRAYSCALE)

读取结果:

c4c1c08dd9254ba29268bdf86d2731f5.png

2. 可视化(matplotlib+opencv)

cv2.imshow()是 OpenCV 库中用于在交互式窗口中显示图像的库函数。它创建一个窗口并显示指定的图像,可以用于在计算机视觉任务中检查和可视化处理后的图像。

cv2.imshow(winname, mat)
"""
winname:字符串类型,表示窗口的名称。它指定将要显示的窗口的名称,并且此名称也是窗口的标识符。如果多个窗口被创建,每个窗口都需要一个唯一的名称
mat:要显示的图像,即 NumPy 数组。通常由 cv2.imread() 读取的图像或其他处理后的图像。这是一个二维或三维数组,表示要显示的图像。图像可以是彩色图像(RBG)或者灰度图像
"""

 使用opencv的库函数cv2.imshow()进行图像可视化

"""
cv2.waitKey(delay)用于暂停程序并等待用户输入的按键,单位为毫秒。如果 delay 为 0,则会无限期等待,直到用户按下键盘上的任意键才会继续
cv2.destroyAllWindows()用于关闭所有通过 cv2.imshow() 打开的窗口。通常在程序结束时调用该函数,以确保释放系统资源并关闭所有窗口。特定的几毫秒之内,如果按下任意键,这个函数会返回按键的 ASCII 码值,程序将会继续运行。如果没有键盘输入,返回值为 -1,如果我们设置这个函数的参数为 0,那它将会无限
期的等待键盘输入。它也可以被用来检测特定键是否被按下。
"""
cv2.imshow('Image show', image_grey)
cv2.waitKey(0)
cv2.destroyAllWindows()

可视化结果:

b96b2336f7624b91b8f4a5119c6de065.png

plt.figure()
plt.title('Grayscale Image')  # 添加标题
plt.imshow(image_grey, cmap='gray')

可视化结果:

ff61a8dc90eb489bb22580dde979c891.png

3. 保存图像

cv2.imwrite()是 OpenCV 中用于将图像保存到文件的函数。它能够将处理后的图像存储为指定的文件格式(如 PNG、JPEG 等),并且可以设置压缩质量等参数。

cv2.imwrite(filename, img, params=None)
"""
filename:字符串类型,表示图像要保存的文件路径和名称。需要包含文件的扩展名,如.jpg, .png等,这决定了图像将以何种格式保存
img:要保存的图像,即 NumPy 数组。通常是由cv2.imread()读取处理后的数组数据
params:保存时的可选参数列表。此参数取决于图像的格式,可以用来指定压缩比或图像质量等
"""

三.数字图像基础操作

1. 读取和修改像素值

在 OpenCV 中,可以通过直接访问图像的 NumPy 数组元素来获取特定像素的值。利用cv2.imread读取的图像数据是numpy数组格式,因此可以通过数组索引获取离散像素点的二维位置坐标。

Numpy 是经过优化了的进行快速矩阵运算的扩展库。所以并不不推荐逐个获取像素值并修改,这样会很慢,能利用矩阵运算就不要用循环。

px=image_grey[1,9]
print(px)
# 160

image_grey[1,9] = 255
print(image_grey[1,9])
# 255

彩色图像每个像素由三个通道(BGR:蓝色、绿色、红色)组成,返回的是一个包含三个元素的数组,分别代表该像素的 B、G、R 值。

2. 获取图像属性

在 OpenCV 中,读取图像后,可以获取多种图像属性。这些属性提供了有关图像的尺寸、颜色通道、数据类型等关键信息,帮助我们更好地理解和处理图像。常见的获取图像属性的方法通常涉及图像的 NumPy 数组。

  1. 图像的形状属性可以通过shape获取,它返回一个包含图像维度的元组。对于彩色图像,返回(height, width, channels) ;对于灰度图像,返回(height, width);
  2. size属性返回图像中像素的总数,即height*width*channels。对于灰度图像,它仅为height*width;
  3. dtype属性返回图像中每个像素的元素类型。通常情况下,OpenCV 读取的图像像素类型是 uint8(无符号8位整数),即每个像素值的范围是0-255;
  4. 对于彩色图像,可以通过shape[-1]获取通道数,即图像的颜色深度。彩色图像通常有 3 个通道(BGR),而灰度图像只有 1 个通道;
  5. 可以使用min()和max()函数来获取图像中像素值的最小值和最大值,这个在图像对比度分析中非常重要;
  6. 对于彩色图像,可以使用cv2.split()将图像的 B、G、R 三个通道拆分为单独的数组;
  7. 位深度表示每个通道中用多少位来表示像素值;
  8. 在 OpenCV 中,图像的颜色通道默认顺序是 BGR(蓝、绿、红),而不是 RGB(红、绿、蓝)。因此,当你从 OpenCV 读取图像并使用其他库(如matplotlib)显示时,可能需要转换颜色通道;
  9. 可以检查图像的类型,例如是否是彩色图像、灰度图像等。

height, width, channels = image_brg.shape   # 获取图像尺寸
print(f"高度: {height}, 宽度: {width}, 通道数: {channels}")

total_pixels = image_brg.size   # 获取图像像素总数
print(f"像素总数: {total_pixels}")

data_type = image_brg.dtype   # 图像的数据类型
print(f"图像的数据类型: {data_type}")

channels = image_brg.shape[-1]   # 通道数
print(f"图像的通道数: {channels}")

b, g, r = cv2.split(image_brg)   # 拆分颜色通道
print(f"蓝色通道形状: {b.shape}, 绿色通道形状: {g.shape}, 红色通道形状: {r.shape}")

bit_depth = image_brg.dtype.itemsize * 8   # 位深度
print(f"图像的位深度: {bit_depth} 位")

if len(image_brg.shape) == 3:  # 判断彩色图像还是灰度图
    print("这是一个彩色图像")
else:
    print("这是一个灰度图像")

image_brg[:,:,-1] = 0   # 令r通道的像素值都为0
cv2.imshow('Image show', image_brg)
cv2.waitKey(0)
cv2.destroyAllWindows() 

运行结果:

15c49d645f074319a7f0fa0bf89f1647.png

                           

6ba3f4958f9f4788a23ba8af8d0538f3.png

9624f76722864d4ab10e8a3f686611d3.png

 获取图像属性是图像处理的基础步骤,帮助我们了解图像的尺寸、数据类型、通道数和像素值等信息,为后期更复杂的图像处理做铺垫。

3. 图像填充

图像填充是指在图像的边缘添加额外的像素,以增加图像的尺寸。填充可以在图像的四个边界上增加像素行或列,并可以填充特定的颜色或根据不同的策略来填充这些新增像素。

  1. 常数填充(cv2.BORDER_CONSTANT):用固定值填充图像边界;
  2. 复制边缘(cv2.BORDER_REPLICATE):用图像边缘的像素值填充;
  3. 反射填充(cv2.BORDER_REFLECT):边界元素的镜像;
  4. 反射101填充(cv2.BORDER_REFLECT_101):与反射填充类似,但是不包含边界元素;
  5. 包裹填充(cv2.BORDER_WRAP):像素值从对立边界包裹到填充区域。

这些填充函数可以接受的主要参数有:需填充操作的图片、在图像四个边添加的像素行列数和相对应的填充类型。

cons_image = cv2.copyMakeBorder(image_brg, 30, 30, 30, 30, cv2.BORDER_CONSTANT, value=[0, 0, 0])
rep_image = cv2.copyMakeBorder(image_brg, 30, 30, 30, 30, cv2.BORDER_REPLICATE)
ref_image = cv2.copyMakeBorder(image_brg, 30, 30, 30, 30, cv2.BORDER_REFLECT)
p101_image = cv2.copyMakeBorder(image_brg, 30, 30, 30, 30, cv2.BORDER_REFLECT_101)
wrap_image = cv2.copyMakeBorder(image_brg, 50, 50, 50, 50, cv2.BORDER_WRAP)

76ab631811a9489783b617171d846543.png

4. 对应元素运算

涉及一幅或者多幅图像的对应元素运算是逐个像素进行的,类似于矩阵的哈达玛积。图片的对应元素运算常用的应用就是掩膜(mask)操作。

40c624acc48649cc9be74b6035dc78e7.png

height, width, channels = image_brg.shape
mask = np.ones((height, width, 3), dtype=np.uint8)
center_x, center_y = width // 2, height // 2
mask[center_y-50:center_y+50, center_x-50:center_x+50, :] = 0  # 定义中心 200x200 的掩膜
# 对掩膜区域进行逐元素乘法计算
masked_image = cv2.multiply(image_brg, mask)

 5. 基础矩阵运算

矩阵加法,可以使用numpy直接进行数值矩阵相加,但是要保证两个加数的尺寸(长 宽 通道数)一致。

img = image_grey+image_2

31b7bb02ebac4eeaad14a6cd10394ad6.png

 图像混合操作,与图像加法类似,区别在于赋予两幅不同的权重:

eq?g%28x%29%3D%281-%5Calpha%20%29f_%7B1%7D%28x%29+%5Calpha%20f_%7B2%7D%28x%29

mixed_img=cv2.addWeighted(image_grey,0.7,image_2,0.3,0)
plt.imshow(mixed_img)
plt.title('Mixed')
plt.axis('off')

df412e6425924f17a32e338ed0199211.png

a881aa3bf59a4b34bd8cf9c8ddae49a0.png

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值