C++ OpenCV 中的网络摄像头图像处理速度很慢

Webcam Image Processing in C++ OpenCV is Slow

我想用 C++ OpenCV 模拟红色盲视图(部分色盲之一),使用网络摄像头来模拟它。这里的代码:

#include "opencv2/opencv.hpp"

using namespace cv;

int main(int, char**)
{
    int i = 0;
    Mat im, im2, kernel3;
    Mat rgb2lms = (Mat_<double>(3, 3) << 17.8824, 43.5161, 4.11935, 3.45565, 27.1554,   3.86714, 0.0299566, 0.184309, 1.46709); //filter1
    Mat lms2lmsp = (Mat_<double>(3, 3) << 0, 2.02344, -2.52581, 0, 1, 0, 0, 0, 1); //filter2
    Mat Result, Result2, op1, op2, op3, op4, op5, op6;
    Vec3b zay, zay2;
    kernel3 = rgb2lms.inv(DECOMP_LU);       //filter 3
    cv::Mat mat(3, 1, CV_64FC1);     //create MAT for matrices multiplication 

Mat frame;
VideoCapture cap(0); // open the default camera
if (!cap.isOpened())  // check if we succeeded
    return -1;
namedWindow("edges", 1);
for (;;)
{

    cap.read(frame); // get a new frame from camera
    if (frame.empty()) continue;
    const int nChannels = frame.channels();
    if (i == 0){
        Result.create(frame.size(), frame.type());
    }
  //Result2.create(frame.size(), frame.type());
    cvtColor(frame, im2, CV_BGR2RGB);   //convert to RGB
    for (int i = 0; i < im2.rows; i++)
    {
        for (int j = 0; j < im2.cols; j++)
            {
                for (int k = 0; k < nChannels; k++)
                    {
                        zay(k) = im2.at<Vec3b>(i, j)[k]; //acces pixel value and put into 3x1 vector zay
                    //put the value in to mat so i can multiplied with easy
                    mat.at <double>(0, 0) = zay[0]; 
                    mat.at <double>(1, 0) = zay[1];
                    mat.at <double>(2, 0) = zay[2];
                    op1 = rgb2lms*mat;     //apply filter1
                    op2 = lms2lmsp*op1;    //apply filter2
                    op3 = kernel3*op2;     //apply filter3

                for (int k = 0; k < nChannels; k++)
                    {
                    Result.at<Vec3b>(i, j)[k] = op3.at<double>(k, 0);   //put the result from vector to mat
                    }

            }
    }

    cvtColor(Result, Result2, CV_RGB2BGR);  //convert back to BGR
    imshow("hasil", Result2);
    if (waitKey(30) >= 0) break;
    i++;
}
// the camera will be deinitialized automatically in VideoCapture destructor
return 0;

}

此代码已运行,但图像视频输出非常慢(滞后)。我是使用 C++ 的新手。我的问题:

  1. 输出非常慢,因为我使用了很多迭代?
  2. 我已经使用 filter2D(卷积)尝试了这个过程,但结果不同。卷积与矩阵乘法滤波器不同吗?
  3. 怎样才能顺利输出?我应该在该代码中使用指针吗?

谢谢

我认为您的问题是 Mat::at<>() 调用,速度很慢。 要加快速度,您可以尝试使用 指针访问 来代替数据。这比较棘手,但速度更快。 OpenCV tutorial 展示了如何操作。

Filter2D 函数不适合您的任务。 它在图像的每个通道上应用 convolution filter,而您想要的是应用在每个 rgb 像素上的线性变换矩阵。

您要查找的函数是transform

首先,为了获得更好的性能,将您的三个转换合并为一个全局转换矩阵:

Mat global_kernel = kernel3*lms2lmsp*rgb2lms;

然后,代替你的 for 循环,使用:

transform(im2, Result, global_kernel);

如果您仍想节省几毫秒,也可以通过直接从 bgr 颜色应用转换来删除 cvtColor 函数调用 space。只需切换 rgb2lms 矩阵的列:

Mat bgr2lms = (Mat_<double>(3, 3) << 4.11935, 43.5161, 17.8824,  3.86714, 27.1554, 3.45565,  1.46709, 0.184309, 0.0299566);