C++ 在openCV中访问某些像素RGB值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8932893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Accessing certain pixel RGB value in openCV
提问by Wookie88
I have searched internet and stackoverflow thoroughly, but I haven't found answer to my question:
我已经彻底搜索了互联网和 stackoverflow,但我还没有找到我的问题的答案:
How can I get/set (both) RGB value of certain (given by x,y coordinates) pixel in OpenCV? What's important-I'm writing in C++, the image is stored in cv::Mat variable. I know there is an IplImage() operator, but IplImage is not very comfortable in use-as far as I know it comes from C API.
如何在 OpenCV 中获取/设置(两个)某些(由 x,y 坐标给出)像素的 RGB 值?重要的是 - 我用 C++ 编写,图像存储在 cv::Mat 变量中。我知道有一个 IplImage() 操作符,但 IplImage 使用起来不是很舒服——据我所知它来自 C API。
Yes, I'm aware that there was already this Pixel access in OpenCV 2.2thread, but it was only about black and white bitmaps.
是的,我知道OpenCV 2.2线程中已经有这个Pixel 访问,但它只是关于黑白位图。
EDIT:
编辑:
Thank you very much for all your answers. I see there are many ways to get/set RGB value of pixel. I got one more idea from my close friend-thanks Benny! It's very simple and effective. I think it's a matter of taste which one you choose.
非常感谢您的所有回答。我看到有很多方法可以获取/设置像素的 RGB 值。我从我的密友那里又得到了一个想法——谢谢 Benny!这是非常简单和有效的。我认为这是你选择哪一个的品味问题。
Mat image;
(...)
(……)
Point3_<uchar>* p = image.ptr<Point3_<uchar> >(y,x);
And then you can read/write RGB values with:
然后您可以使用以下命令读取/写入 RGB 值:
p->x //B
p->y //G
p->z //R
回答by Boaz
Try the following:
请尝试以下操作:
cv::Mat image = ...do some stuff...;
image.at<cv::Vec3b>(y,x);
gives you the RGB (it might be ordered as BGR) vector of type cv::Vec3b
image.at<cv::Vec3b>(y,x);
为您提供类型为 RGB(可能按 BGR 排序)向量 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];
回答by aardvarkk
The low-level way would be to access the matrix data directly. In an RGB image (which I believe OpenCV typically stores as BGR), and assuming your cv::Mat variable is called frame
, you could get the blue value at location (x
, y
) (from the top left) this way:
低级方法是直接访问矩阵数据。在 RGB 图像(我相信 OpenCV 通常存储为 BGR)中,假设您的 cv::Mat 变量被调用frame
,您可以通过以下方式在位置 ( x
, y
)(从左上角)获得蓝色值:
frame.data[frame.channels()*(frame.cols*y + x)];
Likewise, to get B, G, and R:
同样,要得到 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];
Note that this code assumes the stride is equal to the width of the image.
请注意,此代码假定步幅等于图像的宽度。
回答by ShannonLiu
A piece of code is easier for people who have such problem. I share my code and you can use it directly. Please note that OpenCV store pixels as BGR.
对于有这种问题的人来说,一段代码更容易。我分享我的代码,你可以直接使用它。请注意,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.
}
回答by Jacob
The current version allows the cv::Mat::at
function to handle 3 dimensions. So for a Mat
object m
, m.at<uchar>(0,0,0)
should work.
当前版本允许该cv::Mat::at
函数处理3 个维度。所以对于一个Mat
object m
,m.at<uchar>(0,0,0)
应该可以工作。
回答by Saef Myth
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++;
}
回答by user537723
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;
}