Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCV理解灰度_Opencv_Image Processing_Colors_Computer Vision - Fatal编程技术网

OpenCV理解灰度

OpenCV理解灰度,opencv,image-processing,colors,computer-vision,Opencv,Image Processing,Colors,Computer Vision,我对OpenCV如何进行颜色到灰度的转换感到困惑。如果我给它发送一张仅由纯红色、纯绿色和纯蓝色(例如{255,0,0})组成的图像,我希望它将其转换为值255/3=85的一致灰色,但事实并非如此 我试过: IplImage* src; src=cvLoadImage("image.bmp", 0) val = cvGetReal2D( src, y, x ); 这会产生混乱的输出,将纯红色转换为147,纯绿色转换为200,纯蓝色转换为95(我想我已经得到了订单)。灰色会按照预期进行转换(例如,

我对OpenCV如何进行颜色到灰度的转换感到困惑。如果我给它发送一张仅由纯红色、纯绿色和纯蓝色(例如{255,0,0})组成的图像,我希望它将其转换为值255/3=85的一致灰色,但事实并非如此

我试过:

IplImage* src;
src=cvLoadImage("image.bmp", 0)
val = cvGetReal2D( src, y, x );
这会产生混乱的输出,将纯红色转换为147,纯绿色转换为200,纯蓝色转换为95(我想我已经得到了订单)。灰色会按照预期进行转换(例如,{127127}-->127)

然后我遇到了CVTColor函数,它似乎使用人眼反应来加权转换(灰色=0.299*红色+0.587*绿色+0.114*蓝色):

我已通过拆分频道成功转换为所需:

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时如何转换为灰度,和/或是否有一个函数可以在没有人眼反应的情况下转换(即灰色=(红色+绿色+蓝色)/3)?

从颜色到灰度的转换公式不是(R+G+B)/3


找出正确的一个,为什么是这样的

我不认为有一个单一的函数,但你可以分割通道,将每个通道与其系数相乘,然后将单个图像中的所有通道相加

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;
}
intmain()
{
cv::Mat color=cv::imread(“lena.jpg”);
cv::Mat红色(color.rows、color.cols、cv_8UC1);
cv::Mat绿色(color.rows、color.cols、cv_8UC1);
cv::Mat蓝色(color.rows、color.cols、cv_8UC1);
std::矢量输出;
输出。推回(蓝色);
输出。推回(绿色);
输出。推回(红色);
cv::分割(颜色、输出);
浮球r=0.0f;
浮球g=0.2f;
浮球b=1.0f-(r+g);
cv::Mat graySelf=r*红色+g*绿色+b*蓝色;
//可以通过两次调用cv函数addWeighted()以相同的方式计算!
cv::Mat grayCV;
cv::CVT颜色(颜色、灰色cv、cv_rgb2灰色);
cv::namedWindow(“cv”);cv::imshow(“cv”,grayCV);
cv::namedWindow(“self”);cv::imshow(“self”,graySelf);
cv::namedWindow(“颜色”);cv::imshow(“颜色”,颜色);
cv::imwrite(“cv.png”,grayCV);
cv::imwrite(“self.png”,graySelf);
cv::waitKey(-1);
返回0;
}
提供图像:

颜色:

openCV:

自我:

在CVTHORE中,OpenCV2.4.4C++内部使用这个函数片段在IMGPROC/SRC/COLLY。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);
int-scn=srccn;
浮动cb=系数[0],cg=系数[1],cr=系数[2];
对于(int i=0;i
我知道在许多应用程序中,您希望使用人眼响应来加权转换,但在我的应用程序中,我希望它对蓝色的敏感度与对绿色或红色的敏感度一样。然后编写您自己的转换。OpenCV遵循标准。它不需要实现没有实际意义的转换。但我真的怀疑你在你的项目中是否需要R,G,B平均值。谢谢米卡,这是一个非常全面的答案,附有有用的例子。
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);