当使用 CV_8SC3、CV_16FC3、CV_16FC1 时,我应该在 cv::Mat.at<data_type> 中使用什么数据类型?

What data type should I use in cv::Mat.at<data_type> when using CV_8SC3, CV_16FC3, CV_16FC1?

当遍历图像并索引 (i, j) 时,OpenCVcv::Mat 中提供了方法 at。为了获得该像素的正确值,我们需要仔细指定数据类型,否则我们可能会得到一些意想不到的值。

例如,如果您使用 CV_16SC3 创建 cv::Mat,如下所示:

cv::Mat img(h, w, CV_16SC3, cv::Scalar(-32, -64, -64));

索引值时,您应该使用 cv::Vec3s,例如:

img.at<cv::Vec3s>(i, j)[c]

如果你使用其他类型,比如 img.at<cv::Vec3f>,你会得到一些错误的值。

现在我们知道填写正确数据类型的重要性了,下面的table就是我知道要输入什么数据类型才能得到正确的值。

    CV_8UC3  -> cv::Vec3b   CV_8UC1  -> uchar 
    CV_8SC3                 CV_8SC1  -> char
    CV_16UC3 -> cv::Vec3w   CV_16UC1 -> ushort
    CV_16SC3 -> cv::Vec3s   CV_16SC1 -> short  
    CV_32SC3 -> cv::Vec3i   CV_32SC3 -> int

    CV_64FC3 -> cv::Vec3d   CV_64FC1 -> double
    CV_32FC3 -> cv::Vec3f   CV_32FC1 -> float
    CV_16FC3 ->             CV_16FC1 -> 

我想知道 CV_8SC3, CV_16FC3, CV_16FC1,我应该写什么数据类型才能得到正确的值?提前致谢!

您可以根据自己的需求定义自己的专业。 cv::Vecxx 只是 Vec

最流行的专业化的一堆较短的 aliases

所以:

  • 对于 CV_8SC3,您可以使用 cv::Vec<char, 3>
  • 对于 CV_16FC3,您可以使用 cv::Vec<cv::float16_t, 3>
  • 对于 CV_16FC1,您可以使用 cv::Vec<cv::float16_t, 1>

此外,如果你只是想遍历一个cv::Mat,其实有很多方法可以做到,例如at方法有这个重载version

template<typename _Tp >
const _Tp& cv::Mat::at (int i0, int i1, int i2) const

希望这份官方文档能对您有更多帮助: https://docs.opencv.org/4.x/db/da5/tutorial_how_to_scan_images.html