OpenCV图像基础

OpenCV其实就是一堆C和C++语言的源代码文件,这些源代码文件中实现了许多常用的计算机视觉算法。

  • OpenCV的全称是Open Source Computer Vision Library,是一个开放源代码的计算机视觉库

  • OpenCV最初由英特尔公司发起并开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用,现在美国Willow Garage为OpenCV提供主要的支持

  • OpenCV可用于开发实时的图像处理,计算机视觉以及模式识别程序,目前在工业界以及科研领域广泛采用

OpenCV确实起源于C语言,并且其最初的版本主要使用C语言编写。然而,随着发展,OpenCV已经大量采用了C++,提供了更丰富的面向对象接口以及更高的开发效率。尽管如此,OpenCV的核心算法和数据结构在设计上都非常注重性能优化,这使得它即使在处理复杂的图像处理任务时也能保持高效。

以下是一些原因说明为何OpenCV能够实现快速的处理速度:

  1. 底层优化:许多OpenCV的函数都是用C/C++编写的,并且经过了高度优化。此外,对于一些特别计算密集的任务,OpenCV还可能采用汇编语言进行优化,或者利用SIMD(Single Instruction Multiple Data)技术来加速处理过程。

  2. 多线程支持:OpenCV库中的某些操作可以自动利用多核处理器的优势,通过并行处理提高性能。例如,OpenCV 3引入了T-API(透明API),允许对图像处理流水线的不同阶段进行GPU加速。

  3. 硬件加速:OpenCV支持多种硬件加速技术,包括但不限于CUDA(NVIDIA的GPU编程模型)、OpenCL等,这些技术可以显著提升处理速度,特别是在执行大规模矩阵运算、卷积操作等任务时。

  4. 高效的算法实现:除了语言本身的性能优势外,OpenCV中包含的算法本身也是经过精心挑选和优化的,旨在最小化时间和空间复杂度。

  5. 与硬件紧密集成:OpenCV可以直接访问硬件资源,比如摄像头,从而减少了不必要的数据传输和转换延迟

opencv重要性

  • 计算机视觉:OpenCV 是计算机视觉领域的标准库之一,广泛应用于图像识别、物体检测、人脸识别、手势识别等。

  • 机器人技术:在机器人导航、环境感知和交互中,OpenCV 用于处理传感器数据和视觉信息。

  • 医学影像:在医学影像分析中,OpenCV 用于图像增强、分割和特征提取。

  • 自动驾驶:在自动驾驶汽车中,OpenCV 用于环境感知、障碍物检测和车道线识别。

  • 安全监控:在安全监控系统中,OpenCV 用于运动检测、人脸识别和行为分析。

    学习 OpenCV 不仅可以提升你的技术能力,还能为你在计算机视觉和图像处理领域的发展打开更多的门路。无论是学术研究、工业应用还是个人项目,OpenCV 都是一个不可或缺的工具

一、显示窗口

cv2.namedWindow 是 OpenCV 库中的一个函数,用于创建一个命名窗口,以便在该窗口中显示图像或进行其他图形操作。这个函数在处理图像和视频时非常有用,尤其是在开发基于图像处理的应用程序时

函数原型

cv2.namedWindow(winname, flags=None)

参数说明

- winname (str): 窗口的名称。这个名称必须是唯一的,因为它是用来标识窗口的。

- flags (int, 可选): 窗口的标志,用于设置窗口的行为。默认值为

cv2.WINDOW_AUTOSIZE
  • 常见的标志包括:

    • cv2.WINDOW_NORMAL: 允许调整窗口大小。

    • cv2.WINDOW_AUTOSIZE: 窗口大小根据图像大小自动调整,不能手动调整。。

以下是一个简单的示例,展示如何使用 cv2.namedWindow 创建一个窗口并在其中显示图像:

import cv2

# 读取图像
image = cv2.imread('images/car.png')

# 创建一个名为 "Image Window" 的窗口,允许调整大小
cv2.namedWindow('Image Window', cv2.WINDOW_NORMAL)

#2 设置名字和窗口大小
cv2.resizeWindow("Image Window",500,300)
# 显示图像
cv2.imshow('Image Window', image)

# 等待用户按键
cv2.waitKey(0)

# 关闭所有窗口
cv2.destroyAllWindows()

详细解释

1.读取图像:

image = cv2.imread('path/to/your/image.jpg')

2.创建窗口

cv2.namedWindow('Image Window', cv2.WINDOW_NORMAL)

        使用 cv2.namedWindow 创建一个名为 "Image Window" 的窗口,并设置cv2.WINDOW_NORMAL,允许用户调整窗口大小。

3.显示图像

cv2.imshow('Image Window', image)

 4.等待用户按键

cv2.waitKey(0)

 使用 cv2.waitKey 暂停程序执行,等待用户按键。参数 0 表示无限期等待,直到有按键事件发生。返回值:是一个ASCII值,

例如:q 键 ASCII 值为 113 ESC 键是27

5.关闭所有窗口

cv2.destroyAllWindows()

使用 cv2.destroyAllWindows 关闭所有打开的窗口。

其他注意事项

  • 窗口名称:窗口名称必须是唯一的,否则会覆盖已有的同名窗口。

  • 窗口标志:选择合适的窗口标志可以提升用户体验,特别是在需要用户交互的场景中。

二、创建空白图像

你可以使用 np.zeros 函数创建一个全零数组,这个数组可以表示一个空白图像。数组的形状应该符合图像的尺寸和通道数(例如,对于 RGB 图像,形状应为 (height, width, 3)

函数写法

# 创建一个 500x500 像素的空白图像,3 个通道(RGB)
height, width, channels = 500, 500, 3
blank_image = np.zeros((height, width, channels), dtype=np.uint8)

np.uint8 是 NumPy 库中定义的一种数据类型,代表“无符号的 8 位整数”(Unsigned 8-bit Integer)。这意味着它可以表示从 0 到 255 的整数值。这里的“8 位”指的是它使用 8 个二进制位来存储一个数字,因此所能表示的最大值是 2的8次方−1=255,最小值是 0。

在图像处理中,np.uint8 类型非常常见,因为图像的像素值通常以这种格式存储。例如,在常见的 RGB 图像中,每个颜色通道(红、绿、蓝)的强度值范围是从 0 到 255,这正好可以用 np.uint8 来表示

案例:

import cv2
import numpy as np

# 创建一个 500x500 像素的空白图像,3 个通道(RGB)
height, width, channels = 500, 500, 3
blank_image = np.zeros((height, width, channels), dtype=np.uint8)

# 显示空白图像
cv2.imshow('Image', blank_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 为什么不运行cv2.destroyAllWindows() 也可以关闭窗口?

在使用 OpenCV 进行图像或视频处理时,cv2.destroyAllWindows() 函数的作用是关闭所有由 cv2.imshow() 打开的窗口。如果你发现不调用 cv2.destroyAllWindows() 也可以关闭窗口,这可能是由于以下几个原因:

1 程序结束自动关闭:
 当你的 Python 脚本执行完毕并正常退出时,所有通过 cv2.imshow() 打开的窗口都会自动关闭。这是因为当脚本终止运行时,它所创建的所有资源(包括显示窗口)都会被操作系统回收。
2 按特定键关闭窗口:
 在某些情况下,你可能会编写代码来监听键盘输入,并根据用户按下特定键(如 'q' 键)来调用 cv2.destroyWindow() 或 cv2.destroyAllWindows() 来手动关闭窗口。即使你不显式地调用这些函数,在脚本结束时,如果所有窗口句柄都已释放,窗口也会关闭。
3 IDE环境下的行为:
 如果你是在集成开发环境(IDE)中运行你的代码,比如 PyCharm、Jupyter Notebook 等,某些IDE可能有自己的方式管理图形界面和窗口。、
 
总之,虽然不调用 cv2.destroyAllWindows() 有时也能看到窗口关闭,但这并不是最佳实践。为了确保资源正确释放以及避免潜在的资源泄露问题,尤其是在长时间运行的应用程序中,建议始终显式地调用 cv2.destroyAllWindows() 来关闭所有打开的窗口。这样做可以确保你的应用程序干净地退出,并释放所有占用的系统资源。

三、保存图片

`cv2.imwrite 是 OpenCV 库中的一个函数,用于将图像保存到文件中。这个函数在图像处理和计算机视觉任务中非常常用,特别是在需要将处理后的图像结果保存到磁盘时。

函数原型

cv2.imwrite(filename, img[, params])

 

参数说明

  • filename (str): 要保存的文件路径和名称。支持的文件格式包括 .jpg, .png, .bmp, .tiff 等。

  • img (numpy.ndarray): 要保存的图像。通常是一个二维或三维的 NumPy 数组,表示图像的像素值。

返回值

  • bool: 成功保存图像返回 True,否则返回 False

其他注意事项

  • 文件路径:确保提供的文件路径是有效的,如果路径不存在,OpenCV 会尝试创建它,但如果权限不足则会保存失败。

四、图像切片(裁剪)

在 OpenCV 中,图像切片用于从图像中提取一个子区域(矩形区域)。这种操作在图像处理中非常常见,特别是在进行目标检测、ROI(Region of Interest,感兴趣区域)提取等任务时。

语法解释

假设你有一个图像 img,它的类型是 numpy.ndarrayimg[y:y+h, x:x+w] 的含义如下:

  • x: 子区域左上角的 x 坐标。

  • y: 子区域左上角的 y 坐标。

  • w: 子区域的宽度。

  • h: 子区域的高度。

切片操作

  • img[y:y+h, x:x+w] 提取的是从 (x, y) 开始,宽度为 w,高度为 h 的矩形区域。

示例

假设你有一个图像 img,并且你想要从这个图像中提取一个特定的矩形区域,例如左上角坐标为 (50, 60),宽度为 100,高度为 150 的区域。

 

import cv2

# 读取图像
img = cv2.imread('input_image.jpg')

# 定义矩形区域的参数
x, y, w, h = 50, 60, 100, 150

# 提取子区域
roi = img[y:y+h, x:x+w]

# 显示原始图像和提取的子区域
cv2.imshow('Image', img)
cv2.imshow('ROI', roi)

# 等待用户按键
cv2.waitKey(0)

# 关闭所有窗口
cv2.destroyAllWindows()

其他注意事项

  • 边界检查:确保 (x, y)(x+w, y+h) 都在图像的边界内,否则会导致数组索引越界错误。

  • 数据类型img 通常是 numpy.ndarray 类型,切片操作返回的也是 numpy.ndarray 类型。

五、调整图片大小

cv2.resize 是 OpenCV 库中的一个函数,用于调整图像的大小。这个函数在图像处理中非常常用,特别是在需要对图像进行缩放、放大或缩小以适应不同需求时。

函数原型

cv2.resize(src, dsize, dst)

 

参数说明

  • src (numpy.ndarray): 输入图像,通常是一个二维或三维的 NumPy 数组。

  • dsize (tuple): 输出图像的尺寸,是一个二元组 (width, height)。如果指定了 fxfy,则可以忽略此参数。

返回值

  • dst (numpy.ndarray): 缩放后的图像。

示例

以下是一个简单的示例,展示如何使用 cv2.resize 调整图像的大小:

import cv2

img = cv2.imread("images/car.png")
#获取图片的像素和通道数
height, width, channels = img.shape
print(f"高度:{height},宽度:{width},通道数:{channels}")
#调整图片的大小
img = cv2.resize(img, (300, 300))
height, width, channels = img.shape
print(f"调整后:高度:{height},宽度:{width},通道数:{channels}")
#保存图片
cv2.imwrite("save_image/car.png", img)

六、图像绘制

1.绘制圆形

cv2.circle()函数用于在图像上绘制圆形。该函数的语法如下:

cv2.circle(img, center, radius, color, thickness)
​

其中,参数解释如下:

  • img:要绘制圆形的图像。

  • center:圆心的坐标。

  • radius:圆的半径。

  • color:圆的颜色,通常是一个表示BGR颜色的元组,例如(255, 0, 0)表示蓝色。

  • thickness:圆的边界线条的厚度,如果为负值或cv2.FILLED,表示填充整个圆。

2.绘制矩形

cv2.rectangle()`函数用于在图像上绘制矩形。该函数的语法如下:

 cv2.rectangle(img, pt1, pt2, color[, thickness[, lineType[, shift]]])
​

其中,参数解释如下:

  • img:要绘制矩形的图像。

  • pt1:矩形的一个顶点。

  • pt2:矩形对角线上的另一个顶点。

  • color:矩形的颜色,通常是一个表示BGR颜色的元组,例如(255, 0, 0)表示蓝色。

  • thickness:矩形边框的厚度,如果为负值或cv2.FILLED,表示填充整个矩形内部。

3.绘制直线

cv2.line(img, pt1, pt2, color, thickness lineType) -> img

参数说明

  • img: 输出图像,即要在这张图上绘制直线的图像。通常是一个 NumPy 数组。

  • pt1: 直线的一个端点,是一个包含两个元素(x, y)的元组,代表该点的坐标。

  • pt2: 直线的另一个端点,也是一个包含两个元素(x, y)的元组,代表该点的坐标。

  • color: 直线的颜色,对于 BGR 图像,这应该是一个包含三个整数的元组,分别对应蓝色、绿色和红色的强度(例如 (255, 0, 0) 表示纯蓝色)。对于灰度图像,只需要一个整数值即可。

  • thickness: 可选参数,定义直线的宽度。默认值是 1。

返回值

  • img: 返回的是经过修改后的图像,实际上就是传入的图像本身,因为 cv2.line() 是直接在原图上操作的。

cv2.line() 是 OpenCV 库中的一个函数,用于在图像上绘制直线。这个函数非常直观,它接受多个参数来定义直线的位置、颜色、厚度等属性。以下是 cv2.line() 函数的基本语法及其参数说明

4.绘制文本

cv2.putText 是 OpenCV 库中的一个函数,用于在图像上添加文本。这个函数在图像处理和计算机视觉任务中非常有用,特别是在需要标注图像、显示信息或调试时。

函数原型

cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])

参数说明

  • img (numpy.ndarray): 输入图像,通常是一个二维或三维的 NumPy 数组。

  • text (str): 要添加的文本字符串。

  • org (tuple): 文本的起始位置,是一个二元组 (x, y),表示文本左下角的坐标。

  • fontFace

    (int): 字体类型,常见的字体类型包括:

    • cv2.FONT_HERSHEY_SIMPLEX: 正常大小的无衬线字体

    • cv2.FONT_HERSHEY_PLAIN: 小号的无衬线字体

    • cv2.FONT_HERSHEY_DUPLEX: 正常大小的无衬线字体,比 FONT_HERSHEY_SIMPLEX 更粗

    • cv2.FONT_HERSHEY_COMPLEX: 正常大小的有衬线字体

    • cv2.FONT_HERSHEY_TRIPLEX: 正常大小的有衬线字体,比 FONT_HERSHEY_COMPLEX 更粗

    • cv2.FONT_HERSHEY_SCRIPT_SIMPLEX: 手写风格的字体

    • cv2.FONT_HERSHEY_SCRIPT_COMPLEX: 手写风格的字体,比 FONT_HERSHEY_SCRIPT_SIMPLEX 更粗

    • cv2.FONT_ITALIC: 斜体修饰符,可以与其他字体类型组合使用

  • fontScale (float): 字体大小的比例因子。

  • color (tuple): 文本颜色,是一个三元组 (B, G, R),表示蓝色、绿色和红色的值。

  • thickness (int, 可选): 文本线条的厚度,默认值为 1。

  • lineType

    (int, 可选): 线条类型,常见的线条类型包括:

    • cv2.LINE_4: 4 连通线

    • cv2.LINE_8: 8 连通线

    • cv2.LINE_AA: 抗锯齿线(默认值)

返回值

  • img (numpy.ndarray): 添加文本后的图像。

关于opencv 显示中文乱码问题解决

在使用 OpenCV 的 cv2.putText 函数添加中文时,可能会遇到显示乱码的问题。这是因为 OpenCV 默认使用的字体不支持中文字符。为了在图像上正确显示中文,可以使用 PIL(Pillow)库来处理文本,然后将文本渲染到图像上

import cv2
from PIL import Image, ImageDraw, ImageFont
import numpy as np


def put_text(image, text, position, font_path, font_size, color):
    # 将 OpenCV 图像转换为 PIL 图像
    pil_image = Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))

    # 创建一个可以在给定图像上绘图的对象
    draw = ImageDraw.Draw(pil_image)

    # 加载字体
    font = ImageFont.truetype(font_path, font_size)

    # 在图像上绘制文本
    draw.text(position, text, fill=color, font=font)

    # 将 PIL 图像转换回 OpenCV 图像
    image_with_text = cv2.cvtColor(np.array(pil_image), cv2.COLOR_RGB2BGR)

    return image_with_text


# 读取图像
image = cv2.imread('images/car.png')

# 定义文本内容、位置、字体路径、字体大小和颜色
text = "你好,世界!"
position = (50, 50)
font_path = "myfont/simhei.ttf"    # 替换为你的字体文件路径
font_size = 30
color = (0, 0, 255)  # BGR 格式

# 在图像上添加中文文本
image_with_text = put_text(image, text, position, font_path, font_size, color)

# 显示图像
cv2.imshow('Image with Text', image_with_text)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

你可能感兴趣的:(opencv,人工智能,计算机视觉)