Opencv,在编译时找出像素的类型

Posted

技术标签:

【中文标题】Opencv,在编译时找出像素的类型【英文标题】:Opencv, figuring out the type of a pixel at compile time 【发布时间】:2017-10-27 19:55:33 【问题描述】:

tl;博士;如何从cv::Mat my_mat = cv::imread("myfile.png") 获取编译时像素类型?

我有一个我写的函数,它接受一个 Mat 迭代器:

template <typename RAI>
void my_func(RAI mat_begin, RAI mat_end) 
    typedef typename std::iterator_traits<RAI>::value_type T;
    do_stuff<T>(*mat_begin);


int main() 
    cv::Mat my_image = cv::imread("my_file");
    my_func(my_image.begin(), my_image.end());  

我可以在不明确说明RAI 是什么的情况下使用这个函数,因为我认为编译器能够在编译时弄清楚它是什么。

事实证明,我需要重构它以接收整个Mat。但是,现在我无法弄清楚如何调用do_stuff&lt;T&gt;,因为除了我的矩阵迭代器类型的iterator_traits 之外,我不知道如何弄清楚T 是什么,而且我不知道如何从我的代码中找出编译时矩阵迭代器类型,因为矩阵是通过imread 获得的,这似乎在运行时以某种方式神奇地设置了像素的类型。

【问题讨论】:

my_mat.type() 将为您提供该类型的 OpenCV 编码。您需要一个 switch-case 来使用正确的内置类型调用您的函数。 Tl;博士; imread 的默认值为 CV_8UC3 顺便说一句,tl;博士;应该放在顶部;) 但是 my_mat.type() 是运行时类型?不知何故,编译器必须在编译时找出适当的类型,因为提供的示例可以正常工作.... 是的,运行时。如果您想在编译时知道类型(通常是首选),请使用 Mat_ 及其 typedef。例如:一个运行时类型 CV_8UC3 的 Mat,在编译时是 Mat_,又名 Mat3b 从一开始......“垫子”是一个不知道它包含的类型的对象。这就是为什么你需要使用“m.at”之类的东西。您可以知道,但是它是 opencv 类型,例如CV64FC1。 “Mat_”是一个不同的对象(非常类似于“Mat”),其中类型是在编译时定义的。使用 imread 你可以做 "Mat3b img = imread("...");"获得编译时类型 = Vec3b 【参考方案1】:

OpenCV 查询 Mat.type() 值以确定基础像素类型,然后使用 if 或 switch 语句调用特定的模板特化。

例如,这里有一些来自floodfill.cppimgproc/src/floodfill.cpp 的sn-ps

Mat img = _image.getMat();
...
int type = img.type();
...
if( type == CV_8UC1 )
    floodFillGrad_CnIR<uchar, uchar, int, Diff8uC1>(
            img, mask, seedPoint, nv_buf.b[0], newMaskVal,
            Diff8uC1(ld_buf.b[0], ud_buf.b[0]),
            &comp, flags, &buffer);
else if( type == CV_8UC3 )
    floodFillGrad_CnIR<Vec3b, uchar, Vec3i, Diff8uC3>(
            img, mask, seedPoint, Vec3b(nv_buf.b), newMaskVal,
            Diff8uC3(ld_buf.b, ud_buf.b),
            &comp, flags, &buffer);
else if( type == CV_16UC1 )
    floodFillGrad_CnIR<unsigned short, uchar, int, Diff16uC1>(
            img, mask, seedPoint, nv_buf.s[0], newMaskVal,
            Diff16uC1(ld_buf.s[0], ud_buf.s[0]),
            &comp, flags, &buffer);
else if( type == CV_32SC1 )
    floodFillGrad_CnIR<int, uchar, int, Diff32sC1>(
            img, mask, seedPoint, nv_buf.i[0], newMaskVal,
            Diff32sC1(ld_buf.i[0], ud_buf.i[0]),
            &comp, flags, &buffer);
else if( type == CV_32SC3 )
    floodFillGrad_CnIR<Vec3i, uchar, Vec3i, Diff32sC3>(
            img, mask, seedPoint, Vec3i(nv_buf.i), newMaskVal,
            Diff32sC3(ld_buf.i, ud_buf.i),
            &comp, flags, &buffer);
else if( type == CV_32FC1 )
    floodFillGrad_CnIR<float, uchar, float, Diff32fC1>(
            img, mask, seedPoint, nv_buf.f[0], newMaskVal,
            Diff32fC1(ld_buf.f[0], ud_buf.f[0]),
            &comp, flags, &buffer);
else if( type == CV_32FC3 )
    floodFillGrad_CnIR<Vec3f, uchar, Vec3f, Diff32fC3>(
            img, mask, seedPoint, Vec3f(nv_buf.f), newMaskVal,
            Diff32fC3(ld_buf.f, ud_buf.f),
            &comp, flags, &buffer);
else
    CV_Error(CV_StsUnsupportedFormat, "");

【讨论】:

以上是关于Opencv,在编译时找出像素的类型的主要内容,如果未能解决你的问题,请参考以下文章

如何用opencv提取一张图片的像素矩阵

Visual Studio(VS)编译的OpenCV-C++程序(exe)运行时窗口标题乱码怎么办?(使用notepad++切换源代码的编码类型)

CMake 在编译使用 OpenCV 的项目时遇到问题

OpenCV静态库编译与链接

OpenCV 2.x 中的像素访问错误

MATLAB + Mex + OpenCV:链接和编译正确,但在运行时找不到库