【问题标题】:OpenCV: Merge separated JPEG bayer channelsOpenCV:合并分离的 JPEG 拜耳通道
【发布时间】:2013-07-09 17:41:47
【问题描述】:

我有一台相机,它为 4 个不同的拜耳通道(B、G1、G2、R)提供 4 个单独的 JPEG 图像。

我想把它转换成彩色图像。

我目前正在做的是解压缩 jpeg,手动恢复“原始”图像并使用 cvtColor 转换为彩色图像。但这太慢了。我怎样才能做得更好?

    cv::Mat imgMat[4]=cv::Mat::zeros(616, 808, CV_8U); //height, width
    for (k=0;k<4;k++) {
        ........
        imgMat[k] = cv::imdecode(buffer, CV_LOAD_IMAGE_GRAYSCALE);
    }
    //Reconstruct the original image from the four channels! RGGB
    cv::Mat Reconstructed=cv::Mat::zeros(1232, 1616, CV_8U);
    int x,y;
    for(x=0;x<1616;x++){
        for(y=0;y<1232;y++){
            if(y%2==0){
                if(x%2==0){
                    //R
                    Reconstructed.at<uint8_t>(y,x)=imgMat[0].at<uint8_t>(y/2,x/2);
                }
                else{
                    //G1
                    Reconstructed.at<uint8_t>(y,x)=imgMat[1].at<uint8_t>(y/2,floor(x/2));
                }
            }
            else{
                if(x%2==0){
                    //G2
                    Reconstructed.at<uint8_t>(y,x)=imgMat[2].at<uint8_t>(floor(y/2),x/2);
                }
                else{
                    //B
                    Reconstructed.at<uint8_t>(y,x)=imgMat[3].at<uint8_t>(floor(y/2),floor(x/2));
                }
            }
        }
    }
    //Debayer
    cv::Mat ReconstructedColor;
    cv::cvtColor(Reconstructed, ReconstructedColor, CV_BayerBG2BGR);

很明显,解码 jpeg 图像需要更多时间。有人可以使用一些建议/技巧来加快此代码的速度吗?

【问题讨论】:

  • 您确定不能将相机设置为输出原始拜耳图像,没有通道分离和 jpg 压缩吗?可能是带宽方面的问题,但肯定会加快后续的细化……
  • 是的。我可以选择不同的模式来做到这一点。但是我得到的帧速率显然要慢得多......我想使用更高的帧速率。
  • 我会检查时间真正花在了哪里。如果是在 BGGR 图像重建步骤,你有一些希望。另一方面,如果时间真的花在了 imdecode() 上,我看不到可以优化它的方法。如果 BGGR 图像重建步骤是您计算中花费大部分时间的部分,我的第一个猜测是您必须查看 cvtColor 的代码并使用不同类型的输入重写您自己的拜耳转换。还要检查你没有花时间重新分配内存(所有这些零都可以用 setTo(0) 更改。)
  • 谢谢安东尼奥。大部分时间都花在重建步骤上,我可以用下面的答案对其进行优化。它还没有我想要的那么快,但我认为我无法改进任何 imdecode 或 dvtColor 函数。干杯!

标签: opencv jpeg channels


【解决方案1】:

首先,您应该做一个配置文件,看看时间主要花在了哪里。也许这一切都在imdecode() 中,就像“看起来很清楚”一样,但你可能错了。

如果不是,.at&lt;&gt;() 有点慢(你调用了将近 400 万次)。您可以通过更有效地扫描图像来获得一些加速。此外,您不需要 floor() - 这将避免将 int 转换为 double 并再次返回(200 万次)。这样的事情会更快:

int x , y;
for(y = 0; y < 1232; y++){
    uint8_t* row = Reconstructed.ptr<uint8_t>(y);
    if(y % 2 == 0){
        uint8_t* i0 = imgMat[0].ptr<uint8_t>(y / 2);
        uint8_t* i1 = imgMat[1].ptr<uint8_t>(y / 2);

        for(x = 0; x < 1616; ){
            //R
            row[x] = i0[x / 2];
            x++;

            //G1
            row[x] = i1[x / 2];
            x++;
        }
    }
    else {
        uint8_t* i2 = imgMat[2].ptr<uint8_t>(y / 2);
        uint8_t* i3 = imgMat[3].ptr<uint8_t>(y / 2);

        for(x = 0; x < 1616; ){
            //G2
            row[x] = i2[x / 2];
            x++;

            //B
            row[x] = i3[x / 2];
            x++;
        }
    }
}

【讨论】:

  • 谢谢!那很棒。经过更准确的时间观察后,我发现样本帧的时间为: 时间读取图像:0.008328 时间重建图像:0.041352 时间去拜耳:0.004263 使用您的代码时间后:时间阅读图像:0.008466 时间重建图像:0.008402 时间去拜耳: 0.004364 重建图像的速度提高了 4 倍,节省了百分之三秒!我不认为我现在能变得更好!
猜你喜欢
  • 2012-08-07
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多