OpenCV 速度问题
OpenCV speed issue
我想以 ~30fps 转换许多点(整个 720p 图像最好)。
现在我只是循环遍历一个蒙版并寻找标记的像素。然后我将每个标记的像素转换为一个新帧。有什么办法可以加快速度吗?
该代码在 windows 平板电脑上运行,所以我不知道 CUDA 是否可以提供帮助。
//Look for white pixels in mask image and transform them to new frame orientation
for (int row = 0; row < mask.rows; row++){
for (int col = 0; col < mask.cols; col++){
if (mask.at<uchar>(row, col) == 255){
//Point in 2D hom
p = (Mat_<double>(3, 1) << col, row, 1);
p11 = CameraMatrix480.inv()*p; //Pixel-->Camera
//Project 2D Points to table
double d = abs((p11 - midCam).dot(table_normal_cam)); //intersection of point with table surface is z value
ps = p11 - d*table_normal_cam;
p11 *= -Mat(p11 - ps).at<double>(2);
//Get point in new frame in hom camera coordinates
p11.copyTo(p_hom1(Range(0, 3), Range(0, 1)));
p_hom2 = M * p_hom1; //p_hom in frame2
//Point in frame2 in pixel coordinates
p12 = (1 / p_hom2.at<double>(2))*(CameraMatrix480*p_hom2(Range(0, 3), Range(0, 1))); //Camera-->Pixel
pixel = Point(p12.at<double>(0), p12.at<double>(1));
//Check if new location is in the frame
if (rect.contains(pixel)){
RGB& rgb = output.ptr<RGB>(pixel.y)[pixel.x];
rgb = white;
}
}
}
未经测试,我认为逆相机矩阵的计算是您代码中最昂贵的操作。假设相机矩阵是常数,你可以预先计算逆。
Mat invCameraMatrix(CameraMatrix480.inv());
...
p11 = invCameraMatrix*p; //Pixel-->Camera
...
此外,您可以轻松地将 for
循环与 OpenMP
并行化,并检查这是否会提高性能。要使用 CUDA
,您需要 Nvidia 显卡,您的 windows 平板电脑设备可能不提供该显卡。
您可以尝试使用 cv::UMat
进行性能测试吗?
我使用 OpenMP
进行按像素的快速图像操作。
您是否考虑过将操作更改为 float
而不是 double
?由于您使用的是移动设备,它可能有助于加快操作速度。
另外,最后一个if
条件中的rect
是什么?
我设法在 ~40 毫秒内获得 720p 图像的变换 运行,只需使用 Matx 而不是 Mat。图像存储在 UMat 中,也许这也有帮助。
我想以 ~30fps 转换许多点(整个 720p 图像最好)。 现在我只是循环遍历一个蒙版并寻找标记的像素。然后我将每个标记的像素转换为一个新帧。有什么办法可以加快速度吗? 该代码在 windows 平板电脑上运行,所以我不知道 CUDA 是否可以提供帮助。
//Look for white pixels in mask image and transform them to new frame orientation
for (int row = 0; row < mask.rows; row++){
for (int col = 0; col < mask.cols; col++){
if (mask.at<uchar>(row, col) == 255){
//Point in 2D hom
p = (Mat_<double>(3, 1) << col, row, 1);
p11 = CameraMatrix480.inv()*p; //Pixel-->Camera
//Project 2D Points to table
double d = abs((p11 - midCam).dot(table_normal_cam)); //intersection of point with table surface is z value
ps = p11 - d*table_normal_cam;
p11 *= -Mat(p11 - ps).at<double>(2);
//Get point in new frame in hom camera coordinates
p11.copyTo(p_hom1(Range(0, 3), Range(0, 1)));
p_hom2 = M * p_hom1; //p_hom in frame2
//Point in frame2 in pixel coordinates
p12 = (1 / p_hom2.at<double>(2))*(CameraMatrix480*p_hom2(Range(0, 3), Range(0, 1))); //Camera-->Pixel
pixel = Point(p12.at<double>(0), p12.at<double>(1));
//Check if new location is in the frame
if (rect.contains(pixel)){
RGB& rgb = output.ptr<RGB>(pixel.y)[pixel.x];
rgb = white;
}
}
}
未经测试,我认为逆相机矩阵的计算是您代码中最昂贵的操作。假设相机矩阵是常数,你可以预先计算逆。
Mat invCameraMatrix(CameraMatrix480.inv());
...
p11 = invCameraMatrix*p; //Pixel-->Camera
...
此外,您可以轻松地将 for
循环与 OpenMP
并行化,并检查这是否会提高性能。要使用 CUDA
,您需要 Nvidia 显卡,您的 windows 平板电脑设备可能不提供该显卡。
您可以尝试使用 cv::UMat
进行性能测试吗?
我使用 OpenMP
进行按像素的快速图像操作。
您是否考虑过将操作更改为 float
而不是 double
?由于您使用的是移动设备,它可能有助于加快操作速度。
另外,最后一个if
条件中的rect
是什么?
我设法在 ~40 毫秒内获得 720p 图像的变换 运行,只需使用 Matx 而不是 Mat。图像存储在 UMat 中,也许这也有帮助。