OpenCV(3.2)+Python(3

2023-01-31 05:01:30 python opencv 3.2

  博主最近由于项目需求,需要学习OpenCV,在查看并试验了几种语言之后决定用python作为开发语言。刚开始学习也是各种网上找资料,但是网上的资料过于杂乱,最后还是觉得官方api最全面。所以博主梳理近期学习OpenCV官方文档的过程,并且用博客记录下来(官方文档的第一部分是关于opencv的安装,这里不做介绍,直接进入第二部分)。这篇博客先从OpenCV官方文档第二部分(Gui Features in OpenCV)开始,在这个部分官方文档给我们介绍了三个函数。


cv2.imread()

这个函数用来读取一副图像,第一个参数(必须传)可以是图片的相对路径或者绝对路径(如果你第一个参数传错,程序不会报错,但是函数的返回值会是None),第二个参数(可选)指定你要以何种方式读取图片,第二参数是个枚举值它可以是:
- cv2.IMREAD_COLOR:加载一张彩色图片,忽略它的透明度,在不传第二个参数时,它也是默认值。
- cv2.IMREAD_GRAYSCALE:加载灰度图。
- cv2.IMREAD_UNCHANGED:加载一张图片包含它的alpha通道(透明度),就是原图像不做改变的加载。

提示:如果你觉得上面三个枚举值很难记你可以简单的用1,0,-1代替。
具体请看下面的代码

 import numpy as np 
 import cv2

 #加载一张彩色图片不包含alpha通道
 img = cv2.imread('demo.jpg',1)

cv2.imshow()

这个函数用来在一个窗口中显示一幅图片,窗口自动适配图片的大小。
这个函数也接收两个参数,第一个参数是要承载图片的窗口名(字符串类型),第二个参数就是我们要显示的图片。只要每个窗口的名字不重复,我们可以创建多个窗口。
请看下面的代码片段

cv2.imshow('image',img)
cv2.waiTKEy(0)
cv2.destroyAllwindows()

在我的环境下(windows10 x64)运行结果如下:

读取到的图片

下面解释上面用到的一些函数

cv2.waitKey() 是一个键盘绑定函数。它的参数是一个毫秒数。这个函数等待特定的毫秒,如果在这个时间之内有按键按下,它就会返回相应按键的 ASCII 码(int 类型),然后程序继续运行,如果在给定的时间内没有任何按键按下它会返回 255(int 类型),然后程序继续运行。特别的,如果你传递一个0(或者一个负数)给这个函数,那么它会一直等待,直到有任何按键按下,然后程序继续运行。我们也可以只监视某些按键的按下而不是任意按键,这个我们在后面讨论。但是有一点必须注意,cv2.imshow()函数后面必须有cv2.waitKey()函数,否则图片不会显示。

cv2.destroyAllWindows() 将我们创建的所有窗口全部销毁。如果你想销毁任何特定的窗口,请使用 cv2.destroyWindow() 函数并将特定窗口的名字作为参数传递进去。

提示:有时候你可以事先创建好一个窗口后面再载入图片。在这种情况下你可以指定窗口是否可以调整大小,这要用到函数 cv2.namedWindow() 函数。默认状态下标志位是 cv2.WINDOW_AUTOSIZE 。但是你可以指定标志位为 cv2.WINDOW_NORMAL ,这样你就可以调整窗口的大小了。下表显示都有哪些标志位可供我们选择。

枚举值 表示的意思
WINDOW_NORMAL 用户可以调整窗口的大小,也可以将一个窗口从全屏窗口切换到普通窗口
WINDOW_AUTOSIZE 用户不能改变窗口的大小,窗口的大小被所展示的图片所约束
WINDOW_OPENGL opengl支持的窗口
WINDOW_FULLSCREEN 将窗口设置为全屏
WINDOW_FREERATio 扩展图片不考虑图片的分辨率
WINDOW_KEEPRATIO 扩展图片但考虑图片的分辨率
WINDOW_GUI_EXPANDED 带进度条和工具
WINDOW_GUI_NORMAL 旧方法

解释:经测试之后发现,第三个枚举值需要安装OPENGL的支持,后5个枚举值在效果上与WINDOW_NORMAL没有什么区别,如果有朋友对这个特别了解,欢迎讨论。

请看下面的代码

cv2.namedWindow('window_name',cv2.WINDOW_NORMAL)
cv2.imshow('window_name',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

cv2.imwrite()

这个函数用来保存一张图片。
第一个参数是保存之后文件的文件名(可以包含文件路径),第二个参数是你想要保存的图片。

cv2.imwrite('copy.png',img)

这样会保存一张 PNG 格式的图片在你的工作目录(就是跟你的.py文件在一个目录下)。

cv2.imwrite('..\copy.jpg',img)

这样会保存一张 JPG 格式的图片在你工作目录的上一级目录

或者你可以直接这样写

cv2.imwrite('C:\Program Files\opencv\copy.bmp',img)

这样就会在指定的位置保存一张 BMP 图片

注意:你总是需要指定文件的扩展名,虽然官方文档中说不写扩展名就会保存一张 PNG 文件在指定目录,但是实际测试这么做会报 (could not find a writer for the specified extension) 这个错误,告诉你指定的扩展名没有 writer 可以写出来,经测试主流的几种图片格式 (jpg,png,bmp) 都是支持的。第二点就是在你写文件路径的时候注意斜线的方向。

现在我们把之前的代码统一起来,下面这段代码首先以彩色忽略透明度的模式加载一张图片,然后显示图片,如果你按下 ‘s’ 键它会保存图片到指定位置后程序退出,如果按下 ‘esc’ 键那么不保存直接退出,如果按了别的键它会提示你,然后程序退出。

import numpy as np
import cv2

img = cv2.imread('demo.jpg',1)
cv2.imshow('image',img)
k = cv2.waitKey(0)
if( k== 27):
    cv2.destroyAllWindows()
elif( k==ord('s')):
    cv2.imwrite('copy.png',img)
    cv2.destroyAllWindows()
else:
    print('你没有按下S或者ESC,程序退出')
    cv2.destroyAllWindows()

提示:官方文档中说如果你使用64位的机器,你必须将 k=cv2.waitKey(0) 改为k=cv2.waitKey(0) & 0xFF,但是经过我的测试不修改程序仍然可以正常运行。

使用 Matplotlib(请参考Matplotlib Plotting Styles and Features)

Matplotlib 是Python的一个绘图库,它提供了大量的绘图方法。在后面的文章中我们也会遇到,现在我们来学习如何用 Matplotlib 来显示一张图片。你可以用它来放大、保存图片等等。

import numpy as np
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('demo.jpg',0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

运行之后结果如图

用matplotlib画的图

注意:在OpenCV中彩色图片是以BGR模式加载的,但在matplotlib中是以RGB模式。所以如果用OpenCV读取一张彩色图片在matplotlib中将无法正常显示。请参考这里的讨论试着理解它。

相关文章