1

I am starting with the basics of image processing and I am trying to convert a RGB image into grey scale using averaging.

My code is

#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<iostream> using namespace cv; int main() { Mat image = imread("a.jpg"); namedWindow("Original "); namedWindow("Grey"); imshow("Original", image); Mat grey; std::cout << "hello\n"; for (int i = 0; i < image.rows; i++) { for (int j = 0; j < image.cols; j++) { grey.at<Vec3b>(i, j) = (image.at<Vec3b>(i, j)[0] + image.at<Vec3b>(i, j)[1] + image.at<Vec3b>(i, j)[2]); } } imshow("Grey", grey); return 0; }` 

I think there is some problem with the Mat Grey , while accessing the element inside the for loop.

2 Answers 2

2

You need to initialize your grey,

Mat grey(image.rows, image.cols, CV_8UC1); 

And then, during processing,

 for (int j = 0; j < image.cols; j++) { grey.at<Vec3b>(i, j) = ((image.at<Vec3b>(i, j)[0] + image.at<Vec3b>(i, j)[1] + image.at<Vec3b>(i, j)[2]))/3; } 

The /3 will give you the true grayscale value.

HTH

Sign up to request clarification or add additional context in comments.

6 Comments

If you are talking about weighted division, then that isn't true grayscale; that is just considering the colors which have the highest response in the human vision system.
Can you please tell me where is the definition of your "true grayscale"?
Every grayscale transformation is done by Y = 0.2126*R + 0.7152*G + 0.0722*B. And by the way, OpenCV loads the images in BRG mode.
This definition is indeed correct for Grayscale conversion based on human perception since cones are most sensitive to Green. If, however, a true conversion it to be applied, the weights should be distributed equally. This would ensure that a perception system has the best response to all the colors and not just one.
so you are saying that your grayscale is true because is not human? Strange... Anyway, Can you give a link that sustains your idea?
|
1

Of course, You have not initialized it, so it is empty, you cannot access the elements.

Mat grey = Mat::zeros(image.rows, image.cols, CV_8UC1); Should fix it.

Try using an if statement before accessing the elements of a Mat:

if (grey.empty()) { std::cout << "Empty Mat!\n"; return -1; } 

Another thing is that adding the image channels are not the true grayacale, see this.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.