首页 > 解决方案 > 在OpenCV中将二维码投影到摄像头时,出现错误

问题描述

我想生成一个代码,以便在 QR 码指向相机时播放视频。但我在 warpPerspective 中遇到错误。错误是:OpenCV(4.5.3) 错误:断言失败 (_src.total() > 0) in cv::warpPerspective, 文件 C:\build\master_winpack-build-win64-vc15\opencv\modules\imgproc \src \imgwarp.cpp, line 3144 我在很多地方搜索过,但我找不到答案,所以我问。

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

void main() 
{
    Mat cameraFrame, videoFrame;
    vector<Point2f> bbox;
    double width, height;
    VideoCapture camera(0), video;
    QRCodeDetector qrDecoder;
    string data;
    
    while (camera.read(cameraFrame))
    {
        data = qrDecoder.detectAndDecode(cameraFrame, bbox);

        if (data.length() > 0)
        {
            if (!video.isOpened()) {
                video.open("../data/"+data+".mp4");
                width = video.get(CAP_PROP_FRAME_WIDTH);
                height = video.get(CAP_PROP_FRAME_HEIGHT);
            }
            
            vector<Point2f> v_bbox{ Point2f(0, 0), Point2f(width,0), Point2f(width,height), Point2f(0, height) };
            Mat H = findHomography(v_bbox, bbox);
            video >> videoFrame;
            Mat warpedFrame, warpedMask;

            warpedFrame.copyTo(cameraFrame, warpedMask);

            warpPerspective(videoFrame, warpedFrame, H, cameraFrame.size());
            Mat mask(videoFrame.size(), CV_8UC1, cv::Scalar(255));
            
            warpPerspective(mask, warpedMask, H, cameraFrame.size());
            imshow("warepedFrame", warpedFrame);
            imshow("WarpedMask", warpedMask);
        }
        imshow("cam", cameraFrame);
        waitKey(1);
    }
}

标签: c++opencvqr-code

解决方案


问题是你在warpedFrame被warpPerspective填充之前调用copyTo方法,它重置cameraFrame垫,然后当你将cameraFrame.size()传递给 warpPerspective并使用cameraFrame.size()构造掩码垫时,你基本上传递了( 0,0)

您所要做的就是在应用透视变换后复制包装的视频叠加层:

#include "opencv2/opencv.hpp"

using namespace cv;
using namespace std;

void main() 
{
    Mat cameraFrame, videoFrame;
    vector<Point2f> bbox;
    double width, height;
    VideoCapture camera(0), video;
    QRCodeDetector qrDecoder;
    string data;
    
    while (camera.read(cameraFrame))
    {
        data = qrDecoder.detectAndDecode(cameraFrame, bbox);

        if (data.length() > 0)
        {
            if (!video.isOpened()) {
                video.open("../data/"+data+".mp4");
                width = video.get(CAP_PROP_FRAME_WIDTH);
                height = video.get(CAP_PROP_FRAME_HEIGHT);
            }
            
            vector<Point2f> v_bbox{ Point2f(0, 0), Point2f(width,0), Point2f(width,height), Point2f(0, height) };
            Mat H = findHomography(v_bbox, bbox);
            video >> videoFrame;
            Mat warpedFrame, warpedMask;
    
            warpPerspective(videoFrame, warpedFrame, H, cameraFrame.size());
            Mat mask(videoFrame.size(), CV_8UC1, cv::Scalar(255));
            
            warpPerspective(mask, warpedMask, H, cameraFrame.size());

            imshow("warepedFrame", warpedFrame);
            imshow("WarpedMask", warpedMask);

            warpedFrame.copyTo(cameraFrame, warpedMask);

        }
        imshow("cam", cameraFrame);
        waitKey(1);
    }
}

推荐阅读