C++ 在不知道opencv类型的情况下访问矩阵值

C++ 在不知道opencv类型的情况下访问矩阵值,c++,opencv,mat,C++,Opencv,Mat,我正在编写一个函数,其中我需要访问Mat的元素,但此函数可以接收不同类型的Mat。因此,如果我有: filtered.at<TypeofMat>(i) = (typeofmat) somevalue; filtered.at(i)=(typeofmat)somevalue; 我只想到这样做filtered.at(i),但显然这不起作用,因为type返回一个int 我被卡住了,有人能给点提示吗?如果有可能,将接收openCV Mat的函数设置为模板函数: void f<typ

我正在编写一个函数,其中我需要访问
Mat
的元素,但此函数可以接收不同类型的
Mat
。因此,如果我有:

filtered.at<TypeofMat>(i) = (typeofmat) somevalue;
filtered.at(i)=(typeofmat)somevalue;
我只想到这样做
filtered.at(i)
,但显然这不起作用,因为
type
返回一个
int


我被卡住了,有人能给点提示吗?

如果有可能,将接收openCV Mat的函数设置为模板函数:

void f<typename T>(const Mat& m)
{
    (void) m.at<T>(0, 0);
}
void f(施工材料和材料)
{
(无效)m.at(0,0);
}
这样使用:

Mat m1/* ... */;
m1.at<int>(0, 0) = 0;
f<int>(m);
Mat m1/*…*/;
m1.at(0,0)=0;
f(m);

您可以将源矩阵转换为双精度矩阵(键入
CV_64F
)。这样,您就不会因为施法而丢失任何数据。然后你可以像往常一样处理这个矩阵,因为你知道它的类型。最后一步是将目标图像转换回源类型

不过,您需要知道矩阵的通道数。
CV\u assert
将确保您使用的是正确的类型

#include <opencv2/opencv.hpp>
using namespace cv;

void foo(const Mat& src, Mat& dst)
{
    // Assert number of channels
    CV_Assert(src.channels() == 3);

    // Convert to CV64F
    Mat3d _src, _dst;
    src.convertTo(_src, CV_64F);
    _dst.create(_src.size());

    // Work on _src and _dst (you know the type)
    _dst(0,0) = _src(0,0) + Vec3d(1,2,3);

    // Convert _dst to src type
    _dst.convertTo(dst, src.type());
}

int main()
{
    Mat3b img(10,10,Vec3b(0,0,0));

    Mat res;
    foo(img, res);

    // res will be CV_8UC3

    return 0;
}
#包括
使用名称空间cv;
无效foo(施工材料和src、材料和dst)
{
//断言通道数
CV_断言(src.channels()==3);
//转换为CV64F
Mat3d _src,_dst;
src.convertTo(_src,CV_64F);
_创建(_src.size());
//在_src和_dst上工作(您知道类型)
_dst(0,0)=src(0,0)+Vec3d(1,2,3);
//将dst转换为src类型
_convertTo(dst,src.type());
}
int main()
{
Mat3b-img(10,10,Vec3b(0,0,0));
材料;
foo(img,res);
//res将为CV_8UC3
返回0;
}
除此之外,还有其他替代方法:

  • 创建一个模板函数,并调用相应的专门化。看
  • 处理原始指针。看
  • 仅使用正确处理每种类型的OpenCV函数。看见如果可用,这通常是最好的选择

你能展示你想做的函数的简化版本吗?我正在创建应用平滑过滤器的内核。我有两个函数,一个用于创建内核(也可以访问Mat元素),另一个用于计算卷积。通常,如果您知道通道数(这里应该是1,对吗?),您只需在内部将所有矩阵转换为double
CV_64F
,并在内部处理double。然后将结果转换回原始类型。我将尝试,谢谢!,它可以工作,让你的评论成为一个答案:-)你可以在内部将图像转换为CV_64FC3,并使用Double。这只是一个一般的疑问,下面答案中的模板方法可以工作吗?是的,但是你需要一个
开关来选择调用函数中具有正确模板的函数。这相当于我提到的第一种替代方法