简体   繁体   English

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

[英]Webcam Image Processing in C++ OpenCV is Slow

I want to simulate protanopia view (one of the partial colorblind) with C++ OpenCV using webcam to simulate it. 我想使用网络摄像头来模拟带有C ++ OpenCV的泛盲视图(部分色盲之一)。 Here the code: 这里的代码:

#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;

} }

This code is run, but the image video output is very slow (lagging). 该代码已运行,但是图像视频输出非常慢(滞后)。 i'm very new using C++. 我是使用C ++的新手。 My Question: 我的问题:

  1. Very slow output because i'm using many iterations? 输出很慢,因为我使用了很多次迭代?
  2. I have tried this process using filter2D (convolution) and the result is different. 我已经尝试使用filter2D(卷积)进行此过程,结果却有所不同。 Is the convolution different with matrix multiplication filter? 卷积与矩阵乘法滤波器不同吗?
  3. How to make the output smoothly? 如何使输出平稳? Should i use pointer in that code? 我应该在该代码中使用指针吗?

Thanks 谢谢

I think your problem is the Mat::at<>() calls, which are quite slow. 我认为您的问题是Mat::at<>()调用,这很慢。 To speed up, you could try using pointer access to the data instead. 为了加快速度,您可以尝试使用对数据的指针访问 This is trickier, but much faster. 这比较棘手,但速度更快。 The OpenCV tutorial shows how to do it. OpenCV教程显示了如何执行此操作。

Filter2D is not the appropriate function for your task. Filter2D不是适合您任务的功能。 It applies a convolution filter on each channel of the image, while what you want is a linear tranformation matrix applied on each rgb pixel. 它在图像的每个通道上应用卷积滤镜 ,而您想要的是在每个rgb像素上应用的线性变换矩阵。

The function you are looking for is transform . 您正在寻找的功能是transform

First, for better performance, merge your three transformations into a single global transformation matrix: 首先,为了获得更好的性能,请将您的三个转换合并为一个全局转换矩阵:

Mat global_kernel = kernel3*lms2lmsp*rgb2lms;

Then, instead of your for loop, use: 然后,使用以下命令代替您的for循环:

transform(im2, Result, global_kernel);

If you still want to save a few milliseconds, you may also remove the cvtColor function calls by applying your transformation directly from bgr color space. 如果您仍然想节省几毫秒,也可以通过直接从bgr颜色空间应用转换来删除cvtColor函数调用。 Simply switch the columns of your rgb2lms matrix: 只需切换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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM