以前实现RGB图像转换成灰度图像都是直接调用OpenCV的库函数RGB2GRAY(IplImage* src);最近老板让我们除了读入输出图像实时用OpenCV的函数,其余的最好都是自己写,所以我自己上网查了一些资料,得到了一些转换算法,并且用c语言实现,具体归纳下来有如下三种:
方法一.对于RGB转灰度,有一个很著名的心理公式:Gray = r*0.299 + g*0.587 + b*0.114;
方法二.Adobephotoshop的公式:Adobe RGB(1998)[gamma = 2.20], gray = (r^2.2 * 0.2973 + g^2.2 * 0.6274 + b^2.2 * 0.0753)^(1/2.2);
方法三.平均值:gray = (r + b + r) / 3;
具体代码如下:
/*****************************************************************************************************
* File name: RGB2Gray.cpp
* Author: source code by RamiYim
* Version: cs-hhu-cn0.0
* Date: 2014.11.13
* Description: read a RGB frame, change it to Gray.
* Others:
* Function List: main functions and its function
* History: <rami>,<20141113>,<new source file, add basic method and variables>,<desc>
******************************************************************************************************/
#include "RGB2Gray.h"
#include "cv.h"
#include "highgui.h"
#include "math.h"
#include <stdio.h>
void RGB2GrayTypical(int sizeOfPixel, char *imageData);
void RGB2GrayInPhotoShop(int sizeOfPixel, char *imageData);
void RGB2GrayAverage(int sizeOfPixel, char *imageData);
char *gray; //用于存放转换后的灰度像素值
void main(){
IplImage *srcImage = cvLoadImage("D:\\testdata\\lena.jpg");
cvShowImage("srcImage", srcImage);
int width = srcImage->width; //图像宽度
int height = srcImage->height; //图像高度
int nChannels = srcImage->nChannels; //通道数
int sizeOfPixel = width * height; //像素数
IplImage *grayImage = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1);//创建灰度图像
gray = (char *) malloc(sizeof(char) * width * height); //灰度图像的"imageData"初始化
RGB2GrayTypical(sizeOfPixel, srcImage->imageData); //转换成gray图像
grayImage->imageData = gray;
cvShowImage("grayImageTypical", grayImage);
RGB2GrayInPhotoShop(sizeOfPixel, srcImage->imageData); //转换成gray图像
grayImage->imageData = gray;
cvShowImage("RGB2GrayInPhotoShop", grayImage);
RGB2GrayAverage(sizeOfPixel, srcImage->imageData);
grayImage->imageData = gray;
cvShowImage("RGB2GrayAverage", grayImage);
cvWaitKey();
}
/******************************************************************************************************
* Function:RGB2GrayTypical()
* Description:输入一帧RGB图像,得到其灰度图像
* Calls://none
* Called by://main
* Input://none
* Output://none
* Return://void
* Others://算法思想:Gray = R*0.299 + G*0.587 + B*0.114
* History: <rami>,<20141113>,<version>,<desc>
******************************************************************************************************/
void RGB2GrayTypical(int sizeOfPixel, char *imageData){
<span style="white-space:pre"> </span>for (int i = 0; i < sizeOfPixel; i++)
{
uchar b = (uchar)imageData[3 * i + 0];
uchar g = (uchar)imageData[3 * i + 1];
uchar r = (uchar)imageData[3 * i + 2];
gray[i] = r * 0.299 + g * 0.587 + b * 0.114;
}
}
/******************************************************************************************************
* Function:RGB2GrayInPhotoShop()
* Description:输入一帧RGB图像,得到其灰度图像
* Calls://none
* Called by://main
* Input://none
* Output://none
* Return://void
* Others://算法思想:Gray = (R^2.2 * 0.2973 + G^2.2 * 0.6274 + B^2.2 * 0.0753)^(1/2.2)
* History: <rami>,<20141114>,<version>,<desc>
******************************************************************************************************/
void RGB2GrayInPhotoShop(int sizeOfPixel, char *imageData){
for (int i = 0; i < sizeOfPixel; i++)
{
uchar b = imageData[3 * i + 0];
uchar g = imageData[3 * i + 1];
uchar r = imageData[3 * i + 2];
gray[i] = pow((pow(r, 2.2) * 0.2973 + pow(g, 2.2) * 0.6274 + pow(b, 2.2) * 0.0753), 1/2.2);
}
}
/******************************************************************************************************
* Function:RGB2GrayAverage()
* Description:输入一帧RGB图像,通过均值法得到其灰度图像
* Calls://none
* Called by://main
* Input://none
* Output://none
* Return://void
* Others://算法思想:gray = (r + g + b) / 3
* History: <rami>,<20141114>,<version>,<desc>
******************************************************************************************************/
void RGB2GrayAverage(int sizeOfPixel, char *imageData){
for (int i = 0; i < sizeOfPixel; i++)
{
uchar b = imageData[3 * i + 0];
uchar g = imageData[3 * i + 1];
uchar r = imageData[3 * i + 2];
gray[i] = (b + g + r) / 3;
}
}
输出结果如下: