openCV 学习日记(1)

绪言

咩哈哈哈哈哈,大家好呀,这里是一名已经放弃了ACM的中山大学大二学生。随着对智科的学习,对计算机视觉这一块也是越来越有兴趣了,目前学习的是基于Python的opencv3的计算机视觉学习,这一篇属于一个总览吧。基于的书为《OpenCV3计算机视觉Python语言实现》第二版,但是不得不说,这本书错误真的不少……而且代码好像是没有实测过的,得手动调一下bug。

OpenCV3简介

OpenCV是一个英特尔公司开发的计算机视觉库,其特点在于开源,封装程度高,易操作。

计算机视觉图片存储简介

数字图像,在计算机中是采用矩阵(Matrix)的形式进行存储的,每一张图像的每个像素点都会有一个矩阵进行存储颜色信息(比如采用RGB格式的,就会在每一个像素点放置一个3*1的矩阵)比如,我要创建一张3*3的8位图像,其语句如下:

img=numpy.zeros((3,3),dtype=numpy.uint8)

或者

img=numpy.array([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])

但后者一般用于卷积核的创建,卷积的概念将会在后面介绍高斯滤波器时说到。
对其进行print操作,可得:
[[0 0 0]
[0 0 0]
[0 0 0]]
这是一个8位图像,而我们知道,一张RGB图像应有24位(RGB三色各有8位),因此,我们可以用颜色转换函数cvtColor来进行转换:

img=cv2.cvtColor(img,cv2.COLOR_GRAY2BGR)

该函数的第一个参数是原图像文件,opencv的图像处理函数特点为,多数的图像处理函数都会直接覆盖掉原图像,不需要做备份(否则缓存区很容易爆掉)。第二个参数为设置位,cv2.COLOR_GRAY2BGR即为将灰度图转化为三原色彩色图像。

图像处理初步

通道

通道的定义

现在我们来了解一下通道的概念,我们知道,灰度图中只有一种原色:黑,对应一个颜色通道;而BGR三原色有三种基本色,因此对应三个通道。我们使用numpy创建图像矩阵时,是创立了一个有3*3的矩阵。而转换成BGR后,我们可以print一下新的图像来看看:
[[[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]]

[[0 0 0]
[0 0 0]
[0 0 0]]]
可以看到,图像矩阵原来的每个小矩阵被扩充为一个3*3的矩阵,因此,图像的大小变成了一个3*3*3的三层内嵌矩阵,其通道数自然就是3了。
查看图像形状的代码为

扫描二维码关注公众号,回复: 2750597 查看本文章
print(img.shape)

灰度图与三色图的转换

对于语句image[0,0]来说,其返回值为该(y,x)坐标对应像素的灰度值(对于灰度图来说)。而对于有多通道的BGR图像来说,image[0,0,0],第三个通道代表颜色通道。
比如,对于一张8位灰度图来说,若左上角为白色像素。则

>> print(img[0,0])
>> 255

而对于24位BGR图像而言,左上角为蓝色像素的图像则有:

>> print(img[0,0])
>> [255,0,0]
>> print(img[0,0,0])
>> 255

若一幅图像为灰度图(全部像素的通道均为8位),则可以转换为标准的一维Python Bytearray格式

byteArray=bytearray(iamge)

反过来,也可以通过显式转换,转换为numpy array:

grayImage=numpy.array(grayByteArray).reshape(height,weight)
bgrImage=numpy.array(bgrByteArray).reshape(height,weight,3)

图像的读与写

cv2.imread

OpenCV为我们封装了不同图像后缀名的文件处理方法,我们不需要关心要设置读取/写入函数的标志位来区分不同的图像后缀名。在OpenCV中,读取和写入的函数为

cv2.imread
cv2.imwrite

其原型为cv2.imread(filename,flags=None),第一个参数是文件名,而第二个就是读取/写入标志位。imread接受下列几个参数,此处列出几个常用参数:

参数名称 作用
IMREAD_ANYCOLOR 按原图像颜色格式读取
IMREAD_ANYDEPTH 按原图像深度信息读取,非16位或32位的则转化为8位
IMREAD_COLOR 转化为三通道图像
IMREAD_GRAYSCALE 转化为灰度图(8位),dtype=CV_8UC1
IMREAD_UNCHAGED 原样读取,不改变图像信息

无论采用哪种模式,imread()不会保留任何的alpha通道的信息。

cv2.imwrite

而写入函数的原型为cv2.imwrite(filename,mat),第一个参数为写入的文件名,第二个参数为图像矩阵。imwrite函数要求图像为BGR或者灰度格式,并且每个通道有一定的位(该位可以置零,但必须得有)。

numpy下的图像数据访问与修改

查询

我们从刚才的讨论中已经知道,图像矩阵一般都是用numpy.array类进行操作的。
比如,将一幅图的左上角变为白色像素

import cv2,os
import numpy as np
img=cv2.imread('MyPic.png')
img[0,0]=[255,255,255]

numpy里面还提供了两种方法:item和itemset来查询/改变特定像素的特定通道的值:

import cv2,os
import numpy as np
img=cv2.imread('MyPic.png')
print(img.item(150,120,0))
img.itemset((150,120,0),255)//将(150,120)的第0个通道(B通道)的值设置为255

但这些方法不用于实际,因为我们通常使用滤波器对大块大块的图像进行卷积处理而不使用像素来处理。
对于numpy.array库来说,它支持以下三种基本属性的查询:

参数名称 作用
shape 返回包含宽度、高度和通道数的数组(如果图像是彩色的),如果图象为单色图(灰度图也是单色图),将不返回通道数
size 返回图像像素的大小
dtype 得到图像的数据类型,常见的有uint8,uint16,uint32,uint64等

实测代码:

import cv2
import numpy as np
img=cv2.imread('Mypic.png')
print(img.shape,img.size,img.dtype)

运行结果:

运行代码后的结果

修改

numpy还支持使用切片的方式处理array:

import cv2
import numpy as np
img=cv2.imread('MyPic.png')
img[:, :, 1]=0

我们知道,在切片操作中,冒号表示某个范围,如果不设定数字,则是全范围切片,1代表的是第一个通道(G通道)。
这段代码的作用是去除该图像中所有的绿色。
numpy还可以进行区域替换操作

import cv2
import numpy as np
img=cv.imread('MyPic.png')
my_roi= img[0:100,0:100]// setting the 0-100*0-100 as the ROI(Region of Interest)
img[300:400,300:400]=my_roi //cover the 300-400 * 300-400 by ROI

猜你喜欢

转载自blog.csdn.net/weixin_40427089/article/details/81332182
今日推荐