码迷,mamicode.com
首页 > 其他好文 > 详细

S0.2 灰度图

时间:2018-09-13 22:44:01      阅读:233      评论:0      收藏:0      [点我收藏+]

标签:技术   效果图   信息   gray   imshow   照片   电视信号   std   细节   

目录

灰度图定义

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

标签:技术   效果图   信息   gray   imshow   照片   电视信号   std   细节   

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!