首页 > 解决方案 > 将网络摄像头程序转换为处理一张图像

问题描述

我目前正在尝试修改一个将网络摄像头流作为输入的程序。问题是,当我尝试更改程序以使用单个图像时,它不会显示我期望的输出,例如视频流(下面的代码)

#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>

#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FaceDetector.h"
#include "FingerCount.h"

using namespace cv;
using namespace std;

int main(int, char**) {
    VideoCapture videoCapture(0);
    videoCapture.set(CV_CAP_PROP_SETTINGS, 1);

    if (!videoCapture.isOpened()) {
        cout << "Can't find camera!" << endl;
        return -1;
    }

    Mat frame, frameOut, handMask, foreground, fingerCountDebug;

    BackgroundRemover backgroundRemover;
    SkinDetector skinDetector;
    FaceDetector faceDetector;
    FingerCount fingerCount;

    for (int i = 0; i < 2; i++)
    {
        videoCapture >> frame;
        frameOut = frame.clone();

        skinDetector.drawSkinColorSampler(frameOut);

        foreground = backgroundRemover.getForeground(frame);

        faceDetector.removeFaces(frame, foreground);
        handMask = skinDetector.getSkinMask(foreground);
        fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);

        imshow("output", frameOut);
        imshow("foreground", foreground);
        imshow("handMask", handMask);
        imshow("handDetection", fingerCountDebug);

        if (i == 0)
        {
            backgroundRemover.calibrate(frame);
            skinDetector.calibrate(frame);
        }
    }
    waitKey(0);
}

输出显示检测。然而,如果我修改代码以使帧不从视频流中读取,则输出根本不会显示任何内容。有人可以帮忙解决这个问题吗?编辑:由于一些社区成员的混淆,修改后的代码如下,读取单个图像:

#include "opencv2/opencv.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>

#include "BackgroundRemover.h"
#include "SkinDetector.h"
#include "FaceDetector.h"
#include "FingerCount.h"

using namespace cv;
using namespace std;

int main(int, char**) {

    string imageName("C:/Users/whoever/Desktop/hand_test.jpg"); // by default
    Mat image;
    image = imread(imageName.c_str(), IMREAD_COLOR); // Read the file


    Mat frame, frameOut, handMask, foreground, fingerCountDebug;

    BackgroundRemover backgroundRemover;
    SkinDetector skinDetector;
    FaceDetector faceDetector;
    FingerCount fingerCount;

    for (int i = 0; i < 2; i++)
    {
        frame = image;
        frameOut = frame.clone();

        skinDetector.drawSkinColorSampler(frameOut);

        foreground = backgroundRemover.getForeground(frame);

        faceDetector.removeFaces(frame, foreground);
        handMask = skinDetector.getSkinMask(foreground);
        fingerCountDebug = fingerCount.findFingersCount(handMask, frameOut);

        imshow("output", frameOut);
        imshow("foreground", foreground);
        imshow("handMask", handMask);
        imshow("handDetection", fingerCountDebug);

        if (i == 0)
        {
            cout << "Calibrating...";
            backgroundRemover.calibrate(frame);
            skinDetector.calibrate(frame);
        }
    }
    waitKey(0);
}

标签: c++opencv

解决方案


原始代码每次循环处理从相机捕获的不同图像并输出差异。由于您现在每次都使用相同的图像,因此没有任何差异,因此输出完全空白。(请注意,它仍会将输出作为视频播放,只是一个持续空白的视频)

for 循环中的第一行是它从相机中获取新图像的位置:

   videoCapture >> frame;

正如您在更新的代码中看到的那样,您正在删除它并再次使用相同的图像:

    frame = image;

尝试保存 2 个不同的图像,并在每次循环时将程序加载到不同的图像中。

这是一种相当蛮力的方法,您可以改进以在每次循环时加载不同的文件,使用数组等:

string imageName1("C:/Users/whoever/Desktop/hand_test_1.jpg"); // by default
string imageName2("C:/Users/whoever/Desktop/hand_test_2.jpg"); // by default
Mat image1;
Mat image2;
image1 = imread(imageName1.c_str(), IMREAD_COLOR); // Read the file
image2 = imread(imageName2.c_str(), IMREAD_COLOR); // Read the file

Mat frame, frameOut, handMask, foreground, fingerCountDebug;

BackgroundRemover backgroundRemover;
SkinDetector skinDetector;
FaceDetector faceDetector;
FingerCount fingerCount;

for (int i = 0; i < 2; i++)
{
    if (i = 0) { frame = image1 } else { frame = image2 };
...

推荐阅读