【问题标题】:OpenCV speed issueOpenCV速度问题
【发布时间】:2015-09-08 12:37:33
【问题描述】:

我想用 ~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;
            }

        }
    }

【问题讨论】:

  • 你能用数学公式写出你在做什么吗?在线性代数中,可能有一些步骤可以重新排序以预先计算。
  • 基本上我有一个房间里有一张桌子的测试设置。现在我抓住桌子的视频帧并在这张照片中绘制。然后我将绘图映射到桌面上(因此我得到了带有深度的 3D 相机坐标)并将绘图转换为下一帧的方向。这使我可以在一个抓取的帧中绘制一些东西,该帧在每个其他帧都保持在相同的位置。
  • 这对优化没有帮助...我的意思是数学公式...但只是为了好奇:您是否使用发布库在发布模式下编译?

标签: c++ performance opencv computer-vision projective-geometry


【解决方案1】:

未经测试,我认为逆相机矩阵的计算是代码中最昂贵的操作。假设相机矩阵是常数,您可以预先计算逆矩阵。

Mat invCameraMatrix(CameraMatrix480.inv());
...
p11 = invCameraMatrix*p;  //Pixel-->Camera
...

此外,您可以轻松地将for 循环与OpenMP 并行化,并检查它是否获得任何性能。要使用CUDA,您需要一块 Nvidia 显卡,这可能在您的 Windows 平板设备中不可用。

【讨论】:

  • inv() 只需要总计算量的 3%,但我仍然会预先计算它。最昂贵的部分是 16% 的点积。我不认为函数这么慢,我只是经常调用它们(每帧最多 100.000 次迭代)
  • 你确定吗?我刚刚在我的机器上测试了它。反转一个3x4 矩阵比两个3x1 向量的点积要慢大约 3 倍(反转大约需要 0.3 毫秒,点积大约需要 9.9e-5 毫秒)。
【解决方案2】:

您可以尝试使用cv::UMat 进行性能测试吗?

我使用OpenMP 进行像素快速图像操作。

【讨论】:

  • 我只是尝试将 Mat 更改为 UMat,但它根本没有改善。我会尽快尝试 OpenMP。
【解决方案3】:

您是否考虑过将操作更改为float 而不是double?由于您使用的是移动设备,因此它可能有助于加快操作速度。

另外,最后一个if 条件中的rect 是什么?

【讨论】:

  • 最初我使用浮点数,但我的一些函数只接受双精度。 rect 只是一个与我的输出图像大小相同的矩形。这样我可以检查我的投影点是否在图像内。
  • 尝试将事物转换回浮动。仅针对该特定函数调用转换为双精度。如果可能,请尝试找出平台上浮点数的硬件优化。另外,将每一行分成一个子任务是否有助于分析?我可以看到一些行在同一行中执行矩阵减法、叉积和标量乘法。
【解决方案4】:

我设法在大约 40 毫秒内为 720p 图像运行转换,只需使用 Matx 而不是 Mat。图像存储在 UMat 中,也许这也有帮助。

【讨论】:

    猜你喜欢
    • 2011-05-15
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多