opencv 访问 CV_32FC3 BGR cv::Mat 的颜色元素

Posted

技术标签:

【中文标题】opencv 访问 CV_32FC3 BGR cv::Mat 的颜色元素【英文标题】:opencv accessing color element of CV_32FC3 BGR cv::Mat 【发布时间】:2012-03-21 19:19:54 【问题描述】:

我有一个问题。我见过一些更类似的问题,但我找不到解决方案。

我的问题是我有一个 CV_32FC3 cv::Mat,其中的值存储在 0 到 255 之间,我们称之为 S。

我必须创建一个称为 P 的矩阵,其中存储所有像素的 BGR 值。

所以 P 的行数应该是 S 像素的总元素,而列数应该是通道数 (3)。

这是我尝试做的:

int n_pixels = S.cols * S.rows;
p = Mat::zeros(n_pixels, 3, CV_32FC1);

for(int i=0; i<n_pixels; i++) 
    Scalar pixel = S.at<Scalar>(i); // i've tried also Vec3f, Point3_, etc..

    p.at<float>(i,0) = pixel[0];
    p.at<float>(i,1) = pixel[1];
    p.at<float>(i,2) = pixel[2];

我也尝试过像这样的低级 c-api 数据访问:

for(int i=0; i<selection.rows; i++) 
    p.at<float>(i,0) = S.ptr<float>(i)[0];
    p.at<float>(i,1) = S.ptr<float>(i)[1];
    p.at<float>(i,2) = S.ptr<float>(i)[2];


还有拆分通道(但拆分通道的类型为 CV_8U,所以我认为这是错误的):

vector<Mat> bgr;
cv::split(S, bgr);

for(int i=0; i<n_pixels; i++) 
    p.at<float>(i,0) = bgr[0].data[i];
    p.at<float>(i,1) = bgr[1].data[i];
    p.at<float>(i,2) = bgr[2].data[i];

但是每次如果计算像素,我都会得到非常奇怪的结果,例如:

172.2042 0.0000 0.0000 
2771.1414 0.0000 0.0000 
2939505920.0000 3.3468 0.0000 
3079446986752.0000 0.0129 0.0000 
192669347217408.0000 0.8367 0.0000 
51956177323392237568.0000 16301891256320.0000 0.0509 
58314208864123224064.0000 3.3945 0.0029 
180449.1406 0.0000 0.0000 
0.6531 0.0000 0.0000 
0.0100 0.0000 0.0000 
2.7373 0.0000 0.0000 
10957.3184 0.0000 0.0000 
739729604608.0000 3.3778 0.0000 
0.0000 0.0000 0.0000 
0.0000 0.0000 0.0000 
0.0000 0.0000 0.0000 
0.0000 0.0000 0.0000 

而且,在某些情况下还有段错误..

有什么解释吗?如何解决?为什么我的试验是错误的?

编辑:我认为问题在于数据类型转换

【问题讨论】:

【参考方案1】:
for(int row = 0; row < resiz.rows; ++row) 
    float* p = resiz.ptr<float>(row);

    for(int col = 0; col < resiz.cols; ++col,p+=3) 
        p[0]=; p[1]=; p[2]=;
    

【讨论】:

请添加一些解释,更多地关注所提出的问题。 尝试添加一些解释,并在编写代码时使用代码按钮。【参考方案2】:

我认为您以错误的方式访问矩阵元素。

S.at<Scalar>(i);

相同
S.at<Scalar>(Point(i,0));

但您需要提供xy 坐标。

对我来说,这段代码给出了预期的结果:

for(int i=0; i<n_pixels; i++) 

    Vec3f pixel = S.at<Vec3f>(i/S.cols, i%S.cols);

    p.at<float>(i,0) = pixel[0];
    p.at<float>(i,1) = pixel[1];
    p.at<float>(i,2) = pixel[2];

【讨论】:

MHMM如果我打印像素I得到这样的:1242489744243719998709694464.0000 1233139367234153455891318615417290752.0000 1321104336141515779048653031332642816.0000 跨度> 您是否尝试使用Vec3f 而不是Scalar?因为Scalar 使用doublesCV_32FC3 使用floats。这可能也是一个问题。 是的,我用 Scalar 和 Vec3f 和 Vec3b 都试过同样的问题。我认为问题正是数据类型之间的转换 但对我来说就是这样。您能否使用您使用的输入数据给出一个小的运行示例,以便我可以尝试重现错误?

以上是关于opencv 访问 CV_32FC3 BGR cv::Mat 的颜色元素的主要内容,如果未能解决你的问题,请参考以下文章

减去两个 CV_64FC3 矩阵并保持负值

访问opencv矩阵CV_32S元素

访问 OpenCV 中的每个单独通道

如何在 OpenCV 中设置指向 Mat 变量内容的指针

OpenCV python:在 BGR 图像中获取通道时 cv2.split() 与切片

[0] CV Notes - 琐碎