在本章,初步介绍OpenCV的一些基本操作,例如图片的读取以及图片格式的转换。1图片在计算机中的几种存储形式2图片的读取和延时操作3图片的各种输出形式
1.1 图片在计算机中的存储形式
即使我们对图片在计算机中的存储格式不是很清楚,也知道图片在计算机中是以二进制的形式存储的。图片如何转为二进制的形式在这里不进行详细说明,本节只讲程序像素X是如何以矩阵的形式进行图片的操作和相关运算的。
一张1024*960像素的图片,如果我们在程序里使用它或者对它进行一些操作,那么它就是一个960行,1024列的二维矩阵。矩阵的每一个元素存储的都是一个列表,而列表里面存储的则是各个通道的值,那什么是通道呢?
在讲通道之前,我们先了解一下图片的几种存储形式。
1.1.1 BGR图
我们平时在生活中拍摄的图片一般是RGB(R:红色,G:绿色,B:蓝色)格式的图片,在OpenCV中,图片常使用的格式是BGR的,两者本质上没有区别,只是使用的习惯不同。调节3中颜色的值可以构成不同颜色的像素点,但是我们在处理图片的时候,一般都不直接采用BGR图片进行操作,二十需要进行图片颜色格式的转换。
我们称B,G,R是图片上面每个像素点构成的通道,所以BGR图是一个三通道的图片。在OpenCV里,每个通道的取值范围是0~255,我们可以通过Python中元组的形式进行颜色的合成,如(255,255,255)为白色,(0,0,0)为黑色。
1.1.2 灰度图
相比BGR图,灰度图的每个像素点不再由B,G,R这3个通道构成,它只由一个通道来控制,即灰度值,所以灰度图是由灰度值来控制的单通道图。灰度值的取值范围为0~255;如果取哦,表示黑色;如果取255表示白色。
1.1.3 HSV图
HSV图显示出来也是彩色的,且HSV图也是由3个通道构成的,只不过HSV图里面的3个通道和BGR图中的不同,它的3个通道如下:
H:色彩或色度,它取值范围是0~179
S: 饱和度,它的取值范围是0~255
V: 亮度,它的取值范围是0~255
HSV其实也可以理解为RGB的另一种表达方式,这种表达方式更有利于我们对指定颜色的物体进行追踪和提取
1.1.4 二值图
二值图可以理解为一种很特殊的灰度图,它不具有通道,并且图中每个像素点的取值只是0或255,换句话,非黑即白。而灰度图与二值图不同的地方在于,灰度图可以取0~255的任何一个值。
二值图的意义在于他可以帮助用户去除图片的噪点,使得图片内只存在我们想要的那个物体的二值化表示部分。
1.2 图片的读取与写出
现在我们来介绍图片的读取以及写出,虽然这是OpenCV中非常基础的操作,但是它贯穿整个OpenCV的学习过程。
1.2.1 图片的读取
现在需要进行图片的读取,需要调用的函数是cv2.imread,它的语法如下。
cv2.imread(filename,flag=1)
其参数分别解释如下。
filename:读取图片的相对地址
flag:设置读取格式,默认为1,表示按照BGR三通道的方式进行读取,如果选择0,则以灰度图单通道的方式进行读取
示例代码如下:
import cv2
img=cv2.imread(“c://desktop/1.jpg”)
这个时候,img变量就已经是矩阵形式的“1.jpg"图片,并且她的每个像素点都是以BGR三通道的方式进行存储的。
如果我们想要以灰度图的方式读取图片,只需要将flag参数设置为0
img=cv2.imread(“c://desktop/1.jpg”,0)
此时,img变量中保存的就是单通道的”1.jpg" 图片的矩阵形式,矩阵的每个元素列表中只有一个灰度值。
1.2.2 图片的保存
接下来介绍图片的保存函数,也就是cv2.imwrite函数,语法如下:
cv2.imwrite(filename,img)
参数分别解释如下:
filename:要保存的图片名字,此处也是相对地址
img: 要保存的图片的矩阵形式
示例代码
import cv2
img=cv2.imread(“1.jpg”,0)
cv2.imwrite(“2.jpg”,img)
上诉代码就是将文件夹中1.jpg ,以矩阵的方式读取到程序中,然后将它以2.jpg为名字保存到所在文件夹中
1.2.3 BGR图的读取与写出
import cv2
img=cv2.imread(“1.jpg”,1)
cv2.imwrite(2.jpg,img)
等价于如下:
img=cv2.imread(“1.jpg”,cv2.IMREAD_COLOR)
cv2.imwire(“2.jpg”,img)
1.2.4 灰度图的读取与写出
import cv2
img=cv2.imread(“1,jpg”,0)
cv2.imwrite(“2.jpg”,img)
等价于
img=cv2.imread(“1,jpg”,IMREAD_GRAYSCALE)
cv2.imwrite(“2.jpg”,img)
1.2.5 图片展示
我们还没在程序运行的时候看到过图片,如果想在运行的时候看到图片的当前状态,需要使用cv2.imshow函数进行图片展示,如下
cv2.imshow(name,img)
参数
name:展示窗口的名字
img:图片的矩阵形式
如下函数
import cv2
img=cv2.imread(“1.jpg”)
cv2.imshow(“image”,img)
cv2.imwrite(“2.jpg”,img)
cv2.destroyAllWindows()
当我们在运行上述代码的时候,可以发现确实有一张图片弹出来了,但是很快就关闭了,原因在于cv2.imshow函数并没有延时的作用,可是计算机的运行速度比计算机窗口弹出速度快,所以窗口只是显示了极短的时间,代码已经执行完了,图片自动关闭。怎么才可以让图片窗口停留长呢?
很简单,既然cv2.imshow这个函数没有延迟作用,那么使用的函数的这行代码和下一行代码之间加一个延时函数就可以了
1.2.6 图片延时
现在我们在cv2.imshow所在的行和下一行代码之间加一个延时的函数来确保人眼能看清楚窗口。我们需要cv2.waitKey函数做到这一点,语法如下
cv2.waitKey(time)
其中,time表示等待的时间,单位为毫秒
这个函数是在time时间内,计算机会等待我们键盘上的命令,如果在time内程序没有等到按键指令它就自动进入下一帧。因为这个是图片没有下一帧,所以是自动关闭窗口,
如果我们把这个time 设置成0,并不是等待0 毫秒然后再执行下一帧,而是停止到当前帧,有案件指令它会进入下一帧。所以在显示单张图片的时候大多数写cv2.waitKey(0)
1.2.7
图片读取演示
介绍了如何添加延时函数后,我们尝试读取图片,示例代码
import cv2
img=cv2.imread(“1.jpg”)
cv2.imshow(“image”,img)
cv2.waitKey(0)
cv2.imwrite(“2.jpg”,img)
cv2.destoryAllwindows()
此时图片自动停留在桌面,按任意键图片消失,程序关闭。如果我们想通过添加某个特定键程序才关闭,可以通过添加一个if语句进行判定。如果按的键不为指定的键,键一直处于while循环中,直到摁到指定键,才会通过break语句结束循环,示例代码
import cv2
img=cv2.imread(“1.jpg”)
cv2.imshow(“image”,img)
while 1:
if cv2.waitKey(0)==ord(“q”):
break
else:
pass
cv2.waitKey(0)
cv2.imwrite(“2.jpg”,img)
cv2.destoryAllwindows()