加快OpenCV的输入响应

Speeding up OpenCV's input response

本文关键字:响应 输入 OpenCV 加快      更新时间:2023-10-16

我正在编写我的第一个OpenCV程序,只是使用Macbook上的相机进行一些图像处理。下面的代码只显示了相机,并允许我按0进行正常视图,123从GRB更改为黑白,4将其更改为黑白。

不幸的是,我必须按住键才能响应。是什么导致了这种延迟,如何使代码对输入做出更快的响应?

#include "opencv2/core/core.hpp"
#include "opencv2/flann/miniflann.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/photo/photo.hpp"
#include "opencv2/video/video.hpp"
#include "opencv2/features2d/features2d.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/ml/ml.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/highgui/highgui_c.h"
#include "opencv2/imgproc/imgproc_c.h"
using namespace cv;
using namespace std;
Mat channel(Mat A, int ich) {
    Mat Channel[3];
    Mat B = A.clone();
    split(B, Channel);
    for(int i = 0; i < 3; i++) {
        if( ich-1 != i ) Channel[i] = Mat::zeros(B.rows, B.cols, CV_8UC1);
    }
    merge(Channel, 3, B);
    return B;
}
Mat BW(Mat A) {
    Mat B;
    B = A.clone();
    cvtColor( A, B, CV_BGR2GRAY );
    return B;
}
int main() {
    int waitCount = 1; // wait for this many milliseconds to check for input
    VideoCapture stream1(0);
    namedWindow("cam", CV_WINDOW_NORMAL);
    if( !stream1.isOpened() ) { 
        cout << "Cannot open camera!" << endl;
    }   
    int showKind = 0;
    Mat cameraFrame; // showKind = 0
    Mat grey; // showkind = 4
    while( true ) { 
        /// read the cameraFrame
        stream1.read(cameraFrame);
        /// show the cameraFrame
        if( showKind == 0 ) imshow("cam", cameraFrame);
        else if( showKind > 0 && showKind < 4 ) imshow("cam", channel(cameraFrame, showKind));
        else if( showKind == 4 ) imshow("cam", BW(cameraFrame) );
        else {
            cout << "ERROR: Unknown showKind = " << showKind << endl;
        }   
        ////////////////////////////////////////////////////////////
        /// check for input
        ////////////////////////////////////////////////////////////
        // close down
        if( waitKey(waitCount) == 27 ) { 
            cout << "ESC pressed ... exiting" << endl;
            break;
        }   
        // convert showKind
        else if( waitKey(waitCount) == 48 ) { 
            cout << "Showkind changed to 0" << endl;
            showKind = 0;
        }   
        else if( waitKey(waitCount) == 49 ){
            cout << "Showkind changed to 1" << endl;
            showKind = 1;
        }   
        else if( waitKey(waitCount) == 50 ){
            cout << "Showkind changed to 2" << endl;
            showKind = 2;
        }   
        else if( waitKey(waitCount) == 51 ){
            cout << "Showkind changed to 3" << endl;
            showKind = 3;
        }   
        else if( waitKey(waitCount) == 52 ){
            cout << "Showkind changed to 4" << endl;
            showKind = 4;
        }   
    }   
    return 0;
}

该问题是由对waitKey的级联调用引起的。您只能调用waitKey一次,并存储按下key,例如:

int key = waitKey(waitCount);
if (key == 27) {
    cout << "ESC pressed ... exiting" << endl;
    break;
}
// convert showKind
else if (key == 48) {
    cout << "Showkind changed to 0" << endl;
    showKind = 0;
}
else if (key == 49){
    cout << "Showkind changed to 1" << endl;
    showKind = 1;
}
else if (key == 50){
    cout << "Showkind changed to 2" << endl;
    showKind = 2;
}
else if (key == 51){
    cout << "Showkind changed to 3" << endl;
    showKind = 3;
}
else if (key == 52){
    cout << "Showkind changed to 4" << endl;
    showKind = 4;
}

  • 使用switch语句也可以更清楚。
  • 您可以简单地使用#include <opencv2/opencv.hpp>而不是所有#include
  • 要将矩阵设置为给定值,可以使用 setTo ,因此Channel[i].setTo(0);
  • 您不需要初始化OutputArray OpenCV 函数的矩阵。

所以这里的完整代码有一些改进:

#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
Mat channel(const Mat& A, int ich) {
    Mat Channel[3];
    Mat B;
    split(A, Channel);
    for (int i = 0; i < 3; i++) {
        if (ich - 1 != i) Channel[i].setTo(0);
    }
    merge(Channel, 3, B);
    return B;
}
Mat BW(const Mat& A) {
    Mat B;
    cvtColor(A, B, CV_BGR2GRAY);
    return B;
}
int main() {
    int waitCount = 1; // wait for this many milliseconds to check for input
    VideoCapture stream1(0);
    namedWindow("cam", CV_WINDOW_NORMAL);
    if (!stream1.isOpened()) {
        cout << "Cannot open camera!" << endl;
    }
    int showKind = 0;
    Mat cameraFrame; // showKind = 0
    Mat grey; // showkind = 4
    while (true) {
        /// read the cameraFrame
        stream1 >> cameraFrame;

        /// show the cameraFrame
        if (showKind == 0) imshow("cam", cameraFrame);
        else if (showKind > 0 && showKind < 4) imshow("cam", channel(cameraFrame, showKind));
        else if (showKind == 4) imshow("cam", BW(cameraFrame));
        else {
            cout << "ERROR: Unknown showKind = " << showKind << endl;
        }
        ////////////////////////////////////////////////////////////
        /// check for input1
        ////////////////////////////////////////////////////////////
        // close down
        int key = waitKey(waitCount);
        if (key == 27) {
            cout << "ESC pressed ... exiting" << endl;
            break;
        }
        // convert showKind
        else if (key == 48) {
            cout << "Showkind changed to 0" << endl;
            showKind = 0;
        }
        else if (key == 49){
            cout << "Showkind changed to 1" << endl;
            showKind = 1;
        }
        else if (key == 50){
            cout << "Showkind changed to 2" << endl;
            showKind = 2;
        }
        else if (key == 51){
            cout << "Showkind changed to 3" << endl;
            showKind = 3;
        }
        else if (key == 52){
            cout << "Showkind changed to 4" << endl;
            showKind = 4;
        }
    }
    return 0;
}