Python OpenCV学习总结Day 1 图像视频读写、线、圆、矩形、鼠标事件

前言

硕士期间做了近两年的图像处理与深度学习相关的内容,但在实际应用中仍然能遇到新问题,学习新知识,因此在这开一个坑,总结一下图像处理开源库OpenCV(Python)中常见的函数、原理和算法,也会同时记录新碰到的问题与解决方法,巩固一下图像基础。

按照OpenCV官方doc顺序来进行学习回忆和总结~

Day1.OpenCV操作基础

读取/保存图片

图片读取主要采用imread(),读取img的通道顺序为BGR,

img = cv2.imread(path, flags=cv2.IMREAD_COLOR)

其中path表示读取图片路径,flags表示读图方式
cv2.IMREAD_COLOR 读取彩图
cv2.IMREAD_UNCHANGED 读取原图
cv2.IMREAD_GRAYSCALE 读取灰度图

图片保存主要采用imwrite()

cv2.imwrite(path, img)

其中path表示图片保存路径,img表示需要保存的Mat格式图片

如果本地图片名或保存图片名带有中文,则会出现读取/保存图片不成功的现象,此时需要通过imdecode和imencode进行读写,

# 读图
img = cv2.imdecode(np.fromfile(path, dtype=np.uint8), flags)
# 写图
cv2.imencode('.jpg', img)[1].tofile(path)

读取/保存视频

视频读取主要采用VideoCapture(),其中path=0时开启摄像头,

cap = cv2.VideoCapture(path)

常用的读取流程是:捕获视频流VideoCapture()->读取视频帧cap.read()->图像处理->结束后cap.release(),如下所示,

cap = cv2.VideoCapture(0)
if not cap.isOpened():
    print("Cannot open camera")
    exit(0)
while True:
    ret, frame = cap.read()
    if not ret:
        print("Last frame.")
        break
    cv2.imshow('frame', gray)
    if cv2.waitKey(1) == ord('q'):
        break
cap.release()

视频保存主要采用VideoWriter(),其中fourcc表示视频编码方式,*'MJPG’可用来保存.mp4格式

fourcc = cv2.VideoWriter_fourcc(*'XVID')
outvid = cv2.VideoWriter(path, fourcc, fps, (W, H))

注意,如果(W, H)与后面outvid.write(img)中img的Size不符合,就无法正常保存视频,这是常见的保存无效视频文件的原因

以下是打开视频->水平翻转->保存视频的一个例程,

import numpy as np
import cv2
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640,  480))

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break
    frame = cv2.flip(frame, 0)
    out.write(frame)
    cv2.imshow('frame', frame)
    if cv2.waitKey(1) == ord('q'):
        break
cap.release()
out.release()

画点、线、圆、矩形、文字等

图像处理时经常需要画图,例如特征匹配时要画点画线、目标检测画目标框等

画形状的常见函数包括,

# 线
cv2.line(img, pt1, pt2, color, thickness, lineType)
# 矩形
cv2.rectangle(img, pt1, pt2, color, thickness, lineType)
# 圆
cv2.circle(img, center, radius, color, thickness, lineType)
# 椭圆
cv2.ellipse(img, center, (ra, rb), angle, startAngle, endAngle, color, thickness, lineType)
# 多边形或折线
cv2.polylines(img, pts, isClosed, color, thickness, lineType)
# 文字
cv2.putText(img, text, pt1, fontFace, fontScale, color, thickness, lineType)

通用参数包括img,color,thickness,lineType,分别表示输入图像,颜色,线厚度,线形等
thickness=-1时画的形状是内部填充的,可用于图像掩膜的生成
lineType有三种形式,
cv2.LINE_AA 反锯齿线 ,画曲线更平滑
cv2.LINE_8 8-连通线
cv2.LINE-4 4-连通线

以下是一个画图实例,

import cv2
import numpy as np

img = np.zeros([480, 640, 3], np.uint8)
cv2.line(img, (100, 100), (300, 300), (0, 255, 255), 3, cv2.LINE_AA)
cv2.rectangle(img, (384, 0), (510, 128), (0, 255, 0), 3)
cv2.circle(img, (447, 63), 63, (0, 0, 255), -1)
cv2.ellipse(img, (256, 256), (100, 50), -30, 0, 180, (255, 180, 0), -1)

pts = np.array([[10, 5], [20, 30], [70, 20], [50, 10]], np.int32)
cv2.polylines(img, [pts], True, (0, 255, 255))

cv2.putText(img, 'OpenCV', (10, 400), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2, cv2.LINE_AA)
cv2.imshow('img', img)
cv2.waitKey(0)

输出结果:
在这里插入图片描述

鼠标键盘事件以及滑动条设置

鼠标事件

OpenCV鼠标键盘事件包括左右键双击、移动、拖拽、Ctrl/Alt/Shift等,

cv2.CV_EVENT_MOUSEMOVE :鼠标移动
cv2.CV_EVENT_LBUTTONDOWN : 鼠标左键按下
cv2.CV_EVENT_RBUTTONDOWN : 鼠标右键按下
cv2.CV_EVENT_MBUTTONDOWN : 鼠标中键按下
cv2.CV_EVENT_LBUTTONUP : 鼠标左键放开
cv2.CV_EVENT_RBUTTONUP : 右键放开
cv2.CV_EVENT_MBUTTONUP : 中键放开
cv2.CV_EVENT_LBUTTONDBLCLK : 左键双击
cv2.CV_EVENT_RBUTTONDBLCLK : 右键双击
cv2.CV_EVENT_MBUTTONDBLCLK : 中键双击
cv2.CV_EVENT_MOUSEWHEEL : 鼠标向前后滑动
cv2.CV_EVENT_MOUSEHWHEEL : 鼠标向左右滑动
cv2.CV_EVENT_FLAG_LBUTTON :左键拖拽
cv2.CV_EVENT_FLAG_RBUTTON : 右键拖拽
cv2.CV_EVENT_FLAG_MBUTTON : 中键拖拽
cv2.CV_EVENT_FLAG_CTRLKEY : Ctrl按下不放
cv2.CV_EVENT_FLAG_SHIFTKEY : shift按下不放
cv2.CV_EVENT_FLAG_ALTKEY : alt按下不放

有时需要通过鼠标画图,这时就要通过鼠标回调函数setMouseCallback与鼠标响应函数onMouse共同完成

cv2.setMouseCallback(WindowName, onMouse, param=None)
onMouse(event, x, y, flags, param)

其中,setMouseCallback()负责将窗口与鼠标事件绑定,WindowName表示要绑定的窗口onMouse表示要具体事件响应的方式,param是需要传给onMouse的参数(可缺省),
onMouse()中的event表示发生的鼠标事件,x、y表示鼠标位置,param是回调函数传进来的参数

以下给出了一个鼠标点击画圆的程序,

import cv2
import numpy as np


# mouse callback function
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print('event!', cv2.EVENT_LBUTTONDOWN)
        cv2.circle(img, (x, y), 100, (255, 0, 0), -1)
    if event == cv2.EVENT_LBUTTONUP:
        print('event!', cv2.EVENT_LBUTTONUP)
    if event == cv2.EVENT_MOUSEMOVE:
        print('event!', cv2.EVENT_MOUSEMOVE)
    if event == cv2.EVENT_FLAG_ALTKEY:
        print('event!', cv2.EVENT_FLAG_ALTKEY)

counter = 0
# Create a black image, a window and bind the function to window
img = np.ones((512, 512, 3), np.uint8)*255
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)
while 1:
    cv2.imshow('image', img)
    if cv2.waitKey(20) & 0xFF == 27:
        break
cv2.destroyAllWindows()

键盘事件

OpenCV似乎没有具体的键盘相应事件,不过有一个waitKey函数,

cv2.waitKey(time)

在imshow图像后必须至少有一个waitKey()函数,不然无法显示图像

此外,waitKey可以用作键盘响应函数,例如

# 500ms内键盘输入q
cv2.waitKey(500) & 0xFF == ord('q')
# 如果1000ms内键盘输入Esc就退出循环
if cv2.waitKey(1000) & 0xFF == 27:
	break
# &0xFF的作用是防止奇奇怪怪的BUG,不加也行

滑动条设置

如果要在图像窗口创建滑动条,则通过createTrackbar()、cv2.getTrackbarPos(), cv2.setTrackbarPos(),其中createTrackBar用于创建滑动条、绑定窗口并设置响应函数,getTrackbarPos用于获取滑动条数值,setTrackbarPose用于设定滑动条初始数值

以下是一个通过滑动条来改变图像通道的例程

import numpy as np
import cv2
from copy import deepcopy


img = cv2.imread('starry_night.png')
myimg = np.zeros_like(img, np.uint8)
cv2.namedWindow('image')
def updateGray(x):
    global myimg, img, H, W
    size = cv2.getTrackbarPos('gray', 'image')
    if size == 1:
        myimg = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    if size == 0:
        myimg = deepcopy(img)


cv2.createTrackbar('gray', 'image', 0, 1, updateGray)
while True:
    cv2.imshow('image', myimg)
    if cv2.waitKey(50) == 27:
        break
cv2.destroyWindow('image')

在这里插入图片描述
在这里插入图片描述

结语

本文回顾了基本的OpenCV基础读写操作,以后就将正式进入图像处理的核心操作啦

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值