初识OpenCV---1.图像基础

发布于:2025-07-25 ⋅ 阅读:(27) ⋅ 点赞:(0)

一、OpenCV介绍

OpenCV(开放源代码计算机视觉库)是一个开源的计算机视觉和机器学习软件学习库。由一系列C++类和函数构成,用于图像处理、计算机视觉领域的算法实现。

1.OpenCV的优势

  • 开源免费:完全开源,可以自由使用,降低开发成本和技术门槛。​
  • 多语言支持:除 C++ 原生接口外,还支持 Java、Python 等编程语言。​
  • 跨平台:支持多种操作系统,Windows、Linux、ios、Android 等,方便开发和部署。​
  • 丰富 API:完善的传统计算机视觉算法,涵盖主流的机器学习算法,同时添加了对深度学习的支持。

2.OpenCV-Python​

OpenCV-Python 是原始 OpenCV C++ 实现的 Python 包装器。它结合了 OpenCV C++ API 的高性能与 Python 语言的易用性和简洁性。通过 OpenCV-Python,开发者可以轻松地进行图像处理、计算机视觉任务以及机器学习应用。​

与 C / C++ 等语言相比,Python 速度较慢。但 Python 可以使用 C / C++ 扩展,这使我们可以在 C / C++ 中编写计算密集型代码,并创建可用作 Python 模块的 Python 包装器。这样做有两个好处:首先,代码与原始 C / C++ 代码一样快(因为它是在后台工作的实际 C++ 代码),其次,在 Python 中编写代码比使用 C / C++ 更容易。​

OpenCV-Python 使用 Numpy,这是一个高度优化的数据库操作库。所有 OpenCV 数组结构都转换为 Numpy 数组。这也使得与使用 Numpy 的其他库(如 SciPy 和 Matplotlib)集成更容易。

二、环境安装

要使用 OpenCV-Python,首先需要安装相应的库。推荐使用清华大学的镜像源来加快下载速度,安装命令如下:

     pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

 

三、 图像表示​

像素是图像的基本单元,每个像素存储着图像的颜色、亮度和其他特征。一系列像素组合到一起就形成了完整的图像,在计算机中,图像以像素的形式存在并采用二进制格式进行存储。根据图像的颜色不同,每个像素可以用不同的二进制数表示。​

计算机采用 0/1 编码的系统,数字图像也是利用 0/1 来记录信息,我们平常接触的图像都是 8 位数图像。OpenCV 中常用的是 8 位图像,大多数彩色和灰度图像使用 8 位表示每个通道的像素值,范围从 0 到 255,其中 0 代表最黑,255 表示最白。​

日常生活中常见的图像是 RGB 三原色图。RGB 图上的每个点都是由红(R)、绿(G)、蓝(B)三个颜色按照一定比例混合而成的,几乎所有颜色都可以通过这三种颜色按照不同比例调配而成。在计算机中,RGB 三种颜色被称为 RGB 三通道,每个通道的取值都是 0-255,根据这三个通道存储的像素值,来对应不同的颜色。

四、 图像存储​

在 OpenCV 中,无论是读取还是创建图像,结果都是一个 NumPy 数组。​

  • 彩色图像:以三维数组形式存储​
  • 灰度图像:以二维数组形式存储​

图像本质上是像素值的二维或三维矩阵(对于彩色图像)。​

  • 形状(Shape):图像的尺寸由其高(height)、宽(width)和通道数(channels)决定。可以通过img.shape属性获取这些信息。​
  • 对于彩色图像(如 RGB),返回的是一个包含三个值的元组 (height, width, channels)。​
  • 对于灰度图像,返回的是一个包含两个值的元组 (height, width),因为灰度图像只有一个通道。​
  • 数据类型(dtype):图像中的每个像素值的数据类型决定了可以存储的最大值。例如,8 位无符号整数(uint8)允许的范围是从 0 到 255。​
  • 像素表示​
  • 单通道图像(灰度图像):每个像素由一个数值表示,代表该点的亮度。值越低(接近 0),颜色越暗;值越高(接近 255),颜色越亮。​
  • 多通道图像(彩色图像):在 OpenCV 中,默认情况下,彩色图像是以 BGR(蓝 - 绿 - 红)顺序存储

 

彩色图像​

每个像素通常是由红(R)绿(G)蓝(B)三个分量来表示的,分量介于 0 到 255 之间。RGB 图像每一个像素的颜色值(由 RGB 三原色表示)直接存放在图像矩阵中,由于每一像素的颜色需由 R、G、B 三个分量来表示,所以三个 M x N 的二维矩阵分别表示各个像素的 R、G、B 三个颜色分量(其中 M、N 分别表示图像的行列数)。RGB 图像的数据类型一般为 8 位无符号整形,通常用于表示和存放彩色图像。​

例如,生成一个 512x512 大小的彩色图片,每一个像素点为随机颜色的代码如下:

import cv2
import numpy as np

# 生成一个512x512的彩色图像(3通道),像素值为随机数
random_img = np.random.randint(0, 256, (512, 512, 3), dtype=np.uint8)

# 显示图像
cv2.imshow('Random Color Image', random_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 保存图像
cv2.imwrite('random_color_image.png', random_img)

效果如图:

五、 基本图像操作

1.创建窗体​

  • cv2.namedWindow (winname [, 窗口属性])​

使用 cv2.namedWindow() 方法创建一个新的窗口。你可以为这个窗口指定一个名称,并且可以选择窗口的属性(例如,是否可调整大小)。

参数:

  • winname:窗口名​
  • 窗口属性:窗口大小是否可调整​
  • cv2.WINDOW_AUTOSIZE:默认,窗口会根据加载的图像自动调整到合适的大小,并且用户不能拖动窗口边缘来调整窗口大小。​
  • cv2.WINDOW_NORMAL:窗口大小是可调整的,用户可以通过鼠标拖动窗口边缘来自由改变窗口大小。

示例代码:

import cv2

# 创建一个可调整大小的窗口
cv2.namedWindow('Resizable Window', cv2.WINDOW_NORMAL)
# 创建一个自动调整大小的窗口
cv2.namedWindow('Auto-size Window', cv2.WINDOW_AUTOSIZE)

# 显示窗口(这里只是创建窗口,没有显示图像,所以窗口会是空白的)
cv2.waitKey(0)
cv2.destroyAllWindows()

如图: 

     

    2.读取图像​

    • cv2.imread (path [, 读取方式])​

    参数:

    • filename:图像路径

    示例代码:

    import cv2
    
    # 以默认方式(彩色)读取图像
    color_img = cv2.imread('image.jpg')
    # 以灰度方式读取图像
    gray_img = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
    
    # 检查图像是否读取成功
    if color_img is None:
        print("无法读取彩色图像")
    if gray_img is None:
        print("无法读取灰度图像")

    路径说明:

    ./ 表示当前目录。

    ../ 表示当前目录的上一级目录(即父目录)。当你需要引用或访问当前目录所在位置的上一层目录中的文件或文件夹时使用 ../

    3.显示图像

    • cv2.imshow(winname,img)

      参数:

      • winname:显示图像的窗口名,以字符串类型表示

      • img:要显示的图像

      注意:在调用显示图像的API后,要调用cv2.waitKey(0)给图像绘制留下时间,否则窗口会出现无响应情况,并且图像无法显示出来。

      • cv.waitKey(0):表示无限期地等待任何键盘按键。这种用法常见于图像显示窗口中,确保图像在窗口中显示直到用户决定关闭它。

      • cv.waitKey(n):n>0,意味着程序将等待n毫秒。这种方式常用于视频播放或实时摄像头捕获场景,以便控制每一帧停留的时间,同时允许用户通过按键来中断循环或发出命令。

      • cv2.destroyAllWindows([winname])
        • cv2.destroyAllWindows():会在当前程序执行到该语句时立即销毁打开的窗口,并释放与这些窗口相关的资源。

        • winname:窗口名,关闭指定名称的窗口。可省略,销毁所有已打开的窗口。

     

    4.保存图像​

    • cv2.imwrite(path,img)​

    参数:

    • path:图片保存的路径和图片名​
    • img:要保存的图像

     示例代码:

    import cv2
    
    # 读取图像
    img = cv2.imread('image.jpg')
    
    # 保存图像
    success = cv2.imwrite('saved_image.jpg', img)
    if success:
        print("图像保存成功")
    else:
        print("图像保存失败")

     

    5.创建黑白图像​

    • 使用np.zeros()创建全黑图像,再修改像素值成为全白图像。​

    示例代码:

    import cv2
    import numpy as np
    
    # 创建一个512x512的全黑图像(单通道,灰度图)
    black_img = np.zeros((512, 512), dtype=np.uint8)
    # 创建一个512x512的全白图像(单通道,灰度图)
    white_img = np.ones((512, 512), dtype=np.uint8) * 255
    
    # 显示图像
    cv2.imshow('Black Image', black_img)
    cv2.imshow('White Image', white_img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    # 保存图像
    cv2.imwrite('black_image.jpg', black_img)
    cv2.imwrite('white_image.jpg', white_img)

    6.图像切片(图片剪裁)

    • OpenCV 中,图像切片用于从图像中提取一个子区域(矩形区域)。​
    • 假设你有一个图像img,它的类型是numpy.ndarray。img[y:y+h,x:x+w]的含义如下:​
    • x:子区域左上角的 x 坐标​
    • y:子区域左上角的 y 坐标​
    • w:子区域的宽度​
    • h:子区域的高度​
    • 切片操作:img[y:y+h,x:x+w]提取的是从(x,y)开始,高度为h,宽度为w的矩形区域​

    示例代码:

    import cv2 as cv
    cat = cv.imread("W3/D1/images/1.jpg")
    # 切片 arr[h1:h2,w1:w2]231:297,289:368
    ear = cat[84:231,241:405]
    
    cv.imshow("dst",ear)
    cv.waitKey(0)
    cv.destroyAllWindows()

    原图:

    裁剪后:

    可以看到,代码中的ear = cat[84:231,241:405] 就是选取的两个切点高度(height)与宽度(width),即图片的最左上角的像素点和最右下角的像素点

    \

    注意:​

    • 边界检查:确保(y,x)和(y+h,x+w)都在图像的边界内,否则会出现索引越界错误。​
    • 数据类型:img通常是numpy.ndarray类型,切片操作返回的也是numpy.ndarray类型。

    7.图像大小调整​

    • cv2.resize是 OpenCV 库中用于调整图像大小的函数,在图像处理中很常用,特别是在要对图像进行缩放以适应不同需求时。​
    • cv2.resize(img,dsize)

     示例代码:

    import cv2
    
    # 读取图像
    img = cv2.imread('image.jpg')
    
    # 检查图像是否读取成功
    if img is None:
        print("无法读取图像")
    else:
        # 调整图像大小为300x200
        resized_img = cv2.resize(img, (300, 200))
    
        # 显示原始图像和调整大小后的图像
        cv2.imshow('Original Image', img)
        cv2.imshow('Resized Image', resized_img)
        cv2.waitKey(0)
        cv2.destroyAllWindows()
    
        # 保存调整大小后的图像
        cv2.imwrite('resized_image.jpg', resized_img)

    六、图像绘制​

    1.绘制直线​

    • cv2.line(img,start,end,color,thickness)​

    参数:

    • img:要绘制直线的图像​
    • start、end:直线的起点和终点​
    • color:直线的颜色(对于彩色图像,使用 BGR 格式指定颜色)​
    • thickness:线条宽度

     

    示例代码:

    import cv2 as cv
    cat=cv.imread("W3/D1/images/1.jpg")
    cv.line(cat,(50,40),(80,40),(0,0,255),thickness=2)
    cv.imshow("myimg",cat)
    cv.waitKey(0)
    cv.destroyAllWindows()  

    结果: 

    2 绘制圆形​

    • cv2.circle(img,centerpoint,r,color,thickness)​​

    参数:

    • img:要绘制圆形的图片​
    • centerpoint、r:圆心和半径​
    • color:线条颜色​
    • thickness:线条宽度,为 - 1 时生成闭合图案并填充颜色​

    示例代码:

    import cv2 as cv
    cat=cv.imread("W3/D1/images/1.jpg")
    cv.circle(cat,(150,150),50,(255,0,0),6)
    cv.imshow("myimg",cat)
    cv.waitKey(0)
    cv.destroyAllWindows()  

    结果:

    其中cv.circle(cat,(150,150),50,(255,0,0),6)中标红的为线条的宽度参数,将其改为-1将会出现神奇的效果

    cv.circle(cat,(150,150),50,(255,0,0),-1)

    可以看到整片区域均被涂色

    PS: 仅能用于封闭图形

    3.绘制矩形​

    • cv2.rectangle(img,leftupper,rightdown,color,thickness)​

    参数: 

    • img:要绘制矩形的图像​
    • leftupper、rightdown:矩形的左上角和右下角坐标​
    • color:线条的颜色​
    • thickness:线条的宽度

    示例代码:

    import cv2 as cv
    cat=cv.imread("W3/D1/images/1.jpg")
    cv.rectangle(cat,(78,106),(237,306),(0,255,0),2)
    cv.imshow("myimg",cat)
    cv.waitKey(0)
    cv.destroyAllWindows()  

    结果:

    4.读取视频

    • cap = cv2.VideoCapture(path)​
    • path: 视频流资源路径,设置为 0 代表从默认摄像头捕获视频流​
    • ret,frame = cap.read()​
    • 返回值:cap 调用 read () 方法得到一个布尔值和一帧图像,布尔值表示是否成功读取到帧,如果为 False,可能是因为视频结束或读取失败,如果为 True,frame 则是当前帧的图像数据。​
    • 捕获摄像头的实时视频流示例代码:
    import cv2
    
    # 打开默认摄像头
    cap = cv2.VideoCapture(0)
    
    while True:
        # 读取一帧图像
        ret, frame = cap.read()
    
        # 如果读取失败,退出循环
        if not ret:
            break
    
        # 显示图像
        cv2.imshow('Camera', frame)
    
        # 按下'q'键退出循环
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    
    # 释放摄像头资源
    cap.release()
    # 销毁所有窗口
    cv2.destroyAllWindows()

     读取视频文件示例代码:

    import cv2
    
    # 打开视频文件
    cap = cv2.VideoCapture("video.mp4")
    
    while True:
        # 读取一帧图像
        ret, frame = cap.read()
    
        # 如果读取失败(视频结束),退出循环
        if not ret:
            break
    
        # 显示图像
        cv2.imshow('Video', frame)
    
        # 等待25毫秒,按下'q'键退出循环
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break
    
    # 释放视频文件资源
    cap.release()
    # 销毁所有窗口
    cv2.destroyAllWindows()

    此外还可以设置按键退出:

       # 等待25毫秒,按下'q'键退出循环
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break


    网站公告

    今日签到

    点亮在社区的每一天
    去签到