微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

自动浏览具有不同数据类型的OpenCV Mat

如何解决自动浏览具有不同数据类型的OpenCV Mat

在OpenCV> = 3.0中逐步通过OpenCV Mat时,这是一个普遍的问题

目前,对于OpenCV Mat的每种数据类型(32F,8U,64F,16S),我都有几乎复制粘贴的功能。这不是很好,因为如果我想更改任何内容,则必须在所有4个功能中都进行更改。

让我们以一个“最大”函数为例,我逐个遍历像素元素。

uchar* imPtr = (uchar*)A.data;
uchar max=0,dummy;
for (int i = 0; i < A.rows; i++)
{
    const uchar* Mi = A.ptr<uchar>(i);
    for (int j = 0; j < A.cols; j++)
    {
        dummy = Mi[j];
        if (dummy > max)
        {
            max = dummy;
        }
    }
}
return max;

如果要为4种数据类型编写此代码,则需要使用(double ),(float ),(int )和(uchar )。有没有做类似(auto *)之类的好方法

解决方法

请考虑使用Mat_类模板而不是Mat。使用Mat_,您可以在编译时知道类型,并且很容易将函数重写为类型安全的函数模板:

template<class T>
T Max(cv::Mat_<T>& A) {
    T* imPtr = (T*)A.data;
    T max = 0,dummy;
    for (int i = 0; i < A.rows; i++) {
        const T* Mi = A.ptr<T>(i);
        for (int j = 0; j < A.cols; j++) {
            dummy = Mi[j];
            if (dummy > max)
                max = dummy;
        }
    }
    return max;
}

cv::Mat_<uint8_t> mat1 = (cv::Mat_<uint8_t>(2,2) << 1,2,3,4);
std::cout << (int)Max(mat1) << std::endl; // 4
cv::Mat_<float> mat2 = (cv::Mat_<float>(2,2) << 4,12,11);
std::cout << Max(mat2) << std::endl; // 12

您可以继续使用cv::Mat,但随后必须明确指定所需的类型:

template<class T>
T Max2(cv::Mat& A) {
    T* imPtr = (T*)A.data;
    T max = 0,dummy;
    for (int i = 0; i < A.rows; i++) {
        const T* Mi = A.ptr<T>(i);
        for (int j = 0; j < A.cols; j++) {
            dummy = Mi[j];
            if (dummy > max)
                max = dummy;
        }
    }
    return max;
}

short data[] = { 1,1 };
cv::Mat mat3(2,CV_16SC1,data);
std::cout << Max2<short>(mat3) << std::endl; // 3

但是使用此版本,很容易产生错误,例如,如果使用T构造int时将Mat指定为CV_32FC1-find max将截断将所有浮点数都加到int,这将导致返回错误的结果。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。