问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

RGB图像转灰度图像的原理与实现

创作时间:
作者:
@小白创作中心

RGB图像转灰度图像的原理与实现

引用
CSDN
1.
https://blog.csdn.net/u012294613/article/details/141095933

彩色图转灰度图在图像处理中应用非常广泛,而且很多算法只对灰度图有效,因此彩色图转灰度是一个十分重要和关键的步骤。

RGB(红绿蓝)是依据人眼识别的颜色定义出的空间,可表示大部分颜色。但在科学研究一般不采用RGB颜色空间,因为它的细节难以进行数字化的调整。它将色调,亮度,饱和度三个量放在一起表示,很难分开。它是最通用的面向硬件的彩色模型。该模型用于彩色监视器和一大类彩色视频摄像。

RGB颜色空间 基于颜色的加法混色原理,从黑色不断叠加Red,Green,Blue的颜色,最终可以得到白色光,如图:

将R、G、B三个通道作为笛卡尔坐标系中的X、Y、Z轴,就得到了一种对于颜色的空间描述,如图:

RGB转灰度图

对于彩色转灰度,有一个很著名的心理学公式:

Gray = R0.299 + G0.587 + B*0.114

直接计算因为是浮点型计算,所以复杂度较高,速度较低。所以我们考虑优化,可以将小数转为整数,除法变为移位,乘法也变为移位(整数计算比浮点型快,移位运算和加减法比乘除法快),但是这种方法也会带来一定的精度损失,我们可以根据实际情况选择需要保留的精度位数。下面给出不同精度(2-20位)的计算公式:

Grey = (R1 + G2 + B1) >> 2
Grey= (R
2 + G5 + B1) >> 3
Grey= (R4 + G10 + B2) >> 4
Grey = (R
9 + G19 + B4) >> 5
Grey = (R19 + G37 + B8) >> 6
Grey= (R
38 + G75 + B15) >> 7
Grey= (R76 + G150 + B30) >> 8
Grey = (R
153 + G300 + B59) >> 9
Grey = (R306 + G601 + B117) >> 10
Grey = (R
612 + G1202 + B234) >> 11
Grey = (R1224 + G2405 + B467) >> 12
Grey= (R
2449 + G4809 + B934) >> 13
Grey= (R4898 + G9618 + B1868) >> 14
Grey = (R
9797 + G19235 + B3736) >> 15
Grey = (R19595 + G38469 + B7472) >> 16
Grey = (R
39190 + G76939 + B14943) >> 17
Grey = (R78381 + G153878 + B29885) >> 18
Grey =(R
156762 + G307757 + B59769) >> 19
Grey= (R313524 + G615514 + B*119538) >> 20

实现

#include <iostream>  
#include <opencv2/core.hpp>  
#include <opencv2/highgui.hpp>  
#include <opencv2/imgproc.hpp>  

cv::Mat RGB2GRAY(cv::Mat src, bool accelerate=false){  
    CV_Assert(src.channels()==3);  
    cv::Mat dst = cv::Mat::zeros(src.size(), CV_8UC1);  
    cv::Vec3b rgb;  
    int r = src.rows;  
    int c = src.cols;  
    for (int i = 0; i < r; ++i){  
        for (int j = 0; j < c; ++j){  
            rgb = src.at<cv::Vec3b>(i, j);  
            uchar B = rgb[0]; uchar G = rgb[1]; uchar R = rgb[2];  
            if (accelerate == false){  
                dst.at<uchar>(i, j) = R*0.299 + G*0.587 + B*0.114; //原式  
            }  
            else{  
                dst.at<uchar>(i, j) = (R * 4898 + G * 9618 + B * 1868) >> 14; //优化  
            }  
        }  
    }  
    return dst;  
}  

int main(){  
    cv::Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\lena.jpg");  
    if (src.empty()){  
        return -1;  
    }  
    cv::Mat dst,dst1;  
    //opencv自带  
    double t2 = (double)cv::getTickCount(); //测时间  
    cv::cvtColor(src, dst1, CV_RGB2GRAY);  
    t2 = (double)cv::getTickCount() - t2;  
    double time2 = (t2 *1000.) / ((double)cv::getTickFrequency());  
    std::cout << "Opencv_rgb2gray=" << time2 << " ms. " << std::endl << std::endl;  
    //RGB2GRAY  
    double t1 = (double)cv::getTickCount(); //测时间  
    dst = RGB2GRAY(src, true);  
    t1 = (double)cv::getTickCount() - t1;  
    double time1 = (t1 *1000.) / ((double)cv::getTickFrequency());  
    std::cout << "My_rgb2gray=" << time1 << " ms. " << std::endl << std::endl;  
    cv::namedWindow("src", CV_WINDOW_NORMAL);  
    imshow("src", src);  
    cv::namedWindow("My_rgb2gray", CV_WINDOW_NORMAL);  
    imshow("My_rgb2gray", dst);  
    cv::namedWindow("Opencv_rgb2gray", CV_WINDOW_NORMAL);  
    imshow("Opencv_rgb2gray", dst1);  
    cv::waitKey(0);  
    return 0;  
}  

效果

参考:

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号