在openCV中访问某些像素RGB值

时间:2012-01-19 20:35:21

标签: c++ opencv

我已经彻底搜索了互联网和stackoverflow,但我没有找到我的问题的答案:

如何在OpenCV中获取/设置(两者)某些(由x,y坐标给定)像素的RGB值?重要的是 - 我用C ++编写,图像存储在cv :: Mat变量中。我知道有一个IplImage()操作符,但IplImage在使用时不太舒服 - 据我所知它来自C API。

是的,我知道已有这个Pixel access in OpenCV 2.2主题,但它只是关于黑白位图。

修改

非常感谢您的所有答案。我看到有很多方法来获取/设置像素的RGB值。我从亲密的朋友那里得到了一个想法 - 谢谢Benny!这非常简单有效。我认为这是你选择的品味问题。

Mat image;

(...)

Point3_<uchar>* p = image.ptr<Point3_<uchar> >(y,x);

然后您可以使用以下内容读取/写入RGB值:

p->x //B
p->y //G
p->z //R

6 个答案:

答案 0 :(得分:89)

尝试以下方法:

cv::Mat image = ...do some stuff...;

image.at<cv::Vec3b>(y,x);为您提供类型为cv::Vec3b

的RGB(可能按BGR排序)矢量
image.at<cv::Vec3b>(y,x)[0] = newval[0];
image.at<cv::Vec3b>(y,x)[1] = newval[1];
image.at<cv::Vec3b>(y,x)[2] = newval[2];

答案 1 :(得分:15)

低级方式是直接访问矩阵数据。在RGB图像中(我相信OpenCV通常存储为BGR),并假设您的cv :: Mat变量被称为frame,您可以在位置获得蓝色值(x,{{1} })(从左上角)这样:

y

同样,要获得B,G和R:

frame.data[frame.channels()*(frame.rows*y + x)];

请注意,此代码假定步幅等于图像的宽度。

答案 2 :(得分:2)

对于遇到此类问题的人来说,一段代码更容易。我分享我的代码,你可以直接使用它。请注意,OpenCV将像素存储为BGR。

cv::Mat vImage_; 

if(src_)
{
    cv::Vec3f vec_;

    for(int i = 0; i < vHeight_; i++)
        for(int j = 0; j < vWidth_; j++)
        {
            vec_ = cv::Vec3f((*src_)[0]/255.0, (*src_)[1]/255.0, (*src_)[2]/255.0);//Please note that OpenCV store pixels as BGR.

            vImage_.at<cv::Vec3f>(vHeight_-1-i, j) = vec_;

            ++src_;
        }
}

if(! vImage_.data ) // Check for invalid input
    printf("failed to read image by OpenCV.");
else
{
    cv::namedWindow( windowName_, CV_WINDOW_AUTOSIZE);
    cv::imshow( windowName_, vImage_); // Show the image.
}

答案 3 :(得分:0)

当前版本允许cv::Mat::at函数处理3 dimensions。因此,对于Mat对象mm.at<uchar>(0,0,0)应该有效。

答案 4 :(得分:0)

uchar * value = img2.data; //Pointer to the first pixel data ,it's return array in all values 
int r = 2;
for (size_t i = 0; i < img2.cols* (img2.rows * img2.channels()); i++)
{

        if (r > 2) r = 0;

        if (r == 0) value[i] = 0;
        if (r == 1)value[i] =  0;
        if (r == 2)value[i] = 255;

        r++;
}

答案 5 :(得分:-4)

const double pi = boost::math::constants::pi<double>();

cv::Mat distance2ellipse(cv::Mat image, cv::RotatedRect ellipse){
    float distance = 2.0f;
    float angle = ellipse.angle;
    cv::Point ellipse_center = ellipse.center;
    float major_axis = ellipse.size.width/2;
    float minor_axis = ellipse.size.height/2;
    cv::Point pixel;
    float a,b,c,d;

    for(int x = 0; x < image.cols; x++)
    {
        for(int y = 0; y < image.rows; y++) 
        {
        auto u =  cos(angle*pi/180)*(x-ellipse_center.x) + sin(angle*pi/180)*(y-ellipse_center.y);
        auto v = -sin(angle*pi/180)*(x-ellipse_center.x) + cos(angle*pi/180)*(y-ellipse_center.y);

        distance = (u/major_axis)*(u/major_axis) + (v/minor_axis)*(v/minor_axis);  

        if(distance<=1)
        {
            image.at<cv::Vec3b>(y,x)[1] = 255;
        }
      }
  }
  return image;  
}