【OpenCV 图像处理 Python版】图像处理的基本操作 - 指南


目录

​编辑

1.图像的 IO 操作

1.1 图像读取 imread

1.2 图像显示

1.2.1 opencv 方式

1.2.2 matplotlib 方式

1.3 图像保存 imwrite

2.绘制几何图形

1. 绘制直线

2. 绘制矩形

3. 绘制圆形

4. 绘制多边形

5. 添加文字

3.获取并修改图像中的像素点

3.1 获取像素值

3.2 修改像素值

3.3 获取和修改区域像素值

4.获取图像属性

4.1 获取图像属性

详细解释

4.2 处理灰度图像

5.图像通道的拆分与合并

5.1 图像通道的拆分

5.2 图像通道的合并

5.3 修改单个通道并合并

6.色彩空间的改变

详细解释

为什么需要将 HSV 和 Lab 图像,先转换回 RGB 格式再显示?

1. matplotlib 期望的颜色格式是 RGB

2. 可视化的直观性

3. 避免误解


1.图像的 IO 操作

1.1 图像读取 imread

使用cv2.imread函数可以读取图像。该函数有两个参数:

  • 第一个参数是图像文件的路径
  • 第二个参数是读取模式,可以是以下几种:
    • cv2.IMREAD_COLOR:读取彩色图像(默认)。
    • cv2.IMREAD_GRAYSCALE:读取灰度图像。
    • cv2.IMREAD_UNCHANGED:读取图像,并包括图像的alpha通道。

示例

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1.读取图像
# 读取彩色图像
image  = cv.imread('../images/iu.jpg', cv.IMREAD_COLOR)
# 读取灰度图像
image_gray  = cv.imread('../images/iu.jpg', cv.IMREAD_GRAYSCALE)

1.2 图像显示

图像显示主要有两种方式:OpenCV 提供的 imshow 函数和 matplotlib 库提供的 imshow 函数。

1.2.1 opencv 方式

使用 cv2.imshow 函数可以显示图像。该函数有两个参数:

  • 第一个参数是窗口的名称。
  • 第二个参数是要显示的图像。

使用 cv2.waitKey 函数可以等待按键事件。该函数的参数是等待的时间(毫秒),如果设置为0,则无限等待。

使用cv2.destroyAllWindows函数可以关闭所有窗口。

示例

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1.读取图像
# 读取彩色图像
image  = cv.imread('../images/iu.jpg', cv.IMREAD_COLOR)
# 读取灰度图像
image_gray  = cv.imread('../images/iu.jpg', cv.IMREAD_GRAYSCALE)
# 2.显示图像
# 2.1 opencv 显示
cv.imshow('iu', image)
cv.imshow('gray', image_gray)
cv.waitKey(0)
cv.destroyAllWindows()

但是由于使用 opencv 提供的 imshow 函数时会创建新的窗口显示图像,不方便观察,所以后面一般会用另外一种方式。

1.2.2 matplotlib 方式

转换颜色空间

由于OpenCV 读取的图像是 BGR 格式,而 matplotlib 显示图像时使用的是 RGB 格式。因此,需要将 BGR 图像转换为 RGB 图像,此时也是有两种方式:

  1. 使用 cvtColor 进行转换;
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
plt.imshow(image_rgb)
  1. 使用矩阵转换;
plt.imshow(image[:,:,::-1])

示例

第一种方式

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1.读取图像
# 读取彩色图像
image  = cv.imread('../images/iu.jpg', cv.IMREAD_COLOR)
# 读取灰度图像
image_gray  = cv.imread('../images/iu.jpg', cv.IMREAD_GRAYSCALE)
# 2.2 plt 读取
# 第一种方式
image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)# 彩色图像显示
plt.imshow(image_rgb)
plt.show()


第二种方式

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1.读取图像
# 读取彩色图像
image  = cv.imread('../images/iu.jpg', cv.IMREAD_COLOR)
# 读取灰度图像
image_gray  = cv.imread('../images/iu.jpg', cv.IMREAD_GRAYSCALE)
# 2.2 plt 读取
# 第二种方式
plt.imshow(image[:,:,::-1]) # 彩色图像显示
plt.show()

1.3 图像保存 imwrite

使用 cv2.imwrite 函数可以保存图像。该函数有两个参数:

  • 第一个参数是保存的文件路径。
  • 第二个参数是要保存的图像。

示例

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
# 1.读取图像
# 读取彩色图像
image  = cv.imread('../images/iu.jpg', cv.IMREAD_COLOR)
# 读取灰度图像
image_gray  = cv.imread('../images/iu.jpg', cv.IMREAD_GRAYSCALE)
# 2.显示图像
# 2.1 opencv 读取
# cv.imshow('iu', image)
# cv.imshow('gray', image_gray)
# cv.waitKey(0)
# cv.destroyAllWindows()
# 2.2 plt 读取
# 第一种方式
# image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)# 彩色图像读取
# plt.imshow(image_rgb)
# 第二种方式
# plt.imshow(image[:,:,::-1]) # 彩色图像读取
# plt.show()
# 3.图像保存
cv.imwrite('../images/iu_rgb.jpg', image)
cv.imwrite('../images/iu_gray.jpg', image_gray)

2.绘制几何图形

在OpenCV中,可以使用一系列绘图函数在图像上绘制几何图形和添加文字。这些函数包括绘制直线、矩形、圆形、多边形以及添加文本等。以下是如何使用这些函数的详细步骤和示例代码。

1. 绘制直线

使用 cv2.line 函数可以在图像上绘制直线。该函数的参数包括:

  • 图像对象
  • 起点坐标
  • 终点坐标
  • 颜色(BGR格式)
  • 线条粗细(可选)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 绘制一条白色直线
cv.line(image, (0, 0), (511, 511), (255, 255, 255), 5)
# 显示图像
plt.imshow(image[:,:,::-1])
plt.show()

2. 绘制矩形

使用 cv2.rectangle 函数可以在图像上绘制矩形。该函数的参数包括:

  • 图像对象
  • 左上角坐标
  • 右下角坐标
  • 颜色(BGR格式)
  • 线条粗细(如果为负值,则填充矩形)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 绘制一条白色直线
cv.line(image, (0, 0), (511, 511), (255, 255, 255), 5)
# 绘制一个绿色矩形
cv.rectangle(image, (100, 100), (400, 400), (0, 255, 0), 3)
# 显示图像
plt.imshow(image[:,:,::-1])
plt.show()

3. 绘制圆形

使用 cv2.circle 函数可以在图像上绘制圆形。该函数的参数包括:

  • 图像对象
  • 圆心坐标
  • 半径
  • 颜色(BGR格式)
  • 线条粗细(如果为负值,则填充圆形)
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 绘制一条白色直线
cv.line(image, (0, 0), (511, 511), (255, 255, 255), 5)
# 绘制一个绿色矩形
cv.rectangle(image, (100, 100), (400, 400), (0, 255, 0), 3)
# 绘制一个红色圆形
cv.circle(image, (256, 256), 100, (0, 0, 255), -1)
# 显示图像
plt.imshow(image[:,:,::-1])
plt.show()

4. 绘制多边形

使用 cv2.polylines 函数可以在图像上绘制多边形。该函数的参数包括:

  • 图像对象
  • 顶点坐标数组
  • 是否闭合
  • 颜色(BGR格式)
  • 线条粗细
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 绘制一条白色直线
cv.line(image, (0, 0), (511, 511), (255, 255, 255), 5)
# 绘制一个绿色矩形
cv.rectangle(image, (100, 100), (400, 400), (0, 255, 0), 3)
# 绘制一个红色圆形
cv.circle(image, (256, 256), 100, (0, 0, 255), -1)
# 定义多边形的顶点
points = np.array([[100, 50], [200, 300], [70, 200], [50, 100]], np.int32)
points = points.reshape((-1, 1, 2))
# 绘制一个蓝色多边形
cv.polylines(image, [points], True, (255, 0, 0), 3)
# 显示图像
plt.imshow(image[:,:,::-1])
plt.show()

5. 添加文字

使用 cv2.putText 函数可以在图像上添加文字。该函数的参数包括:

  • 图像对象
  • 文字内容
  • 文字起点坐标
  • 字体类型
  • 字体大小
  • 颜色(BGR格式)
  • 线条粗细
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 绘制一条白色直线
cv.line(image, (0, 0), (511, 511), (255, 255, 255), 5)
# 绘制一个绿色矩形
cv.rectangle(image, (100, 100), (400, 400), (0, 255, 0), 3)
# 绘制一个红色圆形
cv.circle(image, (256, 256), 100, (0, 0, 255), -1)
# 定义多边形的顶点
points = np.array([[100, 50], [200, 300], [70, 200], [50, 100]], np.int32)
points = points.reshape((-1, 1, 2))
# 绘制一个蓝色多边形
cv.polylines(image, [points], True, (255, 0, 0), 3)
# 显示图像
# 添加白色文字
cv.putText(image, 'Hello, OpenCV!', (50, 250), cv.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
plt.imshow(image[:,:,::-1])
plt.show()

3.获取并修改图像中的像素点

在OpenCV中,可以非常方便地获取和修改图像中的像素点。图像在OpenCV中被表示为一个NumPy数组,因此可以使用NumPy的索引和切片操作来访问和修改图像的像素值。

3.1 获取像素值

要获取图像中某个像素点的值,可以使用数组索引。对于彩色图像,像素值是一个包含三个元素的数组,分别表示B、G、R三个通道的值。对于灰度图像,像素值是一个单一的灰度值。

示例

import cv2 as cv
# 读取彩色图像
image = cv.imread('../images/iu.jpg')
# 获取某个像素点的值 (x=100, y=100)
pixel_value = image[100, 100]
print("Pixel value at (100, 100):", pixel_value)
# 获取某个像素点的蓝色通道值
blue_value = image[100, 100, 0]
print("Blue channel value at (100, 100):", blue_value)
# 获取某个像素点的绿色通道值
green_value = image[100, 100, 1]
print("Green channel value at (100, 100):", green_value)
# 获取某个像素点的红色通道值
red_value = image[100, 100, 2]
print("Red channel value at (100, 100):", red_value)

3.2 修改像素值

要修改图像中某个像素点的值,可以直接使用数组索引进行赋值操作。对于彩色图像,可以分别修改B、G、R三个通道的值。

示例

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 修改某个像素点的值 (x=100, y=100)
image[100, 100] = [0, 255, 0]  # 将该像素点设置为绿色
# 修改某个像素点的蓝色通道值
image[100, 100, 0] = 255  # 将该像素点的蓝色通道值设置为255
# 修改某个像素点的绿色通道值
image[100, 100, 1] = 0  # 将该像素点的绿色通道值设置为0
# 修改某个像素点的红色通道值
image[100, 100, 2] = 0  # 将该像素点的红色通道值设置为0
# 显示修改后的图像
plt.imshow(image[:,:,::-1])
plt.show()

3.3 获取和修改区域像素值

除了单个像素点,还可以获取和修改图像的某个区域。可以使用NumPy的切片操作来实现。

示例

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
# 创建一个空白图像
image = np.zeros((512, 512, 3), np.uint8)
# 获取某个区域的像素值 (从x=100, y=100到x=200, y=200)
region = image[100:200, 100:200]
print("Region shape:", region.shape)
# 修改某个区域的像素值 (从x=100, y=100到x=200, y=200)
image[100:200, 100:200] = [0, 255, 0]  # 将该区域设置为绿色
# 显示修改后的图像
plt.imshow(image[:,:,::-1])
plt.show()

4.获取图像属性

在OpenCV中,可以通过读取图像的属性来获取图像的基本信息,例如图像的尺寸、通道数、数据类型等。这些属性可以帮助你了解图像的基本结构和格式,从而更好地进行图像处理和分析。

4.1 获取图像属性

以下是一些常用的图像属性及其获取方法:

  1. 图像的形状(尺寸):可以使用NumPy数组的 shape 属性来获取图像的尺寸。
  2. 图像的大小(像素数):可以使用NumPy数组的 size 属性来获取图像的总像素数。
  3. 图像的数据类型:可以使用NumPy数组的 dtype 属性来获取图像的数据类型。

示例

以下是一个示例代码,演示如何获取图像的这些属性:

import cv2 as cv
# 读取图像
image = cv.imread('../images/iu.jpg')
# 获取图像的形状(尺寸)
height, width, channels = image.shape
print("Height:", height)
print("Width:", width)
print("Channels:", channels)
# 获取图像的大小(像素数)
size = image.size
print("Size (number of pixels):", size)
# 获取图像的数据类型
dtype = image.dtype
print("Data type:", dtype)
详细解释
  1. 图像的形状(尺寸)

    • image.shape 返回一个包含三个元素的元组,分别表示图像的高度、宽度和通道数。
    • 对于灰度图像,image.shape 返回的元组只有两个元素,分别表示图像的高度和宽度。
  2. 图像的大小(像素数)

    • image.size 返回图像的总像素数,即高度、宽度和通道数的乘积。
  3. 图像的数据类型

    • image.dtype 返回图像的数据类型,通常是 uint8,表示每个像素值是一个8位无符号整数。

4.2 处理灰度图像

如果你处理的是灰度图像,获取属性的方式略有不同,因为灰度图像只有两个维度(高度和宽度)。

import cv2 as cv
# 读取灰度图像
gray_image = cv.imread('example.jpg', cv.IMREAD_GRAYSCALE)
# 获取图像的形状(尺寸)
height, width = gray_image.shape
print("Height:", height)
print("Width:", width)
# 获取图像的大小(像素数)
size = gray_image.size
print("Size (number of pixels):", size)
# 获取图像的数据类型
dtype = gray_image.dtype
print("Data type:", dtype)

5.图像通道的拆分与合并

在OpenCV中,可以使用 cv2.split 函数将彩色图像的通道拆分为单独的灰度图像,并使用 cv2.merge 函数将多个单通道图像合并为一个多通道图像。这些操作在图像处理和计算机视觉任务中非常常见和有用。

5.1 图像通道的拆分

cv2.split 函数可以将彩色图像的B、G、R三个通道拆分为三个单独的灰度图像。

示例

import cv2 as cv
import matplotlib.pyplot as plt
# 读取彩色图像
image = cv.imread('../images/iu.jpg')
# 拆分图像的B、G、R通道
b_channel, g_channel, r_channel = cv.split(image)
# 将BGR图像转换为RGB图像
image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
# 显示原始图像和拆分后的通道图像
plt.figure(figsize=(10, 7))
# 显示原始图像
plt.subplot(2, 2, 1)
plt.imshow(image_rgb)
plt.title('Original Image (RGB)')
plt.axis('off')
# 显示蓝色通道
plt.subplot(2, 2, 2)
plt.imshow(b_channel, cmap='gray')
plt.title('Blue Channel')
plt.axis('off')
# 显示绿色通道
plt.subplot(2, 2, 3)
plt.imshow(g_channel, cmap='gray')
plt.title('Green Channel')
plt.axis('off')
# 显示红色通道
plt.subplot(2, 2, 4)
plt.imshow(r_channel, cmap='gray')
plt.title('Red Channel')
plt.axis('off')
plt.show()

5.2 图像通道的合并

cv2.merge 函数可以将多个单通道图像合并为一个多通道图像。通常用于将拆分后的通道重新合并为一个彩色图像。

示例

import cv2 as cv
import matplotlib.pyplot as plt
# 读取彩色图像
image = cv.imread('../images/iu.jpg')
# 拆分图像的B、G、R通道
b_channel, g_channel, r_channel = cv.split(image)
# 将BGR图像转换为RGB图像
image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
# 合并B、G、R通道
merged_image = cv.merge([b_channel, g_channel, r_channel])
# 显示合并通道后的图像
plt.imshow(merged_image[:,:,::-1])
plt.show()

5.3 修改单个通道并合并

你还可以在拆分通道后对单个通道进行修改,然后再合并回去。例如,将图像的红色通道设置为零。

示例

import cv2 as cv
import matplotlib.pyplot as plt
# 读取彩色图像
image = cv.imread('../images/iu.jpg')
# 拆分图像的B、G、R通道
b_channel, g_channel, r_channel = cv.split(image)
# 将BGR图像转换为RGB图像
image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
# # 将红色通道设置为零
# r_channel[:] = 0
# 合并B、G、R通道
merged_image = cv.merge([b_channel, g_channel, r_channel])
# 显示合并通道后的图像
plt.imshow(merged_image[:,:,::-1])
plt.show()

6.色彩空间的改变

在图像处理和计算机视觉中,改变色彩空间是一个常见的操作。OpenCV 提供了多种色彩空间转换函数,可以方便地在不同色彩空间之间进行转换。常见的色彩空间包括 BGRRGBHSVLab 等。

OpenCV 提供了 cv.cvtColor 函数来进行色彩空间的转换。以下是一些常见的色彩空间转换:

  • BGR 到 RGBcv.COLOR_BGR2RGB
  • BGR 到 灰度cv.COLOR_BGR2GRAY
  • BGR 到 HSVcv.COLOR_BGR2HSV
  • BGR 到 Labcv.COLOR_BGR2Lab

示例

import cv2 as cv
import matplotlib.pyplot as plt
# 读取彩色图像
image = cv.imread('../images/iu.jpg')
# BGR 转 RGB
image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
# BGR 转 灰度
image_gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
# BGR 转 HSV
image_hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
# BGR 转 Lab
image_lab = cv.cvtColor(image, cv.COLOR_BGR2Lab)
# 显示原始图像和转换后的图像
plt.figure(figsize=(12, 8))
# 显示原始图像(BGR 转 RGB)
plt.subplot(2, 2, 1)
plt.imshow(image_rgb)
plt.title('Original Image (RGB)')
plt.axis('off')
# 显示灰度图像
plt.subplot(2, 2, 2)
plt.imshow(image_gray, cmap='gray')
plt.title('Grayscale Image')
plt.axis('off')
# 显示 HSV 图像
plt.subplot(2, 2, 3)
plt.imshow(image_hsv)
plt.title('HSV Image')
plt.axis('off')
# 显示 Lab 图像
plt.subplot(2, 2, 4)
plt.imshow(image_lab)
plt.title('Lab Image')
plt.axis('off')
plt.tight_layout()
plt.show()

详细解释

读取图像

使用 cv.imread 读取图像,默认情况下图像是以 BGR 顺序存储的。
色彩空间转换:

  • 使用 cv.cvtColor 函数进行色彩空间转换。
    • cv.COLOR_BGR2RGB:将 BGR 转换为 RGB。
    • cv.COLOR_BGR2GRAY:将 BGR 转换为灰度。
    • cv.COLOR_BGR2HSV:将 BGR 转换为 HSV。
    • cv.COLOR_BGR2Lab:将 BGR 转换为 Lab。

显示图像

使用 plt.imshow 显示图像。对于彩色图像,确保颜色通道顺序正确(RGB)

  • 对于灰度图像,使用 cmap='gray' 参数显示灰度图像。
  • 对于 HSV 和 Lab 图像,先转换回 RGB 格式再显示。
为什么需要将 HSV 和 Lab 图像,先转换回 RGB 格式再显示?

在使用 matplotlib 显示图像时,特别是对于 HSV 和 Lab 色彩空间的图像,先转换回 RGB 格式再显示的原因主要有以下几点:

1. matplotlib 期望的颜色格式是 RGB

matplotlib 的 plt.imshow 函数默认期望输入的图像是 RGB 格式的。如果直接传入 HSV 或 Lab 格式的图像,颜色会显示不正确,因为 matplotlib 会将这些值误解为 RGB 值。

2. 可视化的直观性

HSV 和 Lab 色彩空间的值并不直接对应于人类视觉系统中的颜色感知。例如,HSV 色彩空间中的 H(色调)分量是一个角度值,S(饱和度)和 V(亮度)分量是比例值,而这些值在直接显示时并不能直观地反映出图像的颜色信息。将它们转换回 RGB 格式后,可以更直观地展示图像的颜色信息。

3. 避免误解

直接显示 HSV 或 Lab 图像可能会导致误解,因为这些色彩空间的值范围和含义与 RGB 不同。例如,HSV 色彩空间中的 H 分量范围是 [0, 179](在 OpenCV 中),而 RGB 的每个通道范围是 [0, 255]。直接显示这些图像会导致颜色失真和误解。

示例

以下是一个示例代码,演示如何将 HSV 和 Lab 图像转换回 RGB 格式再使用 matplotlib 显示:

import cv2 as cv
import matplotlib.pyplot as plt
# 读取彩色图像
image = cv.imread('example.jpg')
# BGR 转 HSV
image_hsv = cv.cvtColor(image, cv.COLOR_BGR2HSV)
# BGR 转 Lab
image_lab = cv.cvtColor(image, cv.COLOR_BGR2Lab)
# HSV 转 RGB
image_hsv_rgb = cv.cvtColor(image_hsv, cv.COLOR_HSV2RGB)
# Lab 转 RGB
image_lab_rgb = cv.cvtColor(image_lab, cv.COLOR_Lab2RGB)
# 显示原始图像和转换后的图像
plt.figure(figsize=(12, 8))
# 显示原始图像(BGR 转 RGB)
image_rgb = cv.cvtColor(image, cv.COLOR_BGR2RGB)
plt.subplot(2, 2, 1)
plt.imshow(image_rgb)
plt.title('Original Image (RGB)')
plt.axis('off')
# 显示 HSV 图像(转换回 RGB)
plt.subplot(2, 2, 2)
plt.imshow(image_hsv_rgb)
plt.title('HSV Image (Converted to RGB)')
plt.axis('off')
# 显示 Lab 图像(转换回 RGB)
plt.subplot(2, 2, 3)
plt.imshow(image_lab_rgb)
plt.title('Lab Image (Converted to RGB)')
plt.axis('off')
plt.tight_layout()
plt.show()

posted on 2026-01-11 22:19  ljbguanli  阅读(53)  评论(0)    收藏  举报