OpenCV中initUndistortRectifyMap与undistort的性能差异及原理问询
OpenCV去畸变:initUndistortRectifyMap+remap与undistort的核心差异
你在Jetson AGX上处理相机流时遇到的速度差异,核心原因在于两者的计算逻辑和执行时机完全不同:
1. 计算时机:预计算vs逐帧重复计算
initUndistortRectifyMap的作用是根据相机内参、畸变系数,提前计算出像素映射表(mapx和mapy)——这两张表记录了去畸变后图像的每个像素,对应原始畸变图像中的哪个位置。只要相机参数不变,这个映射表只需要计算一次。
你的代码里现在把它放在while循环内,其实完全可以移到循环外,速度还能再提升。undistort是把“计算映射表+图像采样”两步合并成一个函数,而且每处理一帧就重新计算一次映射表。相当于逐帧重复执行initUndistortRectifyMap的计算逻辑,自然会慢很多。
2. 内部实现:分工明确vs单帧全包
initUndistortRectifyMap只做数学计算生成映射表,这一步是纯数值运算;remap则负责根据映射表对图像做插值采样(比如你用的INTER_LINEAR双线性插值),这一步是硬件友好的图像操作,Jetson的GPU可以高效加速。undistort没有拆分这两步,每帧都要重新推导映射关系,再做采样,没有利用缓存或预计算的优势,在嵌入式平台上的性能劣势会被放大。
优化后的代码示例
把映射表生成移到循环外,避免重复计算:
import cv2 import numpy as np cap = cv2.VideoCapture("v4l2src device=/dev/video0 ! video/x-raw, format=BGRx, width=2064, height=1544 ! videoconvert ! video/x-raw, format=BGR ! appsink") cameramtx = np.array([[1.34120872e+03, 0.00000000e+00, 1.03042395e+03], [0.00000000e+00, 1.34241736e+03, 8.32822269e+02], [0.00000000e+00, 0.00000000e+00, 1.00000000e+00]]) dist = np.array([[-0.30198218, 0.11819129, 0.00066535, -0.00047617, -0.025303 ]]) newcameramtx, roi = cv2.getOptimalNewCameraMatrix(cameramtx, dist, (2064,1544), 0, (2064,1544)) # 预计算映射表,仅执行一次 mapx,mapy = cv2.initUndistortRectifyMap(cameramtx, dist, None, newcameramtx,(2064, 1544),5) while True: _, frame = cap.read() dst = cv2.remap(frame,mapx,mapy,cv2.INTER_LINEAR) dst = cv2.resize(dst, (960,640)) # dst1 = cv2.undistort(frame, cameramtx, dist, None, newcameramtx) # dst1 = cv2.resize(dst, (960,640)) cv2.imshow('dst', dst) if cv2.waitKey(1) == ord('q'): break cap.release() cv2.destroyAllWindows()
(注:原代码中frame.release()是错误的,已修正为cap.release())
内容的提问来源于stack exchange,提问作者Aleks-CST
相关产品推荐
相关产品推荐

