OpenCv RGB彩色视频转为灰度视频

int videoColorToGray(const string& videoPathColor, const string& videoPathGray)
{
    VideoCapture cap(videoPathColor, CAP_ANY);

    int fps = cap.get(CAP_PROP_FPS);
    Size videoSize = Size((int)cap.get(CAP_PROP_FRAME_WIDTH), (int)cap.get(CAP_PROP_FRAME_HEIGHT));
    VideoWriter writer(videoPathGray, VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, videoSize, false);

    if (!writer.isOpened())
        std::cout << "writer.isOpened() failed" << std::endl;

    bool bContinue = true;
    Mat img, imgGray;
    int index = 0;
    while (bContinue)
    {
        bContinue = cap.read(img);
        if (bContinue)
        {
            cvtColor(img, imgGray, COLOR_RGB2GRAY);
            writer.write(imgGray);
            index++;
        }
    }

    return 0;
}

(一)问题的提出 接到一个问题问我,用OpenCV彩色视频转换为灰度视频并存储到本地磁盘的实践失败,之所以无法存储提问人怀疑是视频编码的问题。 (二)问题的分析 1.OpenCV作为一个非常好的辅助编程的东西,应该是经受得住考验的,怀疑是视频编码出问题不靠谱 2.直觉反应是在写入视频的时候,写入的帧图像存储格式和写入器定义的帧图像格式不符,导致内存报错 3.接收源代码发现有一段代码是这么写的: CvVideoWriter *writer = cvCreateVideoWriter( "myvideo.avi", CV_FOURCC('X', 'V', 'I', 'D'), fps, size); 一下子问题症结就找到了。 要转化为灰度,那这段代码里对函数cvCreateVideoWriter()的掌握程度就要体现了,函数cvCreateVideoWriter()有5个输入参数,第5个输入参数is_color=1是在类cvCreateVideoWriter的构造函数中默认好的,这段代码没有定义is_color,说明同意is_color=1,那么writer写入器写到磁盘上的视频即为彩色视频,写入的帧图像是三通道的彩色图像,而后面的代码cvWriteFrame( writer, gray_frame );中,cvCvtColor( bgr_frame,gray_frame, CV_BGR2GRAY )把彩色的bgr_frame帧图像转化为灰度的图像并存储到gray_frame图像实例中,于是这个gray_frame就与写入器要求的彩色三通道帧图像不一致,即分析2中的直觉:写入的帧图像存储格式和写入器定义的帧图像格式不符,导致内存报错 (三)问题的解决: 1.把代码进行更改,改成: //创建新的视频文件,需要输入视频文件完整路径名,格式,帧率,长宽值,默认是否为彩色值 CvVideoWriter* writer = cvCreateVideoWriter( "6.avi", //存储完整路径 CV_FOURCC('M','J','P','G'), //编码格式 fps,//帧率 size,//长宽值 0//是否为彩色,0为否,默认1为彩色 ); 2.注意到为什么把编码格式写成'M','J','P','G'?因为这个是无压缩的,直接windows操作系统的media player就可以播放了,如果是'X', 'V', 'I', 'D'格式,那多啰嗦,还要下载有编码解码的播放器才能播放,很累。
`OpenCV`是一个开源计算机视觉库,用于处理各种与图像和视频分析相关的任务。当涉及到灰度图像转换成RGB图像时,你可以通过简单的操作完成这一过程。 ### 简单介绍如何将灰度图像转为RGB图像: 在 `OpenCV` 中,彩色图像通常存储为 `cv::Mat` 类型的对象,并且它会包含三个通道,每个通道代表红、绿、蓝三种颜色分量。而灰度图像则只包含一个通道。 #### 步骤一:加载灰度图像 首先,你需要加载一张灰度图像到内存中。这可以通过 `imread` 函数结合适当的参数来完成,其中第三个参数设置为0表示读取灰度图。 ```cpp cv::Mat gray_image = cv::imread("path_to_your_gray_image.jpg", CV_LOAD_IMAGE_GRAYSCALE); ``` #### 步骤二:创建RGB图像 创建一个新的空的RGB图像,其宽度和高度与灰度图像相匹配。每个像素需要存储三个通道的值。 ```cpp cv::Mat rgb_image(gray_image.cols, gray_image.rows, CV_8UC3, cv::Scalar(0)); ``` 这里,`CV_8UC3` 表示这是一个8位无符号字符类型的3通道图像。 #### 步骤三:将灰度值复制到RGB图像的不同通道 由于我们想要的是每一点都分别对应红、绿、蓝的颜色,我们将灰度值复制到RGB图像的三个通道上。这是因为灰度图像的值范围通常是0到255之间,这正好可以映射到RGB的三个分量。 ```cpp for (int i = 0; i < gray_image.rows; ++i) { for (int j = 0; j < gray_image.cols; ++j) { int gray_val = static_cast<int>(gray_image.at<unsigned char>(i, j)); // 将灰度值分配给RGB的三个通道 rgb_image.at<cv::Vec3b>(i, j) = gray_val; rgb_image.at<cv::Vec3b>(i, j) = gray_val; rgb_image.at<cv::Vec3b>(i, j) = gray_val; } } ``` ### 相关问题: 1. **为什么需要将灰度图像转换为RGB**?这种转换在计算机视觉和机器学习项目中有何应用价值? 2. **如何在Python中实现相同的灰度RGB功能**?请简述步骤并提供代码片段。 3. **在处理特定任务时,直接使用灰度图像而非将其转换为RGB图像是否更为有效?**举例说明在何种场景下这样做更合适。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值