我对OpenCV如何进行Color to Greyscale转换感到困惑。如果我发送的图像只包含纯红色,纯绿色和纯蓝色的片段(例如{255,0,0}),我希望它将其转换为值为255/3 = 85的一致灰色,但是这个不是这样。
我试过了:
IplImage* src;
src=cvLoadImage("image.bmp", 0)
val = cvGetReal2D( src, y, x );
这会产生令人困惑的输出,将纯红色转换为147,将纯绿色转换为200,将纯蓝色转换为95(我认为我在那里得到了订单)。灰色按照您的预期进行转换(例如{127,127,127} - > 127)。
然后我遇到了cvCVTColor函数,这似乎使用人眼响应来加权转换(灰色= 0.299 *红色+ 0.587 *绿色+ 0.114 *蓝色):
IplImage *im_rgb = cvLoadImage("image.bmp");
IplImage *im_gray = cvCreateImage(cvGetSize(im_rgb),IPL_DEPTH_8U,1);
cvCvtColor(im_rgb,im_gray,CV_RGB2GRAY);
val = cvGetReal2D( im_gray, y, x );
我已经通过分割频道成功转换了:
IplImage* red_channel = cvCreateImage(cvSize(src->width, src->height), 8, 1);
IplImage* green_channel = cvCreateImage(cvSize(src->width, src->height), 8, 1);
IplImage* blue_channel = cvCreateImage(cvSize(src->width, src->height), 8, 1);
cvSplit( src, blue_channel , green_channel, red_channel , NULL);
val = ( cvGetReal2D( red_channel, y, x ) + cvGetReal2D( green_channel, y, x ) + cvGetReal2D( blue_channel, y, x ) ) / 3;
但是我想从中学习OpenCV在使用cvLoadImage时转换为灰度的功能和/或是否有一个我可以用来转换而没有人眼响应的功能(即Gray =(Red + Green + Blue) / 3)?
答案 0 :(得分:2)
我认为没有单一的功能,但你可以分割通道,将每个通道乘以其系数,并将单个图像中的所有通道相加。
c ++语法将是:
int main()
{
cv::Mat color = cv::imread("lena.jpg");
cv::Mat red(color.rows, color.cols, CV_8UC1);
cv::Mat green(color.rows, color.cols, CV_8UC1);
cv::Mat blue(color.rows, color.cols, CV_8UC1);
std::vector<cv::Mat> output;
output.push_back(blue);
output.push_back(green);
output.push_back(red);
cv::split(color,output);
float r = 0.0f;
float g = 0.2f;
float b = 1.0f - (r + g);
cv::Mat graySelf = r*red + g*green + b*blue;
// could be computed with two calls of cv function addWeighted() in the same way!
cv::Mat grayCV;
cv::cvtColor(color,grayCV, CV_RGB2GRAY);
cv::namedWindow("cv"); cv::imshow("cv", grayCV);
cv::namedWindow("self"); cv::imshow("self", graySelf);
cv::namedWindow("color"); cv::imshow("color", color);
cv::imwrite("cv.png", grayCV);
cv::imwrite("self.png", graySelf);
cv::waitKey(-1);
return 0;
}
提供图片:
颜色
的OpenCV:
自:
在cvtColor中,opencv 2.4.4 c ++内部在imgproc / src / color.cpp中使用了这个函数片段我猜:
int scn = srccn;
float cb = coeffs[0], cg = coeffs[1], cr = coeffs[2];
for(int i = 0; i < n; i++, src += scn)
dst[i] = saturate_cast<_Tp>(src[0]*cb + src[1]*cg + src[2]*cr);
答案 1 :(得分:0)
从颜色到灰度的转换公式不是(R + G + B)/ 3
找出正确的一个,为什么会这样Wikipedia