gpt4 book ai didi

c++ - 在 OpenCV 中循环遍历 16 位 Mat 像素的有效方法

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:04:18 28 4
gpt4 key购买 nike

我正在尝试在 16 位灰度 OpenCV Mat 上进行非常简单(类似于 LUT)的操作,这种操作非常高效并且不会减慢调试器的速度。

虽然有一个very detailed page in the documentation正是针对这个问题,它没有指出大多数这些方法仅适用于 8 位图像(包括完美、优化的 LUT 函数)。

我尝试了以下方法:

uchar* p = mat_depth.data;
for (unsigned int i = 0; i < depth_width * depth_height * sizeof(unsigned short); ++i)
{
*p = ...;
*p++;
}

真的很快,可惜只支持 uchart(就像 LUT)。


int i = 0;
for (int row = 0; row < depth_height; row++)
{
for (int col = 0; col < depth_width; col++)
{
i = mat_depth.at<short>(row, col);
i = ..
mat_depth.at<short>(row, col) = i;
}
}

改编自此答案:https://stackoverflow.com/a/27225293/518169 .对我不起作用,而且速度很慢。


cv::MatIterator_<ushort> it, end;
for (it = mat_depth.begin<ushort>(), end = mat_depth.end<ushort>(); it != end; ++it)
{
*it = ...;
}

效果很好,但是它使用大量 CPU 并使调试器 super 慢。


这个答案https://stackoverflow.com/a/27099697/518169指出 source code of the built-in LUT function ,但是它只提到高级优化技术,如 IPP 和 OpenCL。

我正在寻找的是一个非常简单的循环,就像第一个代码,但用于 ushorts。

您推荐什么方法来解决这个问题?我不是在寻找极端的优化,只是在寻找与 .data 上的单个 for 循环的性能相当的东西。

最佳答案

我实现了 Michael 和 Kornel 的建议,并在发布和 Debug模式下对它们进行了基准测试。

代码:

cv::Mat LUT_16(cv::Mat &mat, ushort table[])
{
int limit = mat.rows * mat.cols;

ushort* p = mat.ptr<ushort>(0);
for (int i = 0; i < limit; ++i)
{
p[i] = table[p[i]];
}
return mat;
}

cv::Mat LUT_16_reinterpret_cast(cv::Mat &mat, ushort table[])
{
int limit = mat.rows * mat.cols;

ushort* ptr = reinterpret_cast<ushort*>(mat.data);
for (int i = 0; i < limit; i++, ptr++)
{
*ptr = table[*ptr];
}
return mat;
}

cv::Mat LUT_16_if(cv::Mat &mat)
{
int limit = mat.rows * mat.cols;

ushort* ptr = reinterpret_cast<ushort*>(mat.data);
for (int i = 0; i < limit; i++, ptr++)
{
if (*ptr == 0){
*ptr = 65535;
}
else{
*ptr *= 100;
}
}
return mat;
}

ushort* tablegen_zero()
{
static ushort table[65536];
for (int i = 0; i < 65536; ++i)
{
if (i == 0)
{
table[i] = 65535;
}
else
{
table[i] = i;
}
}
return table;
}

结果如下(发布/调试):

  • LUT_16:0.202 毫秒/0.773 毫秒
  • LUT_16_reinterpret_cast:0.184 毫秒/0.801 毫秒
  • LUT_16_if:0.249 毫秒/0.860 毫秒

所以结论是 reinterpret_cast 在 Release模式下快了 9%,而 ptr 在 Debug模式下快了 4%。

同样有趣的是,直接调用 if 函数而不是应用 LUT 只会使它慢 0.065 毫秒。

规范:流式传输 640x480x16 位灰度图像,Visual Studio 2013,i7 4750HQ。

关于c++ - 在 OpenCV 中循环遍历 16 位 Mat 像素的有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28423701/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com