计算机视觉(一) : 10分钟入门opencv
最近突然对计算机视觉感兴趣了,所以就自己摸索着学习一下,先来点有趣的吧,太难的还没学会,嘿嘿!!!
什么是计算机视觉呢?简而言之就是让计算机拥有人能所见、人能所识、人能所思的能力,就可以称计算机拥有视觉,即计算 机视觉。再说的直白一点就是让计算机能够识别图片和视频然后像人类大脑一样经过算法的处理可以获取需要的信息,并对图片和视频做出一些判断。
计算机视觉的应用
就目前所了解到的来讲,计算机主要有五大应用:
图像分类:图像分类架构--卷积神经网络(CNN)
目标检测:R-CNN
目标跟踪:均值漂移算法,即meanshift
语义分割:FCN
实例分割:Mask R-CNN
认识opencv
提到计算机视觉可能我们第一时间能想到的就是opencv库,opencv是C++写的代码,也是一个比较经典的图像处理库,从最经典的图像算法到非常前沿的 DL 预训练模型囊括了 CV 的很多方面,现在很多图像处理的库大都是基于opencv库开发的。但是opencv有一个致命缺陷,就是不可微分,所以就又出现了一种新型开源可微分计算机视觉库 Kornia,建立在 PyTorch 之上。感兴趣的小伙伴可以去github上看一下这个开源项目https://github.com/arraiyopensource/kornia我们先简单看一下opencv库处理图像的一些基础操作吧
图片读取
opencv库是一个跨平台的库,你可以用你擅长的语言去调用它,文章我用python,只需要调用cv2模块就行 python安装opencv模块很简单,一行命令就可以了
pip install opencv-python
利用cv2模块读取图片时一定要注意路径不能有中文,不然会读不出来先看一下cv2读取这张图片后的结果吧
import cv2
img= cv2.imread("data.jpg")
print(img)
#output
[[[238 239 243]
[239 240 244]
[240 241 245]
...
[247 247 247]
[247 247 247]
[247 247 247]]
...
[238 224 206]
[238 224 206]
[241 228 212]]]
我们都知道图片都是由像素点组成的,每个像素点都有RGB这三个颜色值组成,所以读取的图片返回是一个类似于上面的三维数组。这里我再解释一下imread()函数吧,这个函数原型是
imread(filename,flags)
后面的flags参数是个读取标记,用于选择读取图片的方式,默认值为IMREAD_COLOR,意思就是读取的图像一定要是3通道BGR彩色图像。flag值的设定与用什么颜色格式读取图片有关,至于有多少模式可以选择大家自己网上看一下opencv的资料就知道了,这里我不再介绍了。
图片灰度化
因为图片是三维的,每张图片的数据量就会很大,不方便处理,所以常常会转为灰度图做处理。什么是灰度图呢,就是在RGB模型中,如果R=G=B时,则彩色表示一种灰度颜色,其中R=G=B的值叫灰度值,这样得到的灰度图的每个像素点就只需要一个字节,不但节省了存储空间还方便处理。
import cv2
img= cv2.imread("1.jpg")
print(img)
img_gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
print(img_gray)
cv2.imshow('gray', img_gray)
# 等待键盘输入时中断,单位是毫秒,如果是0,无限等待,不然程序执行到show时,会发生肉眼看不见图片的现象
cv2.waitKey(0)
#output
[[240 241 242 ... 247 247 247]
[240 241 242 ... 247 247 247]
[240 241 242 ... 247 247 247]
...
[204 204 204 ... 225 220 219]
[204 204 204 ... 222 218 219]
[200 200 200 ... 220 220 225]]
我们可以看到,转为灰度的图片像素就变成二维的了
人脸识别
人脸识别是基于人的脸部信息特征进行身份识别的生物识别技术,也是当前很热门的一项计算机视觉研究领域。人脸识别需要大量数据进行训练,我们暂时先用安装cv2模块里已经训练好的数据集来测试吧,网上说haarcascade_frontalface_alt.xml这个数据集准确率比较高,为了方便使用,我们直接把这个数据集复制到工程同级目录
这里要注意一下,模块里的人脸检测目前只能检测正脸,并且图片必须是正的,就是图片上的人不能歪着头,不然就检测不到了,比如文章上面的那张图片就检测不到人脸
先看一下完整的代码
import cv2
img = cv2.imread('data.jpg')
# 人脸数据,级联分类器,给人脸特征数据,返回可以识别人脸的对象
detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
# 转换成灰度
gray = cv2.cvtColor(img, code=cv2.COLOR_BGR2GRAY)
# 使用训练好的识别人脸对象来识别人脸区域
# 后两个参数就是默认值,可以修改来调整识别人脸的精确度
face_zone = detector.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=3)
for x, y, w, h in face_zone:
# 在人脸上画一个正方形,画正方形只需要知道左上角和右下角坐标即可
cv2.rectangle(img, pt1=(x, y), pt2=(x+w, y+h), color=[0, 255, 0], thickness=2)
# 使用灰度图检测,绘制在彩色图片上
cv2.imshow('img', img)
cv2.waitKey(0)
这里主要给大家解释一下detectMultiScale()函数,这个函数原型是这样的:
def detectMultiScale(self, image, scaleFactor=None, minNeighbors=None, flags=None, minSize=None, maxSize=None)
image:这里一般是转换成灰度后的图片
scaleFactor:补偿参数,一般设置值为1.1-1.5比较好,效果大家自己改着看
minNeighbors:对当前其周围有多少物体进行定义
minSize:设定窗口大小
flags:略抽象,选择默认或者上图即可
废话不多说先给大家看一下效果
我们再来试试多人的图片识别效果
毕竟不是自己训练的数据集,所以结果差点意思,哈哈!!!不要在意细节 我们再试试人和动物能不能区分开
还是能区分开人脸和动物脸的,哈哈哈!!!
视频处理
视频本来就是由很多张图片组成的,就好比图片是由像素点构成的,两者是同样道理,只不过视频有音频加入,这里我们就先不说视频里的音频怎么处理,因为我也不会啊!!!先看一下整体代码吧
import cv2
# 读取本地视频
cap = cv2.VideoCapture("data.mp4")
w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) + 1 # 宽一点没问题,小了不行
h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) + 1
vidioWriter = cv2.VideoWriter('data2.mp4', cv2.VideoWriter_fourcc('M','P','4','v'), 24, (w, h)) # 要求int型
detector = cv2.CascadeClassifier('haarcascade_frontalface_alt.xml')
while cap.isOpened():
flag, frame = cap.read()
gray = cv2.cvtColor(frame, code=cv2.COLOR_BGR2GRAY)
face_zone = detector.detectMultiScale(gray, scaleFactor=1.3, minNeighbors=3)
for x, y, w, h in face_zone:
# 在人脸上画一个正方形,画正方形只需要知道左上角和右下角坐标即可
cv2.rectangle(frame, pt1=(x, y), pt2=(x + w, y + h), color=[0, 255, 0], thickness=2)
# 上面创建了写视频对象,仅需把每一帧写入即可
vidioWriter.write(frame)
if flag == False:
# 判断是否还能读取到帧,取不到则表示视频结束了,退出循环
break
cv2.imshow('frame', frame)
cv2.waitKey(20)
VideoWriter()函数
打开视频文件或摄像头视频需要使用Opencv中的VideoCapture类,保存视频或摄像头视频到本地磁盘,需要使用Opencv中的VideoWriter类,一般构造方式如下
VideoWriter(filename, fourcc, fps,frameSize, isColor=true);
filename: 是保存到本地后的视频的文件名 fourcc:表示用那种编码器,常用的有以下几种:
CV_FOURCC('P','I','M','1') = MPEG-1 codec
CV_FOURCC('M','J','P','G') = motion-jpeg codec
CV_FOURCC('M', 'P', '4', '2') = MPEG-4.2 codec
CV_FOURCC('D', 'I', 'V', '3') = MPEG-4.3 codec
CV_FOURCC('D', 'I', 'V', 'X') = MPEG-4 codec
CV_FOURCC('U', '2', '6', '3') = H263 codec
CV_FOURCC('I', '2', '6', '3') = H263I codec
CV_FOURCC('F', 'L', 'V', '1') = FLV1 codec
其中CV_FOURCC('M', 'P', '4', '2') 这种方式是占用空间最小的 fps:帧率,通常都会使用20-30 frameSize:每张图片的大小,以元组方式传参(w, h)
read( )函数
flag, frame = cap.read()
flag和frame接收返回值,flag是个布尔型值,表示是否读取到帧,frame为当前帧的数据
上面这两个函数理解了,那么视频中的人脸识别就好理解了,就是获取每一帧的图片然后利用人脸检测标注画个方框,然后我每一帧之间有个20ms等待时间,这样合起来就是一个视频,来看看我们的输出结果
好像还是有点小误差哈,这篇文章里面视频处理其实就是分解为图片的进行处理。
至于图像及视频处理的原理及算法等后面我学会了再分享给大家,有兴趣的小伙伴也可以一起交流一下