本文共 3296 字,大约阅读时间需要 10 分钟。
YUV是一种广泛应用于视频编码和传输的色彩空间表示方法,与常见的RGB色彩模型相比,具有显著的优势。作为彩色电视系统的核心,YUV通过分离亮度信号和色度信号,实现了视频信号的高效传输。本文将深入探讨YUV与RGB之间的转换方法及其优化技术。
YUV色彩模型由亮度信号Y和两个色度信号U、V组成,其中:
相比于RGB色彩模型,YUV色彩模型的优势在于信号传输占用带宽更少,这使得YUV在视频编码和传输中具有重要意义。
RGB到YUV的转换公式为:
Y = 0.299R + 0.587G + 0.114BU = 0.500R - 0.419G - 0.081B + 128V = -0.169R - 0.331G + 0.500B + 128
为了实现快速计算,常见的做法是将公式中的系数进行优化和整数化处理,以减少计算复杂度。
为了提升转换效率,常规的优化方法包括:
以下是优化后的转换公式:
Y = (77R + 150G + 29B) >> 8U = (-43R - 85G + 128B + 32768) >> 8V = (128R - 107G - 21B + 32768) >> 8
#include#include #include #include using namespace cv;Mat RGB2YUV(Mat src, bool accelerate = false) { CV_Assert(src.channels() == 3); Mat dst(src.size(), CV_32FC3); Vec3b rgb; for (int i = 0; i < src.rows; ++i) { for (int j = 0; j < src.cols; ++j) { rgb = src.at (i, j); int R = rgb[2], G = rgb[1], B = rgb[0]; if (!accelerate) { dst.at (i, j)[0] = 0.299 * R + 0.587 * G + 0.114 * B; dst.at (i, j)[1] = 0.500 * R - 0.419 * G - 0.081 * B + 128; dst.at (i, j)[2] = -0.169 * R - 0.331 * G + 0.500 * B + 128; } else { int Y = (77 * R + 150 * G + 29 * B) >> 8; int U = (-43 * R - 85 * G + 128 * B + 32768) >> 8; int V = (128 * R - 107 * G - 21 * B + 32768) >> 8; dst.at (i, j)[0] = Y; dst.at (i, j)[1] = U; dst.at (i, j)[2] = V; } } } dst.convertTo(dst, CV_8UC3); return dst;}Mat YUV2RGB(Mat src, bool accelerate = false) { CV_Assert(src.channels() == 3); Mat dst(src.size(), CV_32FC3); Vec3b yuv; for (int i = 0; i < src.rows; ++i) { for (int j = 0; j < src.cols; ++j) { yuv = src.at (i, j); int Y = yuv[0], U = yuv[1] - 128, V = yuv[2] - 128; if (!accelerate) { dst.at (i, j)[0] = Y + 1.770 * U; // B dst.at (i, j)[1] = Y - 0.343 * U - 0.714 * V; // G dst.at (i, j)[2] = Y + 1.403 * V; // R } else { int B = Y + (U * 198) >> 8; int G = Y - ((U * 88) >> 8) - ((V * 183) >> 8); int R = Y + (V * 103) >> 8; dst.at (i, j)[0] = B; dst.at (i, j)[1] = G; dst.at (i, j)[2] = R; } } } dst.convertTo(dst, CV_8UC3); return dst;}int main() { Mat src = cv::imread("I:\\Learning-and-Practice\\2019Change\\Image process algorithm\\Img\\4.JPG"); if (src.empty()) { return -1; } Mat dst, dst1, dst2; double t2 = (double)cv::getTickCount(); cvtColor(src, dst1, CV_RGB2YUV); double time2 = (t2 * 1000.) / ((double)cv::getTickFrequency()); std::cout << "Opencv_RGB2YUV=" << time2 << " ms. " << std::endl << std::endl; Mat my_rgb2yuv = RGB2YUV(src, true); Mat my_yuv2rgb = YUV2RGB(my_rgb2yuv, true); t2 = (double)cv::getTickCount(); time2 = (t2 * 1000.) / ((double)cv::getTickFrequency()); std::cout << "My_RGB2YUV=" << time1 << " ms. " << std::endl << std::endl; namedWindow("src", CV_WINDOW_NORMAL); imshow("src", src); namedWindow("My_RGB2YUV", CV_WINDOW_NORMAL); imshow("My_RGB2YUV", my_rgb2yuv); namedWindow("My_YUV2RGB", CV_WINDOW_NORMAL); imshow("My_YUV2RGB", my_yuv2rgb); namedWindow("Opencv_RGB2YUV", CV_WINDOW_NORMAL); imshow("Opencv_RGB2YUV", dst1); waitKey(0); return 0;}
通过上述优化后的转换方法,我们可以显著提升转换效率,同时保持较高的颜色准确性。对于实际应用,建议根据具体需求选择合适的加速模式,以在速度和质量之间找到最佳平衡。
转载地址:http://bgrfk.baihongyu.com/