Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV get pixel channel value from Mat image

Maybe I'm not looking hard enough, but everything seems to want me to use an array. Thus, how do I get the channel value for a particular pixel for foo if foo is something like Mat foo = imread("bar.png")?

like image 970
HRÓÐÓLFR Avatar asked Oct 26 '11 05:10

HRÓÐÓLFR


People also ask

What is CV_32FC1?

CV_32F defines the depth of each element of the matrix, while. CV_32FC1 defines both the depth of each element and the number of channels.

What is Vec3b?

Vec3b is the abbreviation for "vector with 3 byte entries" Here those byte entries are unsigned char values to represent values between 0 .. 255. Each byte typically represents the intensity of a single color channel, so on default, Vec3b is a single RGB (or better BGR) pixel.

What is CV_8UC3?

CV_8UC3 - 3 channel array with 8 bit unsigned integers. CV_8UC4 - 4 channel array with 8 bit unsigned integers. CV_8UC(n) - n channel array with 8 bit unsigned integers (n can be from 1 to 512) )


2 Answers

Assuming the type is CV_8UC3 you would do this:

for(int i = 0; i < foo.rows; i++) {     for(int j = 0; j < foo.cols; j++)     {         Vec3b bgrPixel = foo.at<Vec3b>(i, j);          // do something with BGR values...     } } 

Here is the documentation for Vec3b. Hope that helps! Also, don't forget OpenCV stores things internally as BGR not RGB.

EDIT :
For performance reasons, you may want to use direct access to the data buffer in order to process the pixel values:

Here is how you might go about this:

uint8_t* pixelPtr = (uint8_t*)foo.data; int cn = foo.channels(); Scalar_<uint8_t> bgrPixel;  for(int i = 0; i < foo.rows; i++) {     for(int j = 0; j < foo.cols; j++)     {         bgrPixel.val[0] = pixelPtr[i*foo.cols*cn + j*cn + 0]; // B         bgrPixel.val[1] = pixelPtr[i*foo.cols*cn + j*cn + 1]; // G         bgrPixel.val[2] = pixelPtr[i*foo.cols*cn + j*cn + 2]; // R          // do something with BGR values...     } } 

Or alternatively:

int cn = foo.channels(); Scalar_<uint8_t> bgrPixel;  for(int i = 0; i < foo.rows; i++) {     uint8_t* rowPtr = foo.row(i);     for(int j = 0; j < foo.cols; j++)     {         bgrPixel.val[0] = rowPtr[j*cn + 0]; // B         bgrPixel.val[1] = rowPtr[j*cn + 1]; // G         bgrPixel.val[2] = rowPtr[j*cn + 2]; // R          // do something with BGR values...     } } 
like image 180
mevatron Avatar answered Oct 11 '22 11:10

mevatron


The below code works for me, for both accessing and changing a pixel value.

For accessing pixel's channel value :

for (int i = 0; i < image.cols; i++) {     for (int j = 0; j < image.rows; j++) {         Vec3b intensity = image.at<Vec3b>(j, i);         for(int k = 0; k < image.channels(); k++) {             uchar col = intensity.val[k];          }        } } 

For changing a pixel value of a channel :

uchar pixValue; for (int i = 0; i < image.cols; i++) {     for (int j = 0; j < image.rows; j++) {         Vec3b &intensity = image.at<Vec3b>(j, i);         for(int k = 0; k < image.channels(); k++) {             // calculate pixValue             intensity.val[k] = pixValue;         }      } } 

`

Source : Accessing pixel value

like image 40
Yoda Avatar answered Oct 11 '22 11:10

Yoda