opencv cuda多线程用队列方式处理视频
想写一个视频处理器,但是对c++图像处理不太了解于是用了chatgpt…意外chatgpt竟然走那么远了。
·
想写一个视频处理器,但是对c++图像处理不太了解于是用了chatgpt…
意外chatgpt竟然走那么远了
import cv2
from numba import cuda
import concurrent.futures
import queue
import time
# 读取视频文件
video = cv2.VideoCapture("2.mp4")
# 读取视频帧数间格
frame_time_space = int(1000 / video.get(cv2.CAP_PROP_FPS))
stat = time.time()
# 结果队列
result = queue.Queue()
# 在 GPU 上进行图像处理
@cuda.jit
def thresholding(gray_image):
x, y = cuda.grid(2)
if x < gray_image.shape[0] and y < gray_image.shape[1]:
if gray_image[x, y] < 128:
gray_image[x, y] = 0
else:
gray_image[x, y] = 255
# 线程池中的线程所执行的任务
def worker(frame, result):
# 将图像转换为灰度图像
gray_image = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 将灰度图像上传到 GPU
d_gray_image = cuda.to_device(gray_image)
# 处理 item,并将结果放入 result 队列中
result.put(d_gray_image)
# 设置 CUDA 栅格和线程块大小
threadsperblock = (16, 16)
blockspergrid_x = (gray_image.shape[0] + threadsperblock[0] - 1) // threadsperblock[0]
blockspergrid_y = (gray_image.shape[1] + threadsperblock[1] - 1) // threadsperblock[1]
blockspergrid = (blockspergrid_x, blockspergrid_y)
# 运行 CUDA 核函数
thresholding[blockspergrid, threadsperblock](d_gray_image)
# 创建线程池
with concurrent.futures.ThreadPoolExecutor(max_workers=30) as executor:
futures = []
# 启动 4 个工作线程,将队列和结果队列传递给线程池中的线程
# 循环读取视频帧
while True:
# 读取一帧
ret, frame = video.read()
# 如果读取到了最后一帧,退出循环
if not ret:
break
futures.append(executor.submit(worker, frame, result))
while True:
# 将处理后的图像从 GPU 下载到主机内存
processed_image = result.get().copy_to_host()
# 显示fps
fps_disp = "FPS: {}".format(int(1 / (time.time() - stat)))
cv2.putText(processed_image, fps_disp, (10, 25), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 255, 0), 2)
stat = time.time()
# 在窗口中显示该帧
cv2.imshow("frame", processed_image)
# 延时播放
if cv2.waitKey(1) == ord("q"):
break
# 等待线程池中的所有线程退出
concurrent.futures.wait(futures)
# 释放视频流
video.release()
# 销毁窗口
cv2.destroyAllWindows()
欢迎来到由智源人工智能研究院发起的Triton中文社区,这里是一个汇聚了AI开发者、数据科学家、机器学习爱好者以及业界专家的活力平台。我们致力于成为业内领先的Triton技术交流与应用分享的殿堂,为推动人工智能技术的普及与深化应用贡献力量。
更多推荐
已为社区贡献1条内容
所有评论(0)