How to access individual pixels in OpenCV 2.3 using C++?
For my U8C3 image I tried this:
Scalar col = I.at<Scalar>(i, j);
and
p = I.ptr<uchar>(i);
First is throwing an exception, the second one is returning some unrelated data. Also all examples I was able to find are for old IIPimage(?) for C version of OpenCV.
All I need is to get color of pixel at given coordinates.
The type you call cv::Mat::at
with needs to match the type of the individual pixels. Since cv::Scalar
is basically a cv::Vec<double,4>
, this won't work for a U8C3
image (it would work for a F64C4
image, of course).
In your case you need a cv::Vec3b
, which is a typedef
for cv::Vec<uchar,3>
:
Vec3b col = I.at<Vec3b>(i, j);
You can then convert this into a cv::Scalar
if you really need to, but the type of the cv::Mat::at
instantiation must match the type of your image, since it just casts the image data without any conversions.
Your second code snippet returns a pointer to the ith row of the image. It is no unrelated data, but just a pointer to single uchar
values. So in case of a U8C3
image, every consecutive 3 elements in the data returned to p
should represent one pixel. Again, to get every pixel as a single element use
Vec3b *p = I.ptr<Vec3b>(i);
which again does nothing more than an appropriate cast of the row pointer before returning it.
EDIT: If you want to do many pixel accesses on the image, you can also use the cv::Mat_
convenience type. This is nothing more than a typed thin wrapper around the image data, so that all accesses to image pixels are appropriately typed:
Mat_<Vec3b> &U = reinterpret_cast<Mat_<Vec3b>&>(I);
You can then freely use U(i, j)
and always get a 3-tuple of unsigned chars and therefore pixels, again without any copying, just type casts (and therefore at the same performance as I.at<Vec3b>(i, j)
).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With