【问题标题】:manual grayscale in opencv is too slowopencv中的手动灰度太慢
【发布时间】:2014-07-19 19:33:13
【问题描述】:

注意:我必须手动执行此操作,所以不建议我使用库函数 cvtColor()。

我是 opencv 新手,我正在尝试使用公式对彩色图像进行灰度化

(r,g,b) = (r,g,b)/((r+g+b)/3)

这是我转换为灰度的方法(C++):

    Mat dst = src.clone();
for (int i= 0; i<src.rows; ++i)
{
    for (int j = 0 ; j < src.cols; ++j)
    {
        Vec3b myVec = dst.at<Vec3b>(i,j);

        uchar temp = (myVec[0]+myVec[1]+myVec[2])/3;
        Vec3b newPoint(temp,temp,temp);
        dst.at<Vec3b>(i,j) = newPoint ;
    }
}

因为我想对视频进行灰度化,所以我使用这种方法对其每一帧进行灰度化。 与使用 cvtColor(src,dst,CV_RGB2GRAY) 相比,它真的很慢。 (我只有waitkey(1) 所以不是waitkey的问题)

我有 2 个问题

  1. 我只是想知道是否有任何方法可以手动对图像进行灰度化,其速度与 cvtColor 一样快。如果不是,你知道如何优化上面的代码,使灰度视频看起来更流畅。
  2. 以上只是灰度的一种方法。 (r,g,b) = (r,g,b)/((r+g+b)/3) 你能告诉我所有其他灰度彩色图像的方法吗?

任何答案将不胜感激。 提前致谢。

【问题讨论】:

  • 我不知道OpenCV,买你不需要每次都打电话给::at。为什么不调用一次,保存数据,分配一次?
  • 你是的,当我用这个 Vec3b myVec = dst.at(i,j); 替换 for 循环内的代码块时,显然更好一点。 uchar temp = (myVec[0]+myVec[1]+myVec[2])/3; Vec3b 新点(温度,温度,温度); dst.at(i,j) = newPoint ;
  • 但还是不如视频流流畅。有什么想法吗?
  • 我的问题是为什么不使用内置的opencv灰度转换?他们可能会做一些时髦的对齐内存的东西来让它更快。
  • dst是不是必须要有3个频道?如果您只输出单通道图像,您的计算会更快。这种计算可能是受内存限制的,所以你做的内存访问越少,它就会越快。

标签: c++ opencv optimization grayscale


【解决方案1】:

我可以告诉你 ::at 函数很慢。

我总是使用结构体,这里的指针是一个 rgb 示例:

#pragma pack(push, 2)
 struct RGB {        //members are in "bgr" order!
   uchar blue;
   uchar green;
   uchar red;  
 };

然后像这样访问图像的像素:

RGB& rgb = image.ptr<RGB>(y)[x]; //y = row, x = col

像这样更改像素值(对于 RGB 图像):

image.ptr<RGB>(y)[x].value[0] = 142;
image.ptr<RGB>(y)[x].value[1] = 255;
image.ptr<RGB>(y)[x].value[2] = 90;

您可以很容易地将其转化为灰度问题。这样做的好处是,它非常快,因为 cv::Mat 图像的扫描线不会在内存中分割,一条扫描线的像素在内存中彼此相邻。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-11
    • 2016-09-09
    • 2023-03-10
    相关资源
    最近更新 更多