S0.2 灰度图

目录

  • 灰度图定义
  • 灰度图优点
  • RGB转灰度算法(OpenCV3)
    • 量化
    • 算法公式
  • OpenCV自带函数实现
  • 综合比较

灰度图定义

对于单色(灰度)图像而言,每个像素的亮度用一个数值来表示,通常数值范围在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)差不多。

原文地址:https://www.cnblogs.com/juicebox/p/9643335.html

时间: 2024-10-09 11:17:32

S0.2 灰度图的相关文章

opencv将图像转化为灰度图,然后边缘检测

1:代码如下: #include "stdafx.h" #include "highgui.h" #include "cv.h" #include "iostream" using namespace std; IplImage* doCanny(IplImage* in,double lowThresh,double highThresh,double aperture) { if(in->nChannels !=1)

【python】RGB图片到灰度图的转换

在做立体匹配求深度图的时候遇到这个问题,用惯了matlab的rgb2gray,倒是不熟悉python的实现,在网上找到了相关方案,记下来已作备用 RGB到灰度图转换公式: Y' = 0.299 R + 0.587 G + 0.114 B 自定义转换函数: 1 import numpy as np 2 3 def rgb2gray(rgb): 4 return np.dot(rgb[...,:3], [0.299, 0.587, 0.144]) 调用: 1 grayPic = rgb2gray(r

从视频文件中读入数据--&gt;将数据转换为灰度图--&gt;对图像做candy边缘检测

//从视频文件中读入数据-->将数据转换为灰度图-->对图像做candy边缘检测 //作者:sandy //时间:2015-10-10 #include <cv.h> #include <highgui.h> int main(int argc, char *argv[]){ //预备工作 CvCapture* capture=cvCreateFileCapture("E:\\Videos\\xx.avi");//让capture变量指向视频文件 i

mupdf实现常用图片转换为灰度图pnm

我要实现的工作是使用mupdf库转换pdf.jpeg.tif等文件为灰度图,转换完成的灰度图存放到内存中,而不是存为文件,在读取到内存中,主要是嵌入式系统中使用.下面是example.c,我加了我理解的注释,以及自己修改的地方.example.c全文 #include <mupdf/fitz.h> void render(char *filename, int pagenumber, int zoom, int rotation) { // Create a context to hold t

Java 彩色图转灰度图

1. 方法1 BufferedImage grayImage = new BufferedImage(width, height, colorImage.TYPE_BYTE_GRAY); Graphics g = grayImage.getGraphics(); g.drawImage(colorImage, 0, 0, null); g.dispose(); 2. 方法2(不推荐) ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRA

OprenCV学习之路一:将彩色图片转换成灰度图

//将一张彩色图片转成灰度图: //////////////////////////// #include<cv.h> #include<cvaux.h> #include<highgui.h> #include<ml.h> #include<iostream> using namespace std; using namespace cv; int main() { IplImage *src=0; src=cvLoadImage("

Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息

这一节看了几次才慢慢的读懂. 首先是这个灰度图,为什么叫灰度图,是因为 这个图片中的 R.G.B 存放的都是同一份数据,打开Unity 来调一下颜色看看 更直观. 可以看到,当 R.G.B 三个值相同的时候,图片是只有黑白,而丢失了其它的颜色的,所以我们叫灰度图. 什么时候用到灰度图? 本文转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 比如说高度图,在这个坐标的点,海拔高,就记作 1,海拔低就记作0 .把这一份数据 同时存储到

灰度图转彩色图(伪彩色处理)

将8Bit灰度数据转化为Bgr24的彩色图像 8bit灰度数据:byte[] GrayValue    长度:width * height PixelFormat pixelFormat = PixelFormats.Bgr24; byte[] colorvalues = GrayToColor(GrayValue); ByteSize = Width * Height; IntPtr dataPtr = IntPtr.Zero; GCHandle _hObject = GCHandle.All

QImage Color Convert to Gray 转为灰度图

在Qt中,我们有时需要把QImage类的彩色图片转为灰度图,一开始我想的是用QImage的成员函数convertToFormat(),但是试了好多参数,返现转化的图片都有问题,不是我们想要的灰度图,如果谁用成员函数成功转化成了灰度图,请在评论区将您的方法写下,让博主学习一下.那么还有一种笨办法,就是手动将R,G,B的值平均一下,然后用平均值更新每一个像素值,也能得到灰度图.参见代码如下: // image is the input color image, img is output grey