从 16UC3 到 8UC3 的高性能 OpenCV 矩阵转换

High performance OpenCV matrix conversion from 16UC3 to 8UC3

本文关键字:OpenCV 转换 高性能 16UC3 8UC3      更新时间:2023-10-16

我有一个OpenCVCV_16UC3矩阵,其中每个通道只有较低的8Bit被占用。我想从中创建CV_8UC3。目前我使用这种方法:

cv::Mat mat8uc3_rgb(imgWidth, imgHeight, CV_8UC3);
mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3);

这有预期的结果,但我想知道它是否可以以某种方式更快或更高性能。

编辑

整个处理链仅包含 4 个子步骤(计算时间帧由视频场景的 QueryPerformanceCounter 测量确定(

  1. 在 OpenCV-Mat 中挂载原始字节缓冲区:cv::Mat mat16uc1_bayer(imgHeight, RawImageWidth, CV_16UC1, (uint8*)payload);

  2. 德摩赛金 ->cv::cvtColor(mat16uc1_bayer, mat16uc3_rgb, cv::COLOR_BayerGR2BGR);
    需要 0.008808[s]

  3. 像素偏移(16 位中只有 12 位被占用,但我们只需要其中的 8 位( -> 使用 openCV 并行访问像素,使用mat16uc3_rgb.forEach<>
    需要 0.004927[s]

  4. 从CV_16UC3到CV_8UC3的转换mat16uc3_rgb.convertTo(mat8uc3_rgb, CV_8UC3);需要 0.006913[s]

我想如果没有将原始缓冲区转换为 CvMat 或演示,我将无法做到。像素偏移可能不会进一步加速(这里已经使用了并行化的 forEach((。我希望在从CV_8UC3转换为CV_16UC3时可以更新矩阵标题信息或类似信息,因为矩阵数据已经正确,不必再缩放或类似。

我认为您可以放心地假设cv::Mat::convertTo是该操作的最快实现。 看到你从一个色彩空间到另一个色彩空间,这可能不是一个零成本的操作。重新排列需要内存副本。

如果您正在设计一个非常高性能的系统,您应该对瓶颈进行深入分析,并重新设计您的系统以尽量减少它们。问问自己:此时真的需要这种转换吗?我可以通过制作一个将多个操作集成在一起的自定义函数来解决吗?是否可以使用 CPU 并行扩展、多线程或 GPU 加速?等。