opencv-python入门学习(1)

环境安装与配置

使用anaconda进行python环境的安装配置。

  1. 创建新的python环境
  2. 安装相关库(numpy、opencv-python、matplotlib)
  3. 使用pycharm时。import cv2在实际写代码的过程中,pycharm不会给出函数提醒等代码辅助,需要找到你的python环境,在文件路径中找到cv2.pyd文件并复制到上层目录,重启pycharm即可

anaconda/envs/python名/lib/site-packages/cv2

图像入门

学习简单的图像处理

图片的读取、显示和保存

三个函数:

cv.imread():读取图像

import numpy as np
import cv2 as cv
# 加载彩色灰度图像
# 参数为图片路径(相对绝对都可以)以及读取方式
# 读取方式分为:‘0’:灰度图、‘1’:彩色图、‘-1’:带alpha通道
img = cv.imread('pic1.jpg'0)

cv.imshow():显示图像

cv.imshow('image',img)
cv.waitKey(0) # 等待键盘操作
cv.destroyAllWindows()

也可以先创建窗口,再向窗口中添加图像来显示。
当创建一个新窗口时,可以传递一个整数参数(通常为 0),作为窗口的标志。该整数值可以是一组标志的按位或运算结果,其中包括:

  • WINDOW_NORMAL: 允许用户自由调整窗口大小。
  • WINDOW_AUTOSIZE: 窗口大小固定,无法更改。
  • WINDOW_OPENGL: 使用 OpenGL 渲染。
  • WINDOW_FULLSCREEN: 创建全屏窗口。

使用 WINDOW_NORMAL 标志,用户可以通过拖动边框或单击最大化/还原按钮来自由调整窗口大小。

cv.namedWindow('image',cv.WINDOW_NORMAL)
cv.imshow('image',img)
cv.waitKey(0)
cv.destroyAllWindows()

cv.imwrite():储存图像

import numpy as np
import cv2 as cv
img = cv.imread('pic1.jpg',0)
cv.imshow('image',img)
k = cv.waitKey(0)
if k == 27: # 等待ESC退出
 cv.destroyAllWindows()
elif k == ord('s'): # 等待关键字,保存和退出
 cv.imwrite('pic_copy.png',img)
 cv.destroyAllWindows()

视频的读取、显示和保存

从摄像机 / 文件中读取并显示视频

创建videocpture对象,创建时可以可以直接传递视频文件名(地址),或者输入摄影机的编号。对应创建出来的对象分别用于对视频文件和摄影机捕捉的画面进行操作。

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
if not cap.isOpened():
 print("Cannot open camera")
 exit()
while True:
 # 逐帧捕获
 ret, frame = cap.read()
 # 如果正确读取帧,ret为True
 if not ret:
 print("Can't receive frame (stream end?). Exiting ...")
 break
 # 我们在框架上的操作到这里
 gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
 # 显示结果帧e
 cv.imshow('frame', gray)
 if cv.waitKey(1) == ord('q'):
 break
# 完成所有操作后,释放捕获器
cap.release()
cv.destroyAllWindows()

还可以通过cap.get(propId) 方法访问该视频的特定信息其中,propId 表示要获取的属性标识符,可以是以下数字之一:

  • cv2.CAP_PROP_POS_MSEC: 当前帧与视频开始之间的时间(毫秒)
  • cv2.CAP_PROP_POS_FRAMES: 当前帧在视频中的索引(从 0 开始)
  • cv2.CAP_PROP_POS_AVI_RATIO: 视频文件中当前位置相对于文件末尾的比率
  • cv2.CAP_PROP_FRAME_WIDTH: 帧的宽度(像素)
  • cv2.CAP_PROP_FRAME_HEIGHT: 帧的高度(像素)
  • cv2.CAP_PROP_FPS: 帧率(每秒钟帧数)
  • cv2.CAP_PROP_FOURCC: 视频编解码器的四字码
  • cv2.CAP_PROP_FRAME_COUNT: 视频文件中的帧总数
  • cv2.CAP_PROP_FORMAT: 捕获的图像格式
  • cv2.CAP_PROP_MODE: 捕获模式
  • cv2.CAP_PROP_BRIGHTNESS: 亮度(仅适用于摄像头)
  • cv2.CAP_PROP_CONTRAST: 对比度(仅适用于摄像头)
  • cv2.CAP_PROP_SATURATION: 饱和度(仅适用于摄像头)
  • cv2.CAP_PROP_HUE: 色调(仅适用于摄像头)
  • cv2.CAP_PROP_GAIN: 增益(仅适用于摄像头)
  • cv2.CAP_PROP_EXPOSURE: 曝光(仅适用于摄像头)
  • cv2.CAP_PROP_BACKLIGHT: 背光补偿(仅适用于摄像头)
  • cv2.CAP_PROP_AUTOFOCUS: 自动对焦(仅适用于摄像头)

例如,可以通过以下代码获取视频捕获对象的宽度和高度:

import cv2

cap = cv2.VideoCapture(0)
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
print("Width: ", width, " Height: ", height)

并且用cv.set(propId)可以修改视频的部分特征,其中(propId)与get函数对应

保存编辑后的视频

创建Videowriter对象,指定分辨率、帧率、视频编解码器等等,将处理后的每一帧逐帧添加进去(结束时记得释放)

  • FourCC码(视频编解码器):FourCC 是一个四字节码,用于指定视频编解码器的格式。在 OpenCV 中,FourCC 通常用于指定 VideoWriter 对象的编码格式。可以从一组预定义的编码器中选择一个或者定义自己的编码器。如果不知道要使用哪个编码器,可以使用默认的编码器(例如:MJPG)。只需将 fourcc 参数设置为 -1 或 不设置(即使用默认值)即可。
  • 在Fedora中:DIVX,XVID,MJPG,X264,WMV1,WMV2。(最好使用XVID。MJPG会生成大尺寸的视频。X264会生成非常小的尺寸的视频)
  • 在Windows中:DIVX(尚待测试和添加)
  • 在OSX中:MJPG(.mp4),DIVX(.avi),X264(.mkv)。

下面是从摄像机捕获,沿垂直方向翻转每一帧并保存视频的代码

import numpy as np
import cv2 as cv
cap = cv.VideoCapture(0)
# 定义编解码器并创建VideoWriter对象
fourcc = cv.VideoWriter_fourcc(*'XVID')
out = cv.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
while cap.isOpened():
 ret, frame = cap.read()
 if not ret:
 print("Can't receive frame (stream end?). Exiting ...")
 break
 frame = cv.flip(frame, 0)
 # 写翻转的框架
 out.write(frame)
 cv.imshow('frame', frame)
 if cv.waitKey(1) == ord('q'):
 break
# 完成工作后释放所有内容
cap.release()
out.release()
cv.destroyAllWindows()

注:cv.flip() 是 OpenCV 中的一个函数,用于图像的翻转操作。它可以实现将图像水平或垂直翻转,也可以同时进行水平和垂直方向的翻转。
0:沿 x 轴垂直翻转
1:沿 y 轴水平翻转
-1:同时沿 x 和 y 方向翻转

opencv中的绘图功能

绘制几何形状

  • 画线
    要绘制一条线,需要传递线的开始和结束坐标。我们将创建一个黑色图像,并从左上角到右下角在其上绘制一条蓝线。
import numpy as np
import cv2 as cv
# 创建黑色的图像
img = np.zeros((512,512,3), np.uint8)
# 绘制一条厚度为5的蓝色对角线
cv.line(img,(0,0),(511,511),(255,0,0),5)
  • 画矩形
    要绘制矩形,您需要矩形的左上角和右下角。这次,我们将在图像的右上角绘制一个绿色矩形。
cv.rectangle(img,(384,0),(510,128),(0,255,0),3)
  • 画圆圈
    要绘制一个圆,需要其中心坐标和半径。我们将在上面绘制的矩形内绘制一个圆。

(厚度为 ‘-1’ 代表填充)

cv.circle(img,(447,63), 63, (0,0,255), -1)
  • 画椭圆
    要绘制椭圆,我们需要传递几个参数。一个参数是中心位置(x,y)。下一个参数是轴长度(长轴长度,短轴长度)。angle是椭圆沿逆时针方向旋转的角度。startAngle和endAngle表示从主轴沿顺时针方向测量的椭圆弧的开始和结束。即给出0和360给出完整的椭圆。下面的示例在图像的中心绘制一个椭圆形。
cv.ellipse(img,(256,256),(100,50),0,0,180,255,-1)

(256, 256):表示绘制椭圆的中心位置,本例中为坐标系中心点。 (100, 50):表示椭圆的长轴与短轴长度,本例中长轴为
100,短轴为 50。 0:表示椭圆相对于水平轴的旋转角度,本例中为 0。 0, 180:表示绘制的起始和结束角度,本例中从 0 度开始,到
180 度结束,即绘制半个椭圆。 255:表示绘制椭圆的颜色,本例中为白色。
-1:表示填充整个椭圆,本例中整个椭圆都被填充。

  • 画多边形
    要绘制多边形,首先需要顶点的坐标。将这些点组成形状为 ROWSx1x2 的数组,其中 ROWS 是顶点数,并且其类型应为int32。在这里,我们绘制了一个带有四个顶点的黄色小多边形。
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
cv.polylines(img,[pts],True,(0,255,255))
  • 注意 如果第三个参数为False,您将获得一条连接所有点的折线,而不是闭合形状。

  • cv.polylines()可用于绘制多条线。只需创建要绘制的所有线条的列表,然后将其传递给函数即可。所有线条将单独绘制。与为每条线调用cv.line相比,绘制一组线是一种更好,更快的方法。
    pts = pts.reshape((-1,1,2)) 是 NumPy 库中的一个方法,用于将数组 pts 重新调整为新的形状。其中的参数 (-1,1,2) 表示新的形状为 (n,1,2),其中 n 的值可以由输入数组的长度和其他维度推导出来。

  • 对pts = pts.reshape((-1,1,2)): 在这个方法中,-1的含义是自动推导,表示该维度的大小将由其他维度和总长度来确定。对于 reshape 方法的第二个参数
    1,它的含义是将原来的一维数组变成一个列向量;而第三个参数 2 表示每个元素都有两个组成部分。 因此,pts.reshape((-1,1,2)) 的作用是将 pts 数组按照每行一个点,每点两个坐标的形式重构为一个三维数组,其中第一维(n, 1, 2) 表示共有 n 个点,每个点有一行两列表示其横纵坐标。

    例如,如果 pts 初始值如下:

    pts = [[0, 0], [1, 1], [2, 2], [3, 3]] 则经过 pts = pts.reshape((-1,1,2))
    处理后,pts 数组变为如下形式:

    array([[[0, 0]],
    
     [[1, 1]],
    
     [[2, 2]],
    
     [[3, 3]]]) 
    

    这个例子中,pts 数组原本是一个二维数组,其中每个元素都表示一个点的横纵坐标。通过 reshape 方法将其重构为了一个三维数组,其中第一维为点的数量,第二维为 1,第三维为 2,最终形成了一个列向量。

  • 向图像添加文本
    要将文本放入图像中,需要指定以下内容。
    • 要写入的文字数据
    • 要放置它的位置坐标(即数据开始的左下角)。
    • 字体类型(检查cv.putText文档以获取受支持的字体)
    • 字体比例(指定字体大小)
    • 常规的内容,例如颜色,厚度,线条类型等。为了获得更好的外观,建议使用lineType = cv.LINE_AA。

我们将在白色图像上写入OpenCV

font = cv.FONT_HERSHEY_SIMPLEX
cv.putText(img,'OpenCV',(10,500), font, 4,(255,255,255),2,cv.LINE_AA)

用鼠标绘图

使用cv.setMouseCallback()
OpenCV 的鼠标事件包括:

cv.EVENT_MOUSEMOVE:鼠标在窗口上移动时触发。
cv.EVENT_LBUTTONDOWN:鼠标左键按下时触发。
cv.EVENT_RBUTTONDOWN:鼠标右键按下时触发。
cv.EVENT_MBUTTONDOWN:鼠标中键按下时触发。
cv.EVENT_LBUTTONUP:鼠标左键释放时触发。
cv.EVENT_RBUTTONUP:鼠标右键释放时触发。
cv.EVENT_MBUTTONUP:鼠标中键释放时触发。
cv.EVENT_LBUTTONDBLCLK:鼠标左键双击时触发。
cv.EVENT_RBUTTONDBLCLK:鼠标右键双击时触发。
cv.EVENT_MBUTTONDBLCLK:鼠标中键双击时触发。

这些鼠标事件可以通过 cv.setMouseCallback() 函数来绑定到窗口上。该函数的参数含义如下:

winname:窗口名称。
onMouse:回调函数,在指定的窗口上鼠标事件触发时被调用。
param:传递给回调函数的额外参数,一般为None。

下面是一个鼠标回调函数的应用。在这里,我们通过拖动鼠标来绘制矩形或圆形(取决于我们选择的模式) ,就像我们在 Paint 应用程序中所做的那样。所以我们的鼠标回调函数有两部分,一部分用于绘制矩形,另一部分用于绘制圆形。这个具体的例子对于创建和理解一些交互式应用程序非常有帮助,比如目标跟踪,图像分割地图等等。

import numpy as np
import cv2 as cv
drawing = False # 如果按下鼠标,则为真
mode = True # 如果为真,绘制矩形。按 m 键可以切换到曲线
ix,iy = -1,-1
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):
	global ix,iy,drawing,mode
 	if event == cv.EVENT_LBUTTONDOWN:
	 	drawing = True
	 	ix,iy = x,y
 	elif event == cv.EVENT_MOUSEMOVE:
 		if drawing == True:
 			if mode == True:
 				cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
 			else:
 				cv.circle(img,(x,y),5,(0,0,255),-1)
 	elif event == cv.EVENT_LBUTTONUP:
 		drawing = False
 		if mode == True:
 			cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
 		else:
 			cv.circle(img,(x,y),5,(0,0,255),-1)

其中,程序开始时,drawing 和 mode 被初始化为 False 和 True。当用户按下鼠标左键时,cv.EVENT_LBUTTONDOWN 事件被触发,ix 和 iy 被设置为当前鼠标位置 (x, y),drawing 被设置为 True,表示正在绘制图形。

接着,当鼠标移动时,cv.EVENT_MOUSEMOVE 事件被触发,如果 drawing 为 True,则根据 mode 的值绘制矩形或圆形。如果 mode 为 True,则在图像 img 上绘制矩形;否则,在图像 img 上绘制半径为 5 的圆形。

当用户释放鼠标左键时,cv.EVENT_LBUTTONUP 事件被触发,drawing 被设置为 False,表示绘制结束。然后,根据 mode 的值再次在图像 img 上绘制矩形或圆形。

练习

在这里插入图片描述
代码:

import numpy as np
import cv2 as cv

drawing = False  # 如果按下鼠标,则为真
mode = True  # 如果为真,绘制矩形。按 m 键可以切换到曲线
ix, iy = -1, -1


# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
    global ix, iy, drawing, mode
    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 3)
        else:
            cv.circle(img, (x, y), 5, (0, 0, 255), -1)


# 创建一个黑色的图像,一个窗口,并绑定到窗口的功能
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
while (1):
    cv.imshow('image', img)
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值