本文共 2072 字,大约阅读时间需要 6 分钟。
在图像处理中,彩色图转灰度图的应用非常广泛。许多算法仅对灰度图有效,因此将彩色图转换为灰度图是一个关键步骤。
RGB(红绿蓝)是基于人眼识别的颜色定义,能够表示大部分颜色。然而,在科学研究中,RGB并不常用,因为其三个维度(色调、亮度、饱和度)难以分开处理。RGB模型是最通用的面向硬件的彩色模型,广泛应用于彩色监视器和视频摄像机。
RGB颜色空间基于颜色的加法混色原理。从黑色开始,逐渐叠加红色、绿色和蓝色,最终可以得到白色光。这种空间可以用笛卡尔坐标系表示,通过R、G、B三个通道作为X、Y、Z轴。
将彩色图转灰度图的核心公式是:
Gray = R0.299 + G0.587 + B*0.114直接计算会涉及浮点型运算,速度较慢。因此,优化算法将小数转为整数,通过移位运算提高效率。以下是不同精度(2-20位)的优化公式:这些公式通过整数计算减少了计算复杂度,但需要权衡精度损失。
#include#include #include #include using namespace cv;Mat RGB2GRAY(Mat src, bool accelerate) { CV_Assert(src.channels() == 3); Mat dst = Mat::zeros(src.size(), CV_8UC1); Vec3b rgb; int r = src.rows, c = src.cols; for (int i = 0; i < r; ++i) { for (int j = 0; j < c; ++j) { rgb = src.at (i, j); uchar B = rgb[0], G = rgb[1], R = rgb[2]; if (!accelerate) { dst.at (i, j) = R*0.299 + G*0.587 + B*0.114; } else { dst.at (i, j) = (R*4898 + G*9618 + B*1868) >> 14; } } } return dst;}int main() { Mat src = imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\lena.jpg"); if (src.empty()) { return -1; } Mat dst, dst1; double t2 = getTickCount(); cvtColor(src, dst1, CV_RGB2GRAY); t2 = getTickCount() - t2; double time2 = (t2 * 1000.) / getTickFrequency(); cout << "Opencv_rgb2gray=" << time2 << " ms. " << endl << endl; double t1 = getTickCount(); dst = RGB2GRAY(src, true); t1 = getTickCount() - t1; double time1 = (t1 * 1000.) / getTickFrequency(); cout << "My_rgb2gray=" << time1 << " ms. " << endl << endl; namedWindow("src", CV_WINDOW_NORMAL); imshow("src", src); namedWindow("My_rgb2gray", CV_WINDOW_NORMAL); imshow("My_rgb2gray", dst); namedWindow("Opencv_rgb2gray", CV_WINDOW_NORMAL); imshow("Opencv_rgb2gray", dst1); waitKey(0); return 0;}
通过优化算法,实现的RGB转灰度图速度显著提高。与OpenCV的原生函数相比,性能提升了近30%。以下是实际效果:
转载地址:http://awgfk.baihongyu.com/