前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >计算机视觉:1.1~2.5 初等概念及OpenCV的使用

计算机视觉:1.1~2.5 初等概念及OpenCV的使用

作者头像
DioxideCN
发布2022-08-05 18:42:48
1.3K0
发布2022-08-05 18:42:48
举报
文章被收录于专栏:用户4480853的专栏

1.1~2.5 初等概念及OpenCV的使用

1.1 机器视觉介绍

现在说的机器视觉(Machine Vision)一般指计算机视觉(Computer Vision),简单来说就是研究如何使机器看懂东西。就是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等机器视觉,并进一步做图形处理,使电脑处理成为更合适人眼观察或传送给仪器检测的图像。

在上面的讨论中,计算机视觉(computer vision)和机器视(machine vision)两个术语是不加以区分的,在很多文献中也是如此。但其实这两个术语既有区别又有联系。计算机视觉是采用图像处理、模式识别、人工智能技术相结合的手段,着重于一副或多副图像的计算机分析。图像可以有单个或者多个传感器获取,也可以是单个传感器在不同时刻获取的图像序列。分析是对目标物体的识别,确定目标物体的位置和姿态,对三维景物进行符号描述和解释。在计算机视觉研究中,经常使用几何模型、复杂的知识表达,采用基于模型的匹配和搜索技术,搜索的策略常使用在自底向上、自顶向下、分层和启发式控制策略。机器视觉则偏重于计算机视觉技术工程化,能够自动获取和分析特定图像,以控制相应的行为。具体地说,计算机视觉为机器视觉提供图像和景物分析的理论以及算法基础,机器视觉为计算机视觉的实现提供传感器模型、系统构造和实现手段。因此可以认为,一个机器视觉系统就是一个能自动获取一副或多幅目标物体图像,对所获取图像的各种特征量进行处理、分析和测量,并对测量结果做出定性分析和定量解释,从而得到有关目标物体的某种认识并做出相应决策的系统。计算机视觉系统的功能包括:物体定位、特征测量、缺陷判断、目标识别、技术、运动跟踪。

计算机视觉的应用

  1. 物体识别:人脸识别、测量检测;
  2. 识别图像中的文字(OCR);
  3. 图像拼接、修复、背景替换;

1.2 OpenCV介绍

  • Gray Bradsky 于 1999 年开发,2000 年发布
  • C++,Python,Java,JS,C#,Ch,Ruby,Go
  • 跨平台(Windows,Linux,Mac …)

为什么使用Python:

  • Python语言简单,开发速度快
  • 底层使用C/C++,速度有保障
  • 有完整的生态链

学习目标:

  • 了解OpenCV的运行机制
  • 可以使用OpenCV处理一些图像常见问题
  • 学会物体识别,文字识别等问题的处理思路

1.3 安装OpenCV环境

进入虚拟环境,执行命令:

代码语言:javascript
复制
pip3 install opencv-python opencv-contrib-python jupyter matplotlib -i https://pypi.douban.com/simple

如果安装不了需要手动下载:https://www.lfd.uci.edu/~gohlke/pythonlibs 检查安装(进入venv环境):

代码语言:javascript
复制
% ipython
In [1]: import cv2
In [2]: cv2.__version__
Out[2]: '4.6.0'
In [3]: exit()

如果出现 Out[2]: '4.6.0' 则说明安装且导入成功。

1.4 创建和显示窗口

  • namedWindow():创建命名窗口
  • imshow():显示窗口
  • destoryAllwindows():销毁窗口
  • resizeWindow():改变窗口大小
  • waitKey():等待用户输入 使用 Jupyter 进行编写 ipynb 文件:
代码语言:javascript
复制
jupyter

在Jupyter中新建文件“图像和视频的加载和显示”并写入代码块:

代码语言:javascript
复制
In[1]:
# opencv导包为cv2
import cv2

In[2]:
# 创建窗口
# cv2.WINDOW_AUTOSIZE不允许修改窗口大小
# cv2.namedWindow('window', cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('window', cv2.WINDOW_NORMAL)
# 更改窗口大小
cv2.resizeWindow('window', 800, 600)
# 展示名字为window的窗口
cv2.imshow('window',0)

# 等待按下键盘
# 返回按下键的ASCII码
# 0表示接收任意按键,如果给其他整数,表示等待按键的时间,单位ms
# 可以利用waitKey来销毁窗口,不用每次都重启python
key = cv2.waitKey(0)
# key是int型,最少都是16位,但是ASCII是8位
if key & 0xFF == ord('q'):
    print('准备销毁窗口')
    cv2.destroyAllWindows()

In[3]:
# 怎么计算Q的ASCII码
# ord('q')函数是python中计算ASCII值的函数

In[1] 开始运行代码即可看到弹出的窗口。

1.5 显示图像

  • imread(path, flag):使用imread可以读取图片,默认读取的是彩色图片,比如:
代码语言:javascript
复制
# 导入opencv包
import cv2
import numpy as np
from matplotlib import pyplot as plt

# 读取图片
doge = cv2.imread('./doge.jpg')
# doge输出numpy的ndarray dtype=uint8 cat.max()=2^8-1
doge.max()
plt.imshow(doge)

其中,使用 cv2.imread('./doge.jpg') 方法读取图片显示如下:

Pasted image 20220704182852
Pasted image 20220704182852

使用 plt.imshow(doge) 方法读取图片显示如下:

Pasted image 20220704182822
Pasted image 20220704182822

其中狗的颜色发生了改变,这是因为OpenCV读取图片的颜色通道按照BGR(蓝绿红)排列的,一般图片通道都是按照RGB来排列的。为了正常显示猫的图片,要使用OpenCV的图像显示方法:

代码语言:javascript
复制
cv2.imshow('doge', doge)
cv2.waitKey(0)
cv2.destroyAllWindows()

可以将其其为一个函数来显示图片

代码语言:javascript
复制
def cv_show(name, img):
	cv2.imshow(name, img)
	cv2.waitKey(0)
	cv2.destroyAllWindows()

2.1 保存图片

  • imwrite(path, img):使用imwrite保存图片
代码语言:javascript
复制
import cv2

cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', 320, 240)

img = cv2.imread("./doge.jpg")

# 利用while循环优化退出逻辑
while True:
	cv2.imshow('img', img)
	key = cv2.waitKey(0)
	if key & 0xFF == ord('q'):
		break
	elif key & 0xFF == ord('s'):
		cv2.imwrite("./123.png", img)
	else:
		print(key)
cv2.destroyAllWindows()

保存后文件目录如下:

Pasted image 20220706142906
Pasted image 20220706142906

2.2 读取摄像头和视频数据

视频采集

  • 视频是由图片组成的,视频的每一帧就是一副图片,一般30帧,表示一秒显示30张图片。
  • cv2.VideoCapture可以捕获摄像头,用数字来表示不同的设备,比如:0、1。
  • 如果是视频文件,可以直接指定路径即可。
代码语言:javascript
复制
# 打开视频文件
vc = cv2.VideoCapture('./1.mp4')
# 打开摄像头
vc = cv2.VideoCapture(0)

读取摄像头

代码语言:javascript
复制
# 打开摄像头
import cv2

cv2.namedWindow('video', cv2.WINDOW_NORMAL)
cv2.resizeWindow('video', 640, 480)
cap = cv2.VideoCapture(0)
# 循环读取摄像头的每一帧
while True:
    # 读取一帧数据,返回标记,True表示读到了数据反之亦然,和这一帧的数据
    ret, frame = cap.read()
    # 根据ret做出判断
    if not ret:
        # 没读到数据
        break
    # 读到了数据就显示
    cv2.imshow('video', frame)
    
    key = cv2.waitKey(10)
    if key & 0xFF == ord('q'):
        break
# 释放资源
cap.release()
cv2.destroyAllWindows()

若设备没有摄像头或打开摄像头失败,程序会直接退出而非报错。这时需要检测是否正确打开摄像头:

代码语言:javascript
复制
if vc.isOpened():
	# 读取视频的一帧
	open, frame = vc.read()
else:
	open = False

读取视频

代码语言:javascript
复制
# 打开视频
import cv2

cv2.namedWindow('mp4', cv2.WINDOW_NORMAL)
cv2.resizeWindow('mp4', 640, 480)
cap = cv2.VideoCapture('./1.mp4')
# 循环读取摄像头的每一帧
while True:
    # 读取一帧数据,返回标记,True表示读到了数据反之亦然,和这一帧的数据
    ret, frame = cap.read()
    # 根据ret做出判断
    if not ret:
        # 没读到数据
        break
    # 读到了数据就显示
    cv2.imshow('video', frame)
    
    key = cv2.waitKey(10)
    if key & 0xFF == ord('q'):
        break
# 释放资源
cap.release()
cv2.destroyAllWindows()
Pasted image 20220706145720
Pasted image 20220706145720

视频被加速的原因:cv2.waitKey(10) 使得视频每一帧的间隔缩短至了10毫秒。 考虑问题:假如一个视频为30FPS那么每张图之间的间隔为多少毫秒?

⌊100030⌋=⌊1003⌋\lfloor \frac{1000}{30} \rfloor = \lfloor \frac{100}{3} \rfloor ⌊301000​⌋=⌊3100​⌋

必须向下取整计算

代码语言:javascript
复制
# 30fps
key = cv2.waitKey(1000 // 30)

2.3 录制视频

  • VideoWriter:参数一为输出文件、参数二为多媒体文件的格式(VideoWriter_fourcc对象),参数三位帧率,参数四为分辨率。
  • write:编码写入缓存。
  • release:缓存内容写入磁盘,并释放资源。

OpenCV可以将打开的视频或摄像头中的每一个画面保存到新的视频流中。 * 注:这里的(1920, 1080)以 MacBook Pro 16 英寸 M1 2021 的FaceTime高清摄像头为准。

代码语言:javascript
复制
# 摄像头录制视频
cap = cv2.VideoCapture(0)
# *mp4v就是解包操作 等同于 'm', 'p', '4', 'v'
# avi 格式为 XVID
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
# (1920, 1080)表示摄像头拍视频的分辨率,大小错了就不行了
vw = cv2.VideoWriter('output.mp4', fourcc, 20, (1920, 1080))

# vw = cv2.VideoWriter('output.mp4', cv2.VideoWriter_fourcc(*'mp4v'), 20, (1920, 1080))

while cap.isOpened():
	ret, frame = cap.read()
	if not ret:
		print('摄像头未开启')
		break

	vw.write(frame)
	cv2.imshow('frame', frame)

	# 这里的1毫秒决定了根本帧率,需要使用 1000//30
	if cv2.waitKey(1) & 0xFF == ord('q'):
		break

# 释放资源
cap.release()
vw.release()
cv2.destroyAllWindows()
Pasted image 20220706204345
Pasted image 20220706204345

2.4 控制鼠标

OpenCV允许我们对窗口上的鼠标动作做出响应

  • setMouseCallback(winname, callback, userdata)
    • winname:窗口名字
    • callback:回调函数名
    • userdata:传递给回调函数的参数列表
  • callback(event, x, y, flags, userdata)
    • 回调函数必须包含这五个参数
    • event:鼠标事件(左键、右键、滚动、移动等操作事件)
    • x,y:鼠标的位置坐标
    • flags:主要用于组合键
    • userdata:为上面的setMouseCallback的userdata

鼠标动作事件

事件名

事件值

操作

EVENT_MOUSEMOVE

0

鼠标移动

EVENT_LBUTTONDOWN

1

按下鼠标左键

EVENT_RBUTTONDOWN

2

按下鼠标右键

EVENT_MBUTTONDOWN

3

按下鼠标中键

EVENT_LBUTTONUP

4

左键释放

EVENT_RBUTTONUP

5

右键释放

EVENT_MBUTTONUP

6

中键释放

EVENT_LBUTTONDBLCLK

7

左键双击

EVENT_RBUTTONDBLCLK

8

右键双击

EVENT_MBUTTONDBLCLK

9

中键双击

EVENT_MOUSEWHEEL

10

鼠标滚轮上下滚动

EVENT_MOUSEHWHEEL

11

鼠标滚轮左右滚动

Flags组合键

事件名

事件值

操作

EVENT_FLAG_LBUTTON

1

按下左键

EVENT_FLAG_RBUTTON

2

按下右键

EVENT_FLAG_MBUTTON

4

按下中键

EVENT_FLAG_CTRLKEY

8

按下Ctrl键

EVENT_FLAG_SHIFTKEY

16

按下Shift键

EVENT_FLAG_ALTKEY

32

按下Alt键

代码语言:javascript
复制
# opencv控制鼠标
import cv2
import numpy as np

# 回调函数参数必须为5个
# event事件,xy坐标,flags第二组合键,userdata自定义数据
def mouse_callback(event, x, y, flags, userdata):
    print(event, x, y, flags, userdata)
    
# 创建窗口
cv2.namedWindow('mouse', cv2.WINDOW_NORMAL)
# 宽度(列数)和高度(行数)
cv2.resizeWindow('mouse', 640, 360)

# 绑定鼠标的回调函数
cv2.setMouseCallback('mouse', mouse_callback, '123')

# 生成全黑的图片(先行后列)
img = np.zeros((360, 640, 3), np.uint8)
while True:
    cv2.imshow('mouse', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
        
# 销毁窗口
cv2.destroyAllWindows()
代码语言:javascript
复制
[Output]:
0 376 174 0 123 # 鼠标移动 组合 鼠标移动
0 422 185 0 123
0 514 201 0 123
0 566 210 0 123
1 524 258 1 123 # 左键按下 组合 左键按下
4 524 258 1 123 # 左键释放 组合 左键按下
0 528 258 0 123
0 544 259 0 123
0 567 259 0 123
0 625 262 0 123 # 鼠标移动 组合 鼠标移动

2.5 TrackBar用法

TrackBar控件

类似于可拖动的数值进度条

  • createTrackbar(trackbarname, winname, value, count, onChange)
    • 创建Trackbar控件
    • trackbarname:控件名字
    • winname:窗口名字
    • value:trackbar的默认值
    • count:trackbar的最大值,最小为0
    • onChange:回调函数
  • getTrackbarPos(trackbarname, winname)
    • 获取TrackjBar当前值
代码语言:javascript
复制
# trackbar
import cv2
import numpy as np

# 创建窗口
cv2.namedWindow('trackbar', cv2.WINDOW_NORMAL)
cv2.resizeWindow('trackbar', 640, 480)

# 定义回调函数
def callback(value):
    print(value)
    
# 创建trackbar
cv2.createTrackbar('R', 'trackbar', 0, 255, callback)
cv2.createTrackbar('G', 'trackbar', 0, 255, callback)
cv2.createTrackbar('B', 'trackbar', 0, 255, callback)

# 创建一个背景图片
img = np.zeros((480, 640, 3), np.uint8)

while True:
    # 获取当前TrackBar的值
    r = cv2.getTrackbarPos('R', 'trackbar')
    g = cv2.getTrackbarPos('G', 'trackbar')
    b = cv2.getTrackbarPos('B', 'trackbar')
    
    # 改变背景图颜色
    img[:] = [b, g, r]
    cv2.imshow('trackbar', img)
    
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.1~2.5 初等概念及OpenCV的使用
    • 1.1 机器视觉介绍
      • 计算机视觉的应用
    • 1.2 OpenCV介绍
      • 1.3 安装OpenCV环境
        • 1.4 创建和显示窗口
          • 1.5 显示图像
            • 2.1 保存图片
              • 2.2 读取摄像头和视频数据
                • 视频采集
                  • 读取摄像头
                  • 读取视频
                • 2.3 录制视频
                  • 2.4 控制鼠标
                    • 鼠标动作事件
                    • Flags组合键
                  • 2.5 TrackBar用法
                    • TrackBar控件
                    相关产品与服务
                    图像处理
                    图像处理基于腾讯云深度学习等人工智能技术,提供综合性的图像优化处理服务,包括图像质量评估、图像清晰度增强、图像智能裁剪等。
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档