Note: I have to do this manually so don't suggest me to use the library function cvtColor().
I'm new to opencv and I am trying to grayscale an color image with the formula
(r,g,b) = (r,g,b)/((r+g+b)/3)
Here is my method(C++) for converting to grayscale:
Mat dst = src.clone();
for (int i= 0; i<src.rows; ++i)
{
for (int j = 0 ; j < src.cols; ++j)
{
Vec3b myVec = dst.at<Vec3b>(i,j);
uchar temp = (myVec[0]+myVec[1]+myVec[2])/3;
Vec3b newPoint(temp,temp,temp);
dst.at<Vec3b>(i,j) = newPoint ;
}
}
Because I want to grayscale a video so I use this method to grayscale each of its frame. It is really slow in comparison with using the cvtColor(src,dst,CV_RGB2GRAY). (I only waitkey(1) so it is not the problem of waitkey)
I have 2 questions
Any answer would be appreciated. Thanks in advance.
I can tell you that the ::at function is slow.
I always use a struct and a pointer here is an rgb example:
#pragma pack(push, 2)
struct RGB { //members are in "bgr" order!
uchar blue;
uchar green;
uchar red;
};
And then acces the pixels of you image like this:
RGB& rgb = image.ptr<RGB>(y)[x]; //y = row, x = col
Change pixel values (for an RGB image) like this:
image.ptr<RGB>(y)[x].value[0] = 142;
image.ptr<RGB>(y)[x].value[1] = 255;
image.ptr<RGB>(y)[x].value[2] = 90;
You can translate that into your grayscale problem pretty easy. The good thing about this is, that its really fast because a scanline of an cv::Mat image are not split in the memory the pixels of one scanline are next to each other in the memory.
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