python中使用opencv的cuda开发经验
1.python使用GPU读取视频
如果要在python种使用GPU读取视频的话,需要在opencv编译的时候加入ffmpeg和nvcuvid。
(1)nvcuvdid编译
下载Video_Codec_SDK_11.1.5.zip文件,地址:
NVIDIA VIDEO CODEC SDK
复制nvcuid/cuviddec头文件
sudo cp ./Video_Codec_SDK_11.0.10/Interface/nvcuvid.h /usr/local/cuda/include
sudo cp ./Video_Codec_SDK_11.0.10/Interface/cuviddec.h /usr/local/cuda/include
即可在编译的时候获得,如下图红框所示:
有这个编译选项的时候采用调用opencv的GPU读流
2.GPU读流的操作
具体读流函数如下所示:
import cv2
def main(file_path):
cap = cv2.cudacodec.createVideoReader(file_path)
while True:
ret, frame = cap.nextFrame()
if ret is False:
break
cv2.imshow('image', frame)
cv2.waitKey(1)
cap.release()
if __name__ == '__main__':
file_path = 'test.mp4'
main(file_path)
opencv的gpu读取的视频图片的格式位GpuMat格式,并且为BGRA的格式,需要用自带的颜色转换cv2.cvtColor转换为BGR的格式,该函数在GPU中也有相应的函数可以直接转换,就不用再下载打cpu端进行操作。并且如果需要下载到CPU进行操作的话,就需要download,例如frame.download。
3.GpuMat的图像的copyTo
在python端如果进行GpuMat的拼接覆盖操作的话,必须用到copyTo操作,这个操作需要从原图之中扣出来一块区域,并且和原图指向同一个地址,这样子区域的改变才能够影响的原图,如果直接用=或者GpuMat赋值操作的话,则和原图的地址不同了,不能进行相应的操作。
具体的代码如下
import cv2
import numpy as np
def main():
# 创建两个GpuMat的矩阵
gpu_frame1 = cv2.cuda_GpuMat()
gpu_frame2 = cv2.cuda_GpuMat()
# 将图片1上传到GPUGpuMat中
image1 = cv2.imread('./1.png')
image1 = cv2.resize(image1, (640, 640))
gpu_frame1.upload(image1)
# 从图片1左上角获得一个320×320
src_roi = gpu_frame1.rowRange(0, 320).colRange(0, 320)
# 将图片2上传到GPUGpuMat中
image2 = cv2.imread('./2.png')
image2 = cv2.resize(image2, (320, 320))
gpu_frame2.upload(image2)
# 将图片2覆盖到从图片1中获得的区域
gpu_frame2.copyTo(src_roi)
# 将两个图片下载到CPU端
img1 = gpu_frame1.download()
img2 = gpu_frame2.download()
cv2.imwrite('1_1.jpg', img1)
cv2.imwrite('1_2.jpg', img2)
if __name__ == '__main__':
main()
图片1
图片2
拼接后的图片1_1