赞
踩
使用anaconda进行python环境的安装配置。
anaconda/envs/python名/lib/site-packages/cv2
学习简单的图像处理
三个函数:
import numpy as np
import cv2 as cv
# 加载彩色灰度图像
# 参数为图片路径(相对绝对都可以)以及读取方式
# 读取方式分为:‘0’:灰度图、‘1’:彩色图、‘-1’:带alpha通道
img = cv.imread('pic1.jpg',0)
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()
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对象,指定分辨率、帧率、视频编解码器等等,将处理后的每一帧逐帧添加进去(结束时记得释放)
- 在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 方向翻转
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)
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:表示填充整个椭圆,本例中整个椭圆都被填充。
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]]])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
这个例子中,pts 数组原本是一个二维数组,其中每个元素都表示一个点的横纵坐标。通过 reshape 方法将其重构为了一个三维数组,其中第一维为点的数量,第二维为 1,第三维为 2,最终形成了一个列向量。
我们将在白色图像上写入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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。