大众号:尤而小屋
作者:Peter
编辑:Peter

咱们好,我是Peter~

工作的原因,最近开始涉及到很多图画处理的工作,所以决议拓荒一个新专栏:OpenCV入门教程系列

教程从零开始,记载自己的学习历程,欢迎关注本专栏,精力有限,确保周更至少一篇。假如文章中有误或许更好的办法,欢迎咱们提出来,一同学习~

本文是第一篇,主要是介绍OpenCV和图片的根底操作,比如图片的存储方法、格局以及图片的读取、写入、显现等。

图画概述

图画是一种以二维或三维方法存在的数据调集,用于表明对象的视觉信息。依据不同的分类办法,图画能够分为静态图画和动态图画、灰度图画和五颜六色图画等。

  • 静态图画是指不随时刻改动的图画
  • 动态图画则会跟着时刻的改动呈现出不同的视觉效果
  • 灰度图画只包含亮度信息
  • 五颜六色图画则包含了亮度和颜色信息

在实践运用中,依据不同的需求,人们会选择不同类型的图画进行处理和剖析。

OpenCV介绍

OpenCV(Open Source Computer Vision Library)是一个跨渠道的计算机视觉库,供给了丰厚的函数和东西,用于处理和剖析图画和视频数据。它是由英特尔公司开发的,现在现已成为全球规模内广泛运用的计算机视觉领域的重要东西。

OpenCV的主要方针是供给一种简略、高效和可扩展的方法来处理图画和视频数据。它支撑各种常见的图画处理和计算机视觉算法,包括图画滤波、图画切割、特征提取、方针检测、人脸辨认等。

OpenCV还供给了丰厚的接口和东西,能够与其他编程语言和框架进行集成,如Python、C++、Java等。它还支撑各种常见的硬件加速技术,如GPU加速和多核处理器,能够显著提高图画处理和计算机视觉算法的性能和功率。

除此之外,OpenCV还供给了很多的示例代码和教程,能够帮助开发人员快速入门和学习运用OpenCV库。它仍是一个开源项目,具有活泼的社区支撑和文档库,能够供给继续的技术支撑和改善。

运用领域

  • 人机互动:比如人机交互
  • 物体辨认:根据视觉对物体进行判别
  • 图画切割:ROI(Region of Interest,感兴趣区域)技术
  • 人脸辨认:经过Haar级联来完成
  • 动作辨认:主要是2D和3D动作辨认
  • 运动追踪、计算机视觉、图画标示、方针检测等

装置opencv-python

OpenCV-python是OpenCV库的Python接口,它供给了在Python中运用OpenCV的功用和东西。OpenCV-python是OpenCV官方支撑的Python绑定,能够轻松地在Python中运用OpenCV的图画处理和计算机视觉功用。

经过运用OpenCV-python,开发人员能够运用Python语言来编写计算机视觉运用,然后提高了代码的可读性和易用性。它还供给了与OpenCV C++接口类似的API,使得开发人员能够轻松地从C++代码迁移到Python代码。

此外,OpenCV-python还支撑各种常见的Python框架和库,如NumPy、Pandas、Matplotlib等,这些库能够与OpenCV-python无缝集成,然后提高了开发人员的工作功率和代码质量。

总归,OpenCV-python是一个功用强大的Python计算机视觉库,它为开发人员供给了一种简略、高效和可扩展的方法来处理图画和视频数据。

装置:

pip install opencv-python

OpenCV常用python内置函数

ord函数

将键盘输入的字符(长度为1)转成ASCII码

In [1]:

ord("a")

Out[1]:

97

In [2]:

ord("b")

Out[2]:

98

In [3]:

ord("A")

Out[3]:

65

max/min函数

对含有噪声的图片进行去噪处理

In [4]:

max(["a","B"])

Out[4]:

'a'

In [5]:

max(["a","B"], key=str.upper)  # 先统一转成大写

Out[5]:

'B'

sorted函数

排序功用,提高程序中图片抗枯燥才能。

In [6]:

sorted([1,4,5,3,2])

Out[6]:

[1, 2, 3, 4, 5]

In [7]:

sorted([1,4,5,3,2],reverse=True)

Out[7]:

[5, 4, 3, 2, 1]

图片存储方法

图片在计算机中是以二进制的方法进行存储的。先了解图片的几种存储方法:

BGR图

BGR图是一种常见的图画表明方法,其间每个像素点由蓝(Blue)、绿(Green)和红(Red)三个颜色通道的值组成。在BGR图中,每个通道的值一般选用整数或浮点数来表明,取值规模因不同格局而异。

生活中图片一般是RGB方法(R: 赤色Red,G:绿色green,B: 蓝色Blue)。OpenCV中运用的BGR格局,其间每个像素点由蓝(Blue)、绿(Green)和红(Red)三个颜色通道的值组成。

在实践中不直接运用BGR,而是进行图片颜色格局的转化。B、G、R为图片上每个像素点构成的通道,所以每个BGR图示一个蓝绿红3种通道的图片。

通道的取值是0~255,python中经过元组的方法来表明,如(255,255,255)表明白色,(0,0,0)表明黑色

灰度图

灰度图的每个像素点不再由BGR3个通道组成,仅由一个通道组成,即灰度值。灰度值的取值规模:0~255,其间0表明黑色,255表明白色

HSV图

HSV图显现出来的图也是五颜六色的,也是3个通道组成,介绍如下:

  • H:颜色或许色度,取值规模0~179
  • S:饱和度,取值规模0~255
  • V:亮度,取值规模0~255

二值图

一种特别的灰度图,没有通道的概念,并且图中每个像素点的取值只要0或许255两个值,能够了解成非黑即白。

二值图能够帮助去除图片中的噪点,使得图片内只存在咱们想要的二值化表明部分。

图片读取和保存

图片格局

cv2.imread函数是OpenCV库中用于读取图画文件的函数,它能够读取多种静态图画格局,包括但不限于以下几种:

  • BMP(Windows位图)格局:这是一种无紧缩的图画格局,广泛用于Windows系统。
  • JPEG(联合图画专家组)格局:这是一种紧缩的图画格局,广泛运用于互联网和数字相机。
  • PNG(可移植网络图形)格局:这是一种无损紧缩的图画格局,支撑透明度通道,适用于网络传输和存储。
  • GIF(图形交换格局)格局:这是一种支撑动态图画和透明度通道的图画格局,常用于动画和演示。
  • TIFF(标记图画文件格局)格局:这是一种通用的图画格局,支撑多种图画紧缩和颜色方式,广泛运用于出书、印刷和其他职业。

除了以上常见的图画格局,cv2.imread函数还能够读取其他一些不常用的图画格局,如:

  • PBM(Portable Bitmap)格局:这是一种简略的无紧缩二进制图画格局,一般用于存储是非图画。
  • PGM(Portable Graymap)格局:这也是一种简略的无紧缩二进制图画格局,一般用于存储灰度图画。
  • PPM(Portable Pixmap)格局:这是一种简略的无紧缩二进制图画格局,一般用于存储五颜六色图画。 需求留意的是,不同的图画格局或许具有不同的紧缩方法和颜色方式,cv2.imread函数默许会读取一切像素信息,但有时或许需求运用不同的参数来操控读取的方法,例如设置cv2.IMREAD_GRAYSCALE参数来读取灰度图画,或设置cv2.IMREAD_COLOR参数来读取五颜六色图画(默许状况下会忽略透明度通道)。

读取cv2.imread

cv2.imread(filname, flags=1)
  • filename:所要读取的图片的相对地址
  • flags:读取的格局,默许是1,表明依照BGR三通道的格局读取;假如设置为0,表明依照灰度图单通道的方法来读取

In [8]:

import numpy as np
import cv2
# img = cv2.imread("pictures/a.png",flags=1)  # 默许是1 
img = cv2.imread("pictures/a.png")  # 默许是BGR,3通道方法读取
img[:2]

Out[8]:

array([[[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]],
       [[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]]], dtype=uint8)

介绍另外一种读取的方法:写入的参数是cv2.IMREAD_COLOR

In [9]:

img = cv2.imread("pictures/a.png", cv2.IMREAD_COLOR)
img[:2]

Out[9]:

array([[[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]],
       [[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]]], dtype=uint8)

读取BGR图的三种等效方法:

cv2.imread("pictures/a.png",flags=1)
cv2.imread("pictures/a.png")
cv2.imread("pictures/a.png",cv2.IMREAD_COLOR)

In [10]:

# 灰度图的方法来读取
img1 = cv2.imread("pictures/a.png",flags=0)
img1

Out[10]:

array([[93, 93, 93, ..., 93, 93, 93],
       [93, 93, 93, ..., 93, 93, 93],
       [93, 93, 93, ..., 93, 93, 93],
       ...,
       [74, 74, 74, ..., 68, 68, 68],
       [74, 74, 74, ..., 68, 68, 68],
       [74, 74, 74, ..., 68, 68, 68]], dtype=uint8)

灰度图的另外一种读取方法,写入参数:cv2.IMREAD_GRAYSCALE

In [11]:

img1 = cv2.imread("pictures/a.png", cv2.IMREAD_GRAYSCALE)
img1

Out[11]:

array([[93, 93, 93, ..., 93, 93, 93],
       [93, 93, 93, ..., 93, 93, 93],
       [93, 93, 93, ..., 93, 93, 93],
       ...,
       [74, 74, 74, ..., 68, 68, 68],
       [74, 74, 74, ..., 68, 68, 68],
       [74, 74, 74, ..., 68, 68, 68]], dtype=uint8)

读取灰度图的两种方法:

# 两种等价的方法
cv2.imread("pictures/a.png",flags=0)
cv2.imread("pictures/a.png", cv2.IMREAD_GRAYSCALE)

保存cv2.imwrite

运用函数cv2.imwrite():

cv2.write(filaname,img)
  • filename:要保存图片的名字
  • img:要保存的图片的矩阵方法

In [12]:

img[:2]

Out[12]:

array([[[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]],
       [[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]]], dtype=uint8)

In [13]:

cv2.imwrite("./pictures/new_a.jpg",img)

Out[13]:

True
# 完整代码为
import numpy as np
import cv2
# 先读取
img = cv2.imread("pictures/a.png")  # 默许是BGR-3通道读取
# 中间或许很多处理
# 保存
cv2.imwrite("./pictures/new_a.jpg",img)

图片显现(根据cv2)

在读取完图片后,怎么将图片展示出来进行可视化?运用cv2.imshow()

图片显现cv2.imshow()

In [14]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png", cv2.IMREAD_COLOR)  # 读取图片
cv2.imshow("image", img)   # 显现
# cv2.imwrite("pictures/new_a1.png", img)   写入保存
cv2.destroyAllWindows()  # 炸毁函数cv2.destroyAllWindows()

在这里留意两点:

  1. cv2.imshow()用来显现图片,但没有延时效果,此刻仍然没看到图
  2. 假如运用了cv2.imshow,一定加上这个炸毁函数cv2.destroyAllWindows()

图片延时cv2.waitKey(time)

函数的运用:

cv2.waitKey(time)

time表明等候的时刻,单位是毫秒。函数表明在给定的time时刻内等候用户按键的触发。

假如time=0,表明停止在当前帧,有按键指令的时分进入下一帧。假如是单张图片,一般写作:cv2.waitKey(0)

留意:函数的后边是否需求加上&0xff。完整写法为:cv2.waitKey(1000) & 0xFF

延时后图片显现

(1)time=0表明图片已显现,恣意按键下退出

In [15]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png", cv2.IMREAD_COLOR)  # 读取
cv2.imshow("image", img)   # 显现
cv2.waitKey(0)  # 延时
# cv2.imwrite("pictures/new_a1.png", img)   写入
cv2.destroyAllWindows()  # 炸毁

(2)在指定的按键下退出

此刻图片现已逗留,恣意按键即可关闭程序。假如指定特别按键,运用if语句进行判别:只要输入q键才会退出。

In [16]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png",flags=1)
cv2.imshow("image", img)
while True:
    if cv2.waitKey(0) == ord("q"):  # 只要在q键下才会退出
        break
    else:
        pass
cv2.imwrite("new_a.png",img)  # 写入
cv2.destroyAllWindows()

(3)在指定的条件下退出程序和保存图片:

In [17]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png",flags=1)
cv2.imshow("image", img)
while True:
    if cv2.waitKey(0) == ord("q"):  # 只要在q键下才会退出
        break
    if cv2.waitKey(0) == ord("s"):
        cv2.imwrite("new_a.png",img)  # 输入s进行图片写入
        break
cv2.destroyAllWindows()

(4)指定时刻下退出程序

In [18]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png",flags=1)
cv2.imshow("image", img)
if cv2.waitKey(5000) & 0XFF == ord("s"): # 要点
    cv2.imwrite("new_a.png",img) 
cv2.destroyAllWindows()

要点代码解说:假如5秒内没有按键s,则程序将会主动退出。

图片显现(根据matplotlib)

matplotlib中显现图片是以RGB的格局进行显现的,OpenCV默许是以BGR格局。假如是经过cv2读取的图片,需求进行格局转化。

In [19]:

# 读取图片cv2 + 显现图片matplotlib
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
 # BGR格局-三通道读取
img = cv2.imread("pictures/a.png") 
# 转成RGB格局
img2 = img[:,:,::-1]  # 通道翻转
plt.imshow(img2)
plt.show()

OpenCV入门教程:图片读取、保存和显示

介绍另外一种写法:

In [20]:

# 读取图片cv2 + 显现图片matplotlib
import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(10,6))
 # BGR格局-三通道读取
img = cv2.imread("pictures/a.png") 
img_new = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.imshow(img_new)
plt.show()

OpenCV入门教程:图片读取、保存和显示

图片巨细cv2.namedWindow

上面介绍了图片的读取、写入和显现,下面介绍怎么操控图片窗口显现的巨细。

窗口的巨细取决于图片的巨细。

操控窗口巨细的函数:cv2.namedWindow。其初始设置的标签为:cv2.WINDOW_AUTOSIZE,改为cv2.WINDOW_NORMAL即可操控窗口的巨细。

In [21]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png",flags=1)
cv2.namedWindow("image", cv2.WINDOW_AUTOSIZE)  # 要点:一定在imshow前面
cv2.imshow("image", img)
if cv2.waitKey(5000) & 0XFF == ord("s"): 
    cv2.imwrite("new_a.png",img) 
cv2.destroyAllWindows()

关于cv2.namedWindow的其他参数解说:

# 窗口巨细可改动
cv2.namedWindow("image",cv2.WINDOW_NORMAL)
cv2.namedWindow('image',cv2.WINDOW_GUI_NORMAL)
# 窗口巨细不可改动
cv2.namedWindow("image",cv2.WINDOW_AUTOSIZE)
# 窗口巨细自适应份额
cv2.namedWindow("image",cv2.WINDOW_FREERATIO)
# 窗口巨细保持份额
cv2.namedWindow("image",cv2.WINDOW_KEEPRATIO)    
# 显现颜色变成
cv2.namedWindow('image',cv2.WINDOW_GUI_EXPANDED)

改动窗口巨细resizeWindow

In [22]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png",flags=1)
cv2.namedWindow("image",0)
cv2.resizeWindow("image",400,300)  # 黑色窗口巨细
cv2.imshow("result",img)  # 显现图片
if cv2.waitKey(5000) & 0XFF == ord("s"): 
    cv2.imwrite("new_a.png",img) 
cv2.destroyAllWindows()

图片特点

OpenCV中图片是以矩阵的方法存储的。下面介绍计算机视觉中常用的图片特点:

  • 行数
  • 列数
  • 通道数

In [23]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png")
img[:2]

Out[23]:

array([[[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]],
       [[169,  92,   0],
        [169,  92,   0],
        [169,  92,   0],
        ...,
        [169,  92,   0],
        [169,  92,   0],
        [169,  92,   0]]], dtype=uint8)

查看整个图片的行数、列数和通道数:

In [24]:

img.shape  # 整体状况,元组方法

Out[24]:

(733, 978, 3)

In [25]:

img.shape[0]  # 行数

Out[25]:

733

In [26]:

img.shape[1]  # 列数

Out[26]:

978

In [27]:

img.shape[2]  # 通道数

Out[27]:

3

上面是以BGR格局读取的图片,假如换成以灰度图读取呢?

In [28]:

import cv2
import numpy as np
img = cv2.imread("pictures/a.png",flags=0)

In [29]:

img.shape

Out[29]:

(733, 978)

能够看到灰度图的shape值只会回来图片的行数和列数,不会回来通道数。二值图是一种特别的灰度图,也不会回来通道数。

总结

常用根本函数的总结:

import cv2
import numpy as np
# 读取BGR图
cv2.imread("pictures/a.png",flags=1)
cv2.imread("pictures/a.png")
cv2.imread("pictures/a.png",cv2.IMREAD_COLOR)
# 读取灰度图
cv2.imread("pictures/a.png",flags=0)
cv2.imread("pictures/a.png", cv2.IMREAD_GRAYSCALE)
# BGR和RGB通道转化
img_new = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)  
img_new = img[:,:,::-1]
cv2.write(filaname,img)  # 写入
cv2.imshow("img",img)  # 显现
cv2.waitKey(time) &0XFF  # 延时等候   
cv2.destroyAllWindows()  # 炸毁函数