C++ 访问openCV中的特定像素RGB值

C++ 访问openCV中的特定像素RGB值,c++,opencv,C++,Opencv,我已经彻底搜索了互联网和stackoverflow,但我还没有找到我的问题的答案: 如何在OpenCV中获取/设置特定(由x,y坐标给出)像素的(两者)RGB值?重要的是,我用C++编写,图像存储在CV::Mat变量中。我知道有一个IplImage()操作符,但据我所知,IplImage在使用中并不太舒服,因为它来自C API 是的,我知道已经有这个帖子了,但它只是关于黑白位图的。 编辑: 非常感谢你的回答。我知道有很多方法可以获取/设置像素的RGB值。我从我的密友那里又得到了一个主意谢谢Ben

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

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

是的,我知道已经有这个帖子了,但它只是关于黑白位图的。

编辑:

非常感谢你的回答。我知道有很多方法可以获取/设置像素的RGB值。我从我的密友那里又得到了一个主意谢谢Benny!它非常简单有效。我认为你选择哪一个是品味的问题

Mat image;
(……)


低级方法是直接访问矩阵数据。在RGB图像(我认为OpenCV通常存储为BGR)中,假设cv::Mat变量名为
frame
,则可以通过以下方式获得位置(
x
y
)处的蓝色值:

frame.data[frame.channels()*(frame.cols*y + x)];
同样,要得到B、G和R:

uchar b = frame.data[frame.channels()*(frame.cols*y + x) + 0];    
uchar g = frame.data[frame.channels()*(frame.cols*y + x) + 1];
uchar r = frame.data[frame.channels()*(frame.cols*y + x) + 2];

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

当前版本允许使用
cv::Mat::at
函数处理。因此,对于
Mat
对象
m
m.at(0,0,0)
应该可以工作。

尝试以下操作:

cv::Mat image = ...do some stuff...;
image.at(y,x)
为您提供类型为
cv::Vec3b

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];
image.at(y,x)[0]=newval[0];
image.at(y,x)[1]=newval[1];
image.at(y,x)[2]=newval[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.
}
cv::Mat vImage\uux;
if(src_2;)
{
cv::Vec3f-vec;
对于(int i=0;i
const double pi=boost::math::constants::pi();
cv::Mat distance2ellipse(cv::Mat图像,cv::RotatedRect椭圆){
浮动距离=2.0f;
浮动角度=椭圆角度;
cv::点椭圆\中心=椭圆.中心;
浮动长轴=椭圆.size.width/2;
浮动短轴=椭圆.size.height/2;
点像素;
浮子a、b、c、d;
对于(int x=0;xuchar*value=img2.data;//指向第一个像素数据的指针,则它是所有值中的返回数组
int r=2;
对于(size_t i=0;i2)r=0;
如果(r==0)值[i]=0;
如果(r==1)值[i]=0;
如果(r==2)值[i]=255;
r++;
}

谢谢,在读取RGB值时,它起作用了。我试图将frame.data[…]设置为某些值,但运气不好,但Boaz.Jan给出的解决方案起作用了。@aaedvarkk太棒了,你救了我一天!它不应该是
frame.data[frame.channels()*(frame.cols*y+x)]
?实际上,此版本的
at
在多通道Mat上不起作用。尽管二维多通道Mat与三维单通道Mat具有相同的内存布局,但由于Mat头的差异,该方法将引发异常。您能建议我使用相同的Ipl图像吗?当然!请查看cvGet2D,您可以吗请用IplImage帮助我写同样的东西。@Frankenstein看到我的评论了吗cvGet2D@Ahmadtypedef Vec Vec3b;-表示一个包含3个uchars(0-255)的向量,RGB的每个分量(R、G和B)都用一个介于0和255之间的数值表示。“at”image方法是表示二维矩阵的类cv::Mat的一种方法。如果说cv::Mat的单元类型为cv_8UC3,则表示矩阵中的每个单元都将适合3个通道,每个通道8位。a这如何回答问题?
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];
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.
}
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;  
}
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++;
}