OpenCV 4基础篇| OpenCV图像基本操作

2024-02-25 10:09:28 浏览数 (2)

1. 图像读取

1.1 cv2.imread() 不能读取中文路径和中文名称

语法结构:

代码语言:javascript复制
retval = cv.imread(filename[, flags]) #用于从指定的文件读取图像
  • filename:读取图像的文件路径和文件名
  • flags:读取图片的方式,可选项:
    • cv2.IMREAD_COLOR(1):始终将图像转换为 3 通道BGR彩色图像,默认方式
    • cv2.IMREAD_GRAYSCALE(0):始终将图像转换为单通道灰度图像
    • cv2.IMREAD_UNCHANGED(-1):按原样返回加载的图像(使用Alpha通道)
    • cv2.IMREAD_ANYDEPTH(2):在输入具有相应深度时返回16位/ 32位图像,否则将其转换为8位
    • cv2.IMREAD_ANYCOLOR(4):以任何可能的颜色格式读取图像
  • retval:读取的 OpenCV 图像,nparray 多维数组

注意事项:

  • OpenCV 读取图像文件,返回值是一个nparray 多维数组。OpenCV 对图像的任何操作,本质上就是对 Numpy 多维数组的运算。
  • OpenCV 中彩色图像使用 BGR 格式,而 PIL、PyQt、matplotlib 等库使用的是 RGB 格式。
  • cv2.imread() 如果无法从指定文件读取图像,并不会报错,而是数返回一个空矩阵。
  • cv2.imread() 指定图片的存储路径和文件名,在 python 中不支持中文和空格(但并不会报错)。必须使用中文时,可以使用 cv2.imdecode() 处理。
  • cv2.imread() 读取图像时默认忽略透明通道,但可以使用 CV_LOAD_IMAGE_UNCHANGED 参数读取透明通道。
  • 对于彩色图像,可以使用 flags=0 按照读取为灰度图像。

1.2 cv2.imdecode() 可以读取中文路径和中文名称

语法结构:

代码语言:javascript复制
retval = cv2.imdecode(buf, flags) #用于从内存中读取图像
  • buf:字节数组,其中包含要解码的图像数据。
  • flags:读取图片的方式,可选项:
    • cv2.IMREAD_COLOR(1):始终将图像转换为 3 通道BGR彩色图像,默认方式
    • cv2.IMREAD_GRAYSCALE(0):始终将图像转换为单通道灰度图像
    • cv2.IMREAD_UNCHANGED(-1):按原样返回加载的图像(使用Alpha通道)
    • cv2.IMREAD_ANYDEPTH(2):在输入具有相应深度时返回16位/ 32位图像,否则将其转换为8位
    • cv2.IMREAD_ANYCOLOR(4):以任何可能的颜色格式读取图像
  • retval:读取的 OpenCV 图像,nparray 多维数组

注意事项:

  • 确保传递给 cv2.imdecode() 的缓冲区包含有效的图像数据,并且使用正确的标志来解码图像。如果缓冲区为空或损坏,或者使用了错误的标志,函数将无法正确解码图像。
  • cv2.imdecode() 返回的是一个 NumPy 数组,该数组存储了解码后的图像数据。这个数组是存储在内存中的,因此在处理大量图像或非常大的图像时,需要注意内存使用情况,避免内存溢出或内存不足的问题。

代码示例:

代码语言:javascript复制
import numpy as np
import cv2

imgFile = "img/测试图.png"  # 带有中文的文件路径和文件名
# 使用 imdecode 可以读取带有中文的文件路径和文件名
img = cv2.imdecode(np.fromfile(imgFile, dtype=np.uint8), -1)
cv2.imshow("demo", img)
cv2.waitKey()
cv2.destroyAllWindows()

2. 图像的显示

2.1 openCV显示图像 cv2.imshow()

语法结构:

代码语言:javascript复制
 cv2.imshow(winname,mat) #用于在窗口中显示图像
  • winname:用于标识要显示的窗口。如果指定的窗口名称已经存在,cv2.imshow() 将在这个现有窗口中显示图像。如果不存在,它将创建一个新窗口。
  • mat:所显示的 OpenCV 图像,nparray 多维数组。

注意事项:

  • cv2.imshow() 会自动调整窗口大小以适应图像的尺寸。如果需要手动设置窗口大小,可以使用 cv2.namedWindow() 函数,并指定窗口的大小。
  • cv2.imshow() 之后要用 waitKey() 函数设定图像窗口的显示时长,否则不会显示图像窗口,waitKey(0) 表示窗口显示时长为无限。
  • 可以创建多个不同的显示窗口,每个窗口必须命名不同的 filename。
  • 可以用 destroyWindow() 函数关闭指定的显示窗口,也可以用 destroyAllWindows() 函数关闭所有的显示窗口。

2.2 matplotlib显示图像 plt.imshow()

语法结构:

代码语言:javascript复制
plt.imshow(img[, cmap])
  • img:图像数据,一个二维或三维数组,通常表示图像的像素值。对于灰度图像,它是一个二维数组,其中每个值表示一个像素的亮度。对于彩色图像,它是一个三维数组,通常的形状是 (height, width, 3) 或 (height, width, 4),其中 3 或 4 分别表示 RGB(红、绿、蓝)或 RGBA(红、绿、蓝、透明度)颜色通道.
  • cmap:颜色图谱(colormap),默认为 RGB(A) 颜色空间
    • gray:灰度显示
    • hsv:hsv 颜色空间

注意事项:

  • plt.imshow() 可以直接显示 OpenCV 灰度图像,不需要格式转换,但需要使用 cmap=‘gray’ 进行参数设置。
  • plt.imshow() 可以使用 matplotlib 库中的各种方法绘图,如标题、坐标轴、插值等
  • plt.imshow() 只是将图像显示在当前的 Matplotlib 图形上。要实际看到图像,你需要调用 plt.show()。如果你想要保存图像到文件,可以使用 plt.savefig() 函数。
  • 在 Matplotlib 中,图像的默认原点(即坐标 (0,0))通常位于左上角,这与许多图像处理库(如 OpenCV)中的默认设置(左下角为原点)不同。这可能在处理或显示图像时造成混淆。
  • 在使用 plt.imshow() 或其他 Matplotlib 函数显示图形后,如果你不再需要它,最好使用 plt.close() 来关闭图形,以释放资源。

代码示例:

代码语言:javascript复制
from matplotlib import pyplot as plt
import cv2

imgFile = "img/1.png"  # 带有中文的文件路径和文件名
img1 = cv2.imread(imgFile, flags=1)  # flags=1 读取彩色图像(BGR)

imgRGB = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB)  # 图片格式转换:BGR(OpenCV) -> RGB(PyQt5)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)  # 图片格式转换:BGR(OpenCV) -> Gray

plt.rcParams['font.sans-serif'] = ['FangSong']  # 支持中文标签
plt.subplot(221), plt.title("1. RGB 格式(mpl)"), plt.axis('off')
plt.imshow(imgRGB)  # matplotlib 显示彩色图像(RGB格式)
plt.subplot(222), plt.title("2. BGR 格式(OpenCV)"), plt.axis('off')
plt.imshow(img1)  # matplotlib 显示彩色图像(BGR格式)
plt.subplot(223), plt.title("3. 设置 Gray 参数"), plt.axis('off')
plt.imshow(img2, cmap='gray')  # matplotlib 显示灰度图像,设置 Gray 参数
plt.subplot(224), plt.title("4. 未设置 Gray 参数"), plt.axis('off')
plt.imshow(img2)  # matplotlib 显示灰度图像,未设置 Gray 参数
plt.show()

3. 图像的保存 cv2.imwrite()

语法结构:

代码语言:javascript复制
retval = cv2.imwrite(filename, img [, params])
  • filename:要保存的文件的路径和名称,包括文件扩展名
  • img:要保存的 OpenCV 图像,nparray 多维数组
  • params:不同编码格式的参数
    • cv2.CV_IMWRITE_JPEG_QUALITY:设置 .jpeg/.jpg 格式的图片质量,取值为 0-100(默认值 95),数值越大则图片质量越高;
    • cv2.CV_IMWRITE_WEBP_QUALITY:设置 .webp 格式的图片质量,取值为 0-100;
    • cv2.CV_IMWRITE_PNG_COMPRESSION:设置 .png 格式图片的压缩比,取值为 0-9(默认值 3),数值越大则压缩比越大。
  • retval:返回值,保存成功返回 True,否则返回 False。

注意事项:

  • 文件名和扩展名决定了图像的格式。例如,如果文件名为 ‘image.jpg’,则图像将以 JPEG 格式保存。
  • 在 Python 3 中,cv2.imwrite() 不支持中文和空格作为文件名。如果需要使用中文,可以使用 cv2.imencode() 函数进行处理。
  • cv2.imwrite() 函数的返回值是一个布尔值,表示图像是否成功保存。
  • 对 4 通道 BGRA 图像,可以使用 Alpha 通道保存为 PNG 图像。

代码示例:

代码语言:javascript复制
import cv2

imgFile = "../img/1.png"  # 读取文件的路径
img = cv2.imread(imgFile, flags=1)  # flags=1 读取彩色图像(BGR)
# 保存 JPEG 图像并指定质量为 90
cv2.imwrite('output.jpg', img, [int(cv2.IMWRITE_JPEG_QUALITY), 90])
# 保存 PNG 图像并指定压缩级别为 9
cv2.imwrite('output.png', img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9])

4. 图像的复制

4.1 img.copy()

  • img.copy() 是NumPy数组的一个方法。当你在一个NumPy数组(通常是OpenCV图像)上调用这个方法时,它会创建一个新的数组,这个新数组是原始数组的一个深拷贝(deep copy)。这意味着新数组和原始数组在内存中是独立的,对其中一个数组的任何修改都不会影响另一个数组。

4.2 np.copy()

  • img.copy()是NumPy数组的一个方法。当你在一个NumPy数组(通常是OpenCV图像)上调用这个方法时,它会创建一个np.copy(img) 是NumPy库的一个函数,它也可以用来创建数组的一个深拷贝。与 img.copy() 类似,np.copy(img) 会创建一个新的数组,这个新数组与原始数组 img 在内存中是独立的。

4.3 代码示例

代码语言:javascript复制
import cv2  
import numpy as np  
  
# 读取图像  
img = cv2.imread('input.jpg')  
  
# 使用img.copy()方法复制图像  
img_copy1 = img.copy()  
  
# 使用np.copy()函数复制图像  
img_copy2 = np.copy(img)  
  
# 现在img_copy1和img_copy2都是img的副本

5. 图像的属性

  • 在OpenCV中,经常需要获取图像的大小,类型,像素等图像属性,为此,提供了shape、size、dtype这3个常用函数:
    • shape: shape是一个包含图像高度、宽度和通道数的元组。可以通过shape属性获取图像的尺寸。 如果图像是灰度图,返回值就仅有 行数和列数,所以通过检查这个返回值就可以知道加载的是灰度图还是彩色图。
    • size: 返回图像的像素数目。
    • dtype: 返回的是图像的数据类型。

代码示例:

代码语言:javascript复制
import cv2

image_Color = cv2.imread("log.jpg")  # 读取log.jpg
print("获取彩色图像的属性:")
print("shape =", image_Color.shape)  # 打印彩色图像的(像素行数,像素列数,通道数)
print("size =", image_Color.size)  # 打印彩色图像包含的像素个数
print("dtype =", image_Color.dtype)  # 打印彩色图像的数据类型
image_Gray = cv2.imread("log.jpg", 0)  # 读取与log.jpg(彩色图像)对应的灰度图像
print("获取灰度图像的属性:")
print("shape =", image_Gray.shape)  # 打印灰度图像的(像素行数,像素列数)
print("size =", image_Gray.size)  # 打印灰度图像包含的像素个数
print("dtype =", image_Gray.dtype)  # 打印灰度图像的数据类型

0 人点赞