S0.2 灰度图
Posted juicebox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了S0.2 灰度图相关的知识,希望对你有一定的参考价值。
目录
灰度图定义
对于单色(灰度)图像而言,每个像素的亮度用一个数值来表示,通常数值范围在0到255之间,0表示黑、255表示白,其它值表示处于黑白之间的灰度。
灰度图优点
我们在进行很多图像的操作时,如果是彩色的 256 色图,由于图象处理后有可能会产生不属于这 256 种颜色的新颜色。
RGB转灰度算法(OpenCV3)
量化
我们知道,自然界中的所有颜色都可以由红、绿、蓝(R,G,B)组合而成。有的颜色有红色成分多一些,如深红;有的有红色成分少一些,如浅红。针对有红色成分的多少,可以分成 0 到 255 共 256 个等级,0 级表示不含红色成分;255 级表示 有 100%的红色成分。 同样,绿色和蓝色也被分成 256 级。这种分级概念称为量化。
算法公式
灰度图是指只含亮度信息,不含色彩信息的图象,就象我们平时看到的黑白照片:亮度由暗到明,变化是连续的。因此,要表示灰度图,就需要把亮度值进行量化。通常划分成0到255共256个级别,其中0最暗(全黑),255最亮(全白)。在表示颜色的方法中,除了RGB外,还有一种叫YUV的表示方法,应用也很多。电视信号中用的就是一种类似于YUV的颜色表示方法。在这种表示方法中,Y分量的物理含义就是亮度,Y分量包含了灰度图的所有信息,只用Y分量就能完全能够表示出一幅灰度图来。
从 RGB 到 YUV 空间的 Y 转换,有一个很著名的心理学公式:
Y = R*0.299 + G*0.587 + B*0.114
我们进行优化变为整数算法:
Y = (R*299 + G*587 + B*114 + 500) / 1000
(当然,聪明的你们一定也想到了另一种方法就是,灰度值为(r+g+b)/3,之后你们可以看看两种方法的效果。)
OpenCV3代码:
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void main()
{
Mat srcImage = imread("Lena.jpg");
Mat dstImage;
dstImage = srcImage.clone();
int rowNumber = srcImage.rows;
int colNumber = srcImage.cols * srcImage.channels();
imshow("old", srcImage);
for (int i = 0; i < rowNumber; i++)
{
uchar* data = dstImage.ptr<uchar>(i);
for (int j = 0; j < colNumber; j+=3)
{
data[j] =(data[j] * 299 + data[j + 1] * 587 + data[j + 2] * 114 + 500) / 1000;
//data[j] =(data[j] + data[j + 1] + data[j + 2]) / 3;
data[j + 1] = data[j+2] = data[j];
}
}
imshow("new", dstImage);
waitKey(0);
}
效果图:
OpenCV自带函数实现
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("images/Lena.jpg");
Mat dstImage1 = imread("images/Lena.jpg", 0);//法一
Mat dstImage2;
cvtColor(srcImage, dstImage2, CV_RGB2GRAY);//把图片转化为灰度图,法二
imshow("old", srcImage);
imshow("new1", dstImage1);
imshow("new2", dstImage2);
waitKey(10000);
return 0;
}
综合比较
我们把几种方法都写在一个程序里,看看效果
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<iostream>
using namespace std;
using namespace cv;
int main()
{
Mat srcImage = imread("images/favorite/Lena.jpg");
Mat srcImage2 = imread("images/favorite/Lena.jpg", 0);
Mat dstImage,dstImage2;
dstImage = srcImage.clone();
dstImage2 = srcImage.clone();
int rowNumber = srcImage.rows;
int colNumber = srcImage.cols * srcImage.channels();
imshow("old", srcImage);
for (int i = 0; i < rowNumber; i++)
{
uchar* data = dstImage.ptr<uchar>(i);
for (int j = 0; j < colNumber; j+=3)
{
data[j] =(data[j] * 299 + data[j + 1] * 587 + data[j + 2] * 114 + 500) / 1000;
data[j + 1] = data[j+2] = data[j];
}
}
imshow("new", dstImage);
for (int i = 0; i < rowNumber; i++)
{
uchar* data = dstImage2.ptr<uchar>(i);
for (int j = 0; j < colNumber; j+=3)
{
data[j] =(data[j] + data[j + 1] + data[j + 2]) / 3;
data[j + 1] = data[j+2] = data[j];
}
}
imshow("new2", dstImage2);
imshow("new3", srcImage2);
waitKey(20000);
return 0;
}
效果如下:
显然,我们的心理学公式灰化的Lena(图new)是最好看的,头发细节比较清楚。而自带函数产生的(new3)和我们取rgb平均值产生的(new2)差不多。
以上是关于S0.2 灰度图的主要内容,如果未能解决你的问题,请参考以下文章