来自OpenCV Mat对象的奇怪像素值

时间:2014-10-01 20:24:36

标签: c++ opencv rgb pixel scalar

我试图从OpenCV Mat对象中提取像素。当我将它们提取为Vec4b时,它可以很好地工作,但是当我使用Scalar时,这是标准的(afaik),那么我会得到奇怪的数字。如何使用Scalar并正确解释数字?

用于提取像素(0,0)的代码,一次为Vec4b广告一次为Scalar(其位于Scalar_<double>):

cv::Vec4b vec = stroke.at<cv::Vec4b>(0, 0);
printf("vec: %i, %i, %i\n", vec[0], vec[1], vec[2]);
cv::Scalar sca = stroke.at<cv::Scalar>(0, 0);
printf("sca: %5.1f, %5.1f, %5.1f\n", sca[0], sca[1], sca[2]);

输出:

vec: 223, 178, 77
sca: -91331626426359316704088074967484318223735050578187982644502863694523413598032925912253837118690612448172200441235555626964757579094862898778997953403371230682094365379726071857064466448183314663075981261984082516073752896735112503485663679145991425485597914964276617645535969580912538709979773360278601728.0, ...

我期待一些奶油黄色,所以我认为Vec3b是正确的。

2 个答案:

答案 0 :(得分:3)

这很有趣:

对于灰度,您通常会使用cv::Scalar,如下所示:

Scalar myColor = stroke.at<uchar>(Point(x, y));
std::cout << myColor.val[0] << std::endl;;

对于3-channel彩色图片,您需要cv::vec3b,如下所示:

Vec3b myColor = stroke.at<Vec3b>(Point(x, y));
 for(int i = 0; i < 3; i++) std::cout << myColor.val[i] << " ";

顾名思义(如here所示)标量是单个单位而不是向量单位。这可能会与显示的文档here混淆。但是如果你必须将你的值作为cv::Scalar类型,你可以做什么,你可以将每个vec3b索引分配给它自己的标量。即:

cv::Scalar b = vec[0];
cv::Scalar g = vec[1];
cv::Scalar r = vec[2];

答案 1 :(得分:0)

要使.at<_Tp>()函数正常工作,必须正确指定图像矩阵的组件数据类型。如果你不这样做,那么像素的二进制数据会被误解,你会得到意想不到的结果。

正确提取像素值后,您可以将其转换为您想要的任何其他通用Scalar_<_Tp>类型。通常,您将其转换为Scalar,这实际上是Scalar_<double>的别名。通过使用赋值运算符(=)隐式地完成转换。

更多详情:

大多数图像矩阵都带有类型代码CV_8UC4(4个通道,红色,绿色,蓝色和alpha)。例如。从JPG文件加载彩色图像时,图像矩阵将采用此格式。 8U表示每通道8位,无符号整数&#34;并且C4表示每个矩阵元素&#34; 4个通道&#34;。元素的相应C ++类型是Scalar_<uchar>。您必须将其指定为通用.at<_Tp>()函数才能使其正常工作:

mat.at<Scalar_<uchar>(y, x)

正确提取Scalar_<uchar>后,您只需通过分配即可自动将其转换为Scalar(实际上是Scalar_<double>):

cv::Scalar scalar = mat.at<cv::Scalar_<uchar>>(0, 0);