“*mat.ptr<float>(i,j)”和“*mat.ptr(i,j)”的区别?

The difference of " *mat.ptr<float>(i,j)" and "*mat.ptr(i,j)"?

提问人:meng lu 提问时间:11/16/2023 更新时间:11/16/2023 访问量:44

问:

我正在尝试使用以下代码修改 Opencv::Mat 中的值:

void gaussian_high_pass_kernel(cv::Mat& gaussianBlur, float sigma) 
{ 
    float d0 = sigma; 
    for (int i = 0; i < scr.rows; i++) 
    {   
        for (int j = 0; j < scr.cols; j++) 
        {       
            float d = pow(float(i - scr.rows / 2), 2) + pow(float(j - scr.cols / 2), 2);                                
            *gaussianBlur.ptr(i, j) = 1 - expf(-d / (2 * d0 * d0));     
        } 
    }  
}

行中似乎有一个错误;。它没有像我预期的那样工作,未能将新值分配给 。相反,cv::Mat gaussianBlur 中的所有值最终都为 -4.31596e+08。*gaussianBlur.ptr(i, j) = 1 - expf(-d / (2 * d0 * d0))gaussianBlur[i,j]

但是,当我将此行修改为 ;时,它可以正常工作。我想了解这两种方法之间的区别。*gaussianBlur.ptr<float>(i,j) = 1 - expf(-d / (2 * d0 * d0))

有人可以解释为什么直接访问元素 using 不会产生预期的结果,而显式指定数据类型可以解决问题吗?任何见解或解释将不胜感激。谢谢!*gaussianBlur.ptr(i, j)*gaussianBlur.ptr<float>(i,j)

C++ opencv 指针 mat 函数模板

评论

0赞 BoP 11/16/2023
它们只是不同的函数,一个是返回的非模板,另一个返回(当要求时)。如果你问我,一个糟糕的设计。uchar*float*
0赞 Christoph Rackwitz 11/16/2023
对于简单的元素访问,您不应该使用 OR。use -- 是的,opencv 很旧,Mat 类未使用 C++ 功能。垫子知道它们的类型,但在类型系统级别上不知道。在这方面,有些重新实施的尝试在某种程度上更安全。.ptr().ptr<type>().at<type>()
0赞 Aconcagua 11/16/2023
确实有模板和非模板变体???非常不幸的:( – 但是,如果没有,那么问题仍然有意义:前一种形式明确指定用于实例化的类型,而对于第二种形式,编译器将从函数参数中推断出模板类型(只是为了这种情况,这可能是未知的......ptr

答:

0赞 DrBobs 11/16/2023 #1

*gaussianBlur.ptr(i, j) 和 *gaussianBlur.ptr(i, j) 的区别在于数据类型解释。

使用 *gaussianBlur.ptr(i, j) 时,指针被视为指向数据的泛型指针,并且不会显式指定类型信息。编译器需要根据矩阵的类型(gaussianBlur)来推断类型,并且它可能并不总是推导出正确的类型,从而导致意外的结果。

另一方面,当您使用 *gaussianBlur.ptr(i, j) 时,您明确告诉编译器将指定位置的数据解释为浮点数。这可确保使用正确的类型进行解释,从而防止类型转换中出现任何歧义。

在本例中,如果矩阵 gaussianBlur 的类型为 CV_32F(32 位浮点),则显式使用 *gaussianBlur.ptr(i, j) 可确保使用正确的类型,并且赋值按预期工作。

总之,使用 *gaussianBlur.ptr(i, j) 的显式类型规范是避免与类型推断相关的潜在问题的良好做法,尤其是在处理不同数据类型的矩阵时。它为编译器提供了有关如何解释数据的清晰信息,从而生成更可预测且无错误的代码。

评论

0赞 Christoph Rackwitz 11/19/2023
请查看 stackoverflow.com/editing-help 并校对您的帖子
0赞 Christoph Rackwitz 11/19/2023
这个答案是由人工智能生成的吗?