4

我有一些代码希望能够同时处理 8 位和 16 位图像。

现在代码之间的唯一区别是 8 位代码使用:

filename.at<uchar>(i, j)

16位代码使用:

filename.at<ushort>(i, j)

现在最简单的方法是在顶部包含一个检查图像类型的 if 语句,然后我只有两个代码块做同样的事情,但我想避免这个,因为维护变得有点痛苦。

首先,我通读了 OpenCV 文档,我可能错过了它,但我没有看到任何返回 Mat 对象用于存储像素数据的数据类型的内容。因此,如果我错过了它,我会感到很傻,但那将是最好的。

我研究的另一个选项是函数指针,但我不确定是否可以为 .at 模板函数执行此操作。

非常感谢对任何这些选项的任何建议。

4

3 回答 3

1

一种可能的解决方案是简单地根据输入的深度进行分支。(感谢您的灵感,perfanoff!)

在访问单个像素之前:

bool eightBit = false;  //I assume 8- and 16-bits are the only options
if (m.depth() == CV_8U)
    eightBit = true;

在任何像素访问之前进行比较是一种优化,因此您可以避免调用.depth()并为每个像素进行比较,因为结果永远不会改变。

然后,在你的循环中:

if (eightBit)
{
 // Something using m.at<uchar>(i,j) 
}
else
{
 // Something using m.at<ushort>(i,j)
}

这将允许对像素数据进行读写访问。但是,像这样在内部循环中分支可能不利于性能。

于 2013-03-19T23:31:41.090 回答
0

您可以定义自己的函数来访问 Mat 中的元素。不过,您应该测试它会慢多少。

inline ushort GetPixel(const Mat& m,int x,int y)
{
    if (m.depth == CV_8U)
       return m.at<uchar>(x,y);
    else return m.at<ushort>(x,y);
}
于 2013-03-19T17:30:18.983 回答
0

这是我的 2 克拉。:

template < class T > 
void myfunction( Mat & img ) {
    // code with a lot of img.at<T>(y,x);
}

并称之为:

myfunction<ushort>(img);

或者 :

myfunction<uchar>(img);
于 2013-03-19T17:54:53.010 回答