OpenCV get pixel channel value from Mat image
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...
}
}
How access to a pixel value in a binary Mat image?
For Mat element access you can refer OpenCV official Doc and these link1, link2 might be helpful
And here is a simple code that access pixel value according to your mouse position and display the pixel value.
#include <iostream>
#include <stdio.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat image, src;
char window_name[20]="Pixel Value Demo";
void onMouse( int event, int x, int y, int f, void* ){
image=src.clone();
Vec3b pix=image.at<Vec3b>(y,x);
int B=pix.val[0];
int G=pix.val[1];
int R=pix.val[2];
char name[30];
sprintf(name,"R=%d",R);
putText(image,name, Point(10,130) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"G=%d",G);
putText(image,name, Point(10,170) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"B=%d",B);
putText(image,name, Point(10,210) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"X=%d",x);
putText(image,name, Point(10,300) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
sprintf(name,"Y=%d",y);
putText(image,name, Point(10,340) , FONT_HERSHEY_SIMPLEX, .7, Scalar(0,255,0), 2,8,false );
imshow( window_name, image );
}
int main( int argc, char** argv )
{
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
src = imread( "ball.jpg");
imshow( window_name, src );
setMouseCallback( window_name, onMouse, 0 );
waitKey(0);
return 0;
}
Edit:-
For binary image you can access pixel value with Mat::at(row,col) method.
In below example show how to do this. Here the image is of type uchar.
Mat src(480,640,CV_8UC1,Scalar(0));
circle(src,Point(src.cols/2,src.rows/2),100,Scalar(255),-1,8,0);
int pix=(int)src.at<uchar>(src.rows/2,src.cols/2);
cout<<pix<<endl;
How to make getting a pixel value independent of the cv::Mat type?
Drop the use of cv::Mat
- where you have to call type()
method (at runtime) to get the type of values stored by mat, and instead that just start using templated version of mat class: it is cv::Mat_<Type>
and write more generic code.
Then you could write only one function template to read mat pixels:
template<class T>
T access(cv::Mat_<T> const& img, int r, int c) {
return img(r,c);
}
More about cv::Mat_
here.
How to get pixel value of Mat image with webcam capture in OpenCV
The output image of distanceTransform is of type CV_32FC1
, so each pixel is of type float
. To access the pixel value, you have to do the following:
if(distanceTr.at<float>(0,0) == 0)
{
cout<<1;
}
In the opencv documentation, the description of each function parameter is given, like what is the size and type of the image etc.
Using get() and put() to access pixel values in OpenCV for Java
It was happening because of byte() casting. I changed the data type of mat image in second case to *CV_64FC3* so that I can use double[] instead of byte[] and it solved the problem.
Mat A = Highgui.imread(image_addr); //"image_addr" is the address of the image
Mat C = A.clone();
A.convertTo(A, CvType.CV_64FC3); // New line added.
int size = (int) (A.total() * A.channels());
double[] temp = new double[size]; // use double[] instead of byte[]
A.get(0, 0, temp);
for (int i = 0; i < size; i++)
temp[i] = (temp[i] / 2); // no more casting required.
C.put(0, 0, temp);
FYI, I also did some time measurement and using second method is way faster than first method.
How to get pixel value from the contoured image with mask?
A few things:
- Your variables names and
Mat
types are at least confusing. Use proper names for the variables, and useMat_<T>
whenever possible (I'd say always). - To get the mean you should divide by the number of pixels in the mask, not by total number of pixels.
- you should consider using
cv::mean
- you need
cv::waitKey()
to actually see yourcv::imshow
Check the code:
#include <opencv2\opencv.hpp>
int main()
{
cv::Mat3b star = cv::imread("path/to/image");
cv::imshow("Original", star);
cv::Mat3b hsv;
cv::cvtColor(star, hsv, cv::COLOR_BGR2HSV);
cv::Mat1b mask;
cv::inRange(hsv, cv::Scalar(29, 220, 220), cv::Scalar(30, 255, 255), mask);
cv::imshow("mask", mask);
// Change to 'false' to see how to use the 'cv::mask' approach
if (true)
{
double blue, green, red = 0.0;
int counter = 0;
for (int r = 0; r < star.rows; r++)
{
for (int c = 0; c < star.cols; c++)
{
if (mask(r, c) > 0)
{
++counter;
blue += star(r, c)[0];
green += star(r, c)[1];
red += star(r, c)[2];
}
}
}
// Avoid division by 0
if (counter > 0)
{
blue /= counter;
green /= counter;
red /= counter;
}
std::cout << "$$ Red(R), Green(G), Blue(B) $$" << " \n\n";
std::cout << "avg_R: " << red << " \n";
std::cout << "avg_G: " << green << " \n";
std::cout << "avg_B: " << blue << " \n\n";
}
else
{
cv::Scalar mean_value = cv::mean(star, mask);
double blue = mean_value[0];
double green = mean_value[1];
double red = mean_value[2];
std::cout << "$$ Red(R), Green(G), Blue(B) $$" << " \n\n";
std::cout << "avg_R: " << red << " \n"; // red value
std::cout << "avg_G: " << green << " \n"; // green value
std::cout << "avg_B: " << blue << " \n\n"; // blue value
}
cv::waitKey();
}
c++ and opencv get and set pixel color to Mat
You did everything except copying the new pixel value back to the image.
This line takes a copy of the pixel into a local variable:
Vec3b color = image.at<Vec3b>(Point(x,y));
So, after changing color
as you require, just set it back like this:
image.at<Vec3b>(Point(x,y)) = color;
So, in full, something like this:
Mat image = img;
for(int y=0;y<img.rows;y++)
{
for(int x=0;x<img.cols;x++)
{
// get pixel
Vec3b & color = image.at<Vec3b>(y,x);
// ... do something to the color ....
color[0] = 13;
color[1] = 13;
color[2] = 13;
// set pixel
//image.at<Vec3b>(Point(x,y)) = color;
//if you copy value
}
}
Related Topics
How to Get Console Output in C++ With a Windows Program
Why Should I Declare a Virtual Destructor For an Abstract Class in C++
Optional Parameters With C++ Macros
Public Data Members VS Getters, Setters
Alternative Virtual Function Calls Implementations
Does Mingw-W64 Support Std::Thread Out of the Box When Using the Win32 Threading Model
C++11 Features in Visual Studio 2012
C++0X Lambda Capture by Value Always Const
How to Deal With Mutexes in Movable Types in C++
C++11 Aggregate Initialization For Classes With Non-Static Member Initializers
Static Variables in Member Functions
Append an Int to a Std::String
Fast Ceiling of an Integer Division in C/C++
Efficient Way of Storing Huffman Tree
Static_Assert Dependent on Non-Type Template Parameter (Different Behavior on Gcc and Clang)