6

我被这件事难住了很长一段时间。您能否帮我知道,Opencv 中的 minMaxLoc() 在查找 Mat 变量的最大值、最小值时考虑了什么数据类型?我从函数中得到了某个值,但我不知道该值实际代表什么,以及在什么数据类型中?

    Laplacian(src_gray,dst,ddepth,kernel_size,scale,delta,BORDER_DEFAULT);
    minMaxLoc(dst,&min,&estimate,&minLoc,&maxLoc,noArray());

'estimate' 的值在 1000 左右,而如果我尝试访问 'dst' Mat 变量的值,使用

    dst.at<datatype>(k,l)

如果我使用 long int,我会得到模糊的值,从 124、uchar 的 125 到 2、xxx、xxx、xxx。minMaxLoc 函数实际给出的值是多少?请帮我。

4

3 回答 3

13

min 和 estimate 应该是 double 类型,我想它们是正确的。问题可能在于您访问

dst.at<datatype>(k,l)

正如 Abhishek Thakur 提到的,输出取决于您的输入。如果您对矩阵的类型感到困惑,您可以查看 dst.type() 它返回一个整数,该整数对应于从第 557 行开始的types_c.h中定义的列表。单通道类型或“深度”的定义是

#define CV_8U   0
#define CV_8S   1 
#define CV_16U  2
#define CV_16S  3
#define CV_32S  4
#define CV_32F  5
#define CV_64F  6

您可以在第 573 行看到用于计算其他类型标识符的公式

#define CV_CN_SHIFT   3
#define CV_DEPTH_MAX  (1 << CV_CN_SHIFT)

#define CV_MAT_DEPTH_MASK       (CV_DEPTH_MAX - 1)
#define CV_MAT_DEPTH(flags)     ((flags) & CV_MAT_DEPTH_MASK)

#define CV_MAKETYPE(depth,cn) (CV_MAT_DEPTH(depth) + (((cn)-1) << CV_CN_SHIFT))

例如

#define CV_8UC4 CV_MAKETYPE(CV_8U,4)

有类型

0+((4-1) << 3) == 24

因此对于 4 通道的 uchar 图像,type() 将返回 24。从上面可以看出,类型的深度由整数类型的最后 3 位表示。如果您想要的只是深度(您不在乎它有多少个频道),您可以直接使用 dst.depth()

于 2013-01-16T19:08:41.957 回答
3

锤子的答案非常清楚,它向您展示了一个很好的提示:始终检查数据类型并注意types_c.h,每次需要时都检查一下!

无论如何, minMaxLoc 返回一个 double 但它已经为你做了演员。如果您将 uchar Mat 对象作为输入数组,它将在 0-255 范围内(uchar 范围!)将 2 个双精度变量设置为双精度。

看这个例子:

#include <opencv2/core/core.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int /*argc*/, char** /*argv*/) {

    double m, M;
    Point p_min, p_max;
    Mat img;

    // let's do with uchar Mat
    img = (Mat_<uchar>(3,3) << 0,1,2,3,4,5,6,7,255); 
    cout << img << endl;
    minMaxLoc(img, &m, &M, &p_min, &p_max);
    cout << "min: " << m << " at " << p_min << endl;
    cout << "max: " << M << " at " << p_max << endl;
    cout << (int)img.at<uchar>(p_max.y, p_max.x) << endl; // cast to int otherwise cout will print an ASCII (uchar)

    // now with float Mat
    img = (Mat_<float>(3,3) << 0.1f,1.2f,2,3000.2f,4,5,6,7,255); 
    cout << img << endl;
    minMaxLoc(img, &m, &M, &p_min, &p_max);
    cout << "min: " << m << " at " << p_min << endl;
    cout << "max: " << M << " at " << p_max << endl;
    cout << img.at<float>(p_max.y, p_max.x) << endl;

    return 0;
}

现在,在您发布的代码中,您在ddepth. 您可以将ddepth数据类型指定为 opencv 常量,例如:

ddepth = CV_8UC1

在这种情况下, cv::Laplacian 将返回一个 uchar Mat。

因此,请始终注意您要处理的数据类型。如果您正在使用彩色图像,您可能会更好地使用Mat::at<Scalar>().

于 2013-01-20T10:21:20.013 回答
2

这取决于你想要什么价值。对于灰度图像,如果您输入具有 uchar 数据类型的 Mat,您将得到一个介于 0 到 255 之间的值。

于 2013-01-16T18:22:31.867 回答