简体   繁体   English

OpenCV(3.4.1) 错误: cv::Mat::locateROI 中的断言失败 (dims <= 2 && step[0] > 0)

[英]OpenCV(3.4.1) Error: Assertion failed (dims <= 2 && step[0] > 0) in cv::Mat::locateROI

I will post my code and the exception after explaining my issue.在解释我的问题后,我将发布我的代码和异常。 So basically, I'm making a program where the end goal is to be able to calibrate a fisheye camera which is then on a rtsp stream from the camera that will be recorded via zoneminder using OpenCV and a lot of the code so far I have gotten from here:所以基本上,我正在制作一个程序,其最终目标是能够校准鱼眼相机,然后在相机的 rtsp stream 上,将使用 OpenCV 通过 zoneminder 记录,到目前为止我有很多代码从这里得到:

http://aishack.in/tutorials/calibrating-undistorting-opencv-oh-yeah/ http://aishack.in/tutorials/calibrating-undistorting-opencv-oh-yeah/

But I've just started to notice an exception that has been popping up on line 53 of my code但我刚刚开始注意到我的代码第 53 行出现了一个异常

 bool found = findChessboardCorners(image, board_sz,corners, CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS); 

and I have no idea what exactly is causing it, I'm still new to a lot of what I'm trying to do along with stack overflow in general, so feel free to leave any input you feel might be helpful or ask any questions that may need to be asked.而且我不知道究竟是什么原因造成的,我对很多我正在尝试做的事情以及一般的堆栈溢出仍然很陌生,所以请随时留下您认为可能有帮助的任何输入或提出任何问题这可能需要问。

Also a quick note if you run the code yourself is that stack overflow seems to like to split certain lines up, so keep that in mind along with the fact that you'll need OpenCV.如果您自己运行代码,还有一个快速注意事项是堆栈溢出似乎喜欢将某些行拆分,因此请记住这一点以及您需要 OpenCV 的事实。

Code:代码:

// ConsoleApplication2.cpp : Defines the entry point for the console 
application.

#include <opencv2\videoio.hpp>
#include <opencv2\highgui.hpp>
#include <opencv\cv.hpp>
#include <opencv\cv.h>
#include <iostream>
#include <stdio.h>
#include <chrono>
#include <thread>


using namespace cv;
using namespace std;

int main (){
int numBoards = 0;
int numCornersHor;
int numCornersVer;

printf("Enter number of corners along width: ");
scanf_s("%d", &numCornersHor);

printf("Enter number of corners along height: ");
scanf_s("%d", &numCornersVer);

printf("Enter number of boards: ");
scanf_s("%d", &numBoards);

int numSquares = numCornersHor * numCornersVer;
Size board_sz = Size(numCornersHor, numCornersVer);

VideoCapture capture = VideoCapture("rtsp://172.16.127.27:554/mpeg4");

vector<vector<Point3f>> object_points;
vector<vector<Point2f>> image_points;

vector<Point2f> corners;
int successes = 0;

Mat image;
Mat gray_image;
capture >> image;

vector<Point3f> obj;
for (int j = 0; j < numSquares; j++)
    obj.push_back(Point3f(j / numCornersHor, j%numCornersHor, 0.0f));

while (successes < numBoards) {
    this_thread::sleep_for(chrono::milliseconds(100));
    cvtColor(image, gray_image, CV_BGR2GRAY);

    bool found = findChessboardCorners(image, board_sz, corners, 
CV_CALIB_CB_ADAPTIVE_THRESH | CV_CALIB_CB_FILTER_QUADS);

    if (found) {
        cornerSubPix(gray_image, corners, Size(11,11), Size(-1, -1), 
TermCriteria(CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 30, 0.1));
        drawChessboardCorners(gray_image, board_sz, corners, found);
    }

    imshow("win1", image);
    imshow("win2", gray_image);

    capture >> image;
    int key = waitKey(1);

    if (key == 27)

        return 0;

    if (key == ' ' && found != 0){
        image_points.push_back(corners);
        object_points.push_back(obj);

        printf("Snap stored!");

        successes++;

        if (successes >= numBoards)
            break;
    }
}

Mat intrinsic = Mat(3, 3, CV_32FC1);
Mat distCoeffs;
vector<Mat> rvecs;
vector<Mat> tvecs;

intrinsic.ptr<float>(0)[0] = 1;
intrinsic.ptr<float>(1)[1] = 1;

calibrateCamera(object_points, image_points, image.size(), intrinsic, 
distCoeffs, rvecs, tvecs);

Mat imageUndistorted;
while (1) {
    capture >> image;
    undistort(image, imageUndistorted, intrinsic, distCoeffs);

    imshow("win1", image);
    imshow("win2", imageUndistorted);
    waitKey(1);
}

capture.release();

return 0;
}

Error in Console:控制台中的错误:

OpenCV(3.4.1) Error: Assertion failed (dims <= 2 && step[0] > 0) in 
cv::Mat::locateROI, file C:\build\master_winpack-build-win64- 
vc15\opencv\modules\core\src\matrix.cpp, line 760

Exception:例外:

Exception thrown at 0x00007FFEFC21A388 in ConsoleApplication2.exe: Microsoft 
C++ exception: cv::Exception at memory location 0x000000637891D640.
Exception thrown at 0x00007FFEFC21A388 in ConsoleApplication2.exe: Microsoft 
C++ exception: [rethrow] at memory location 0x0000000000000000.
Exception thrown at 0x00007FFEFC21A388 in ConsoleApplication2.exe: Microsoft 
C++ exception: cv::Exception at memory location 0x000000637891D640.
Unhandled exception at 0x00007FFEFC21A388 in ConsoleApplication2.exe: 
Microsoft C++ exception: cv::Exception at memory location 0x000000637891D640.

Edit: So, oddly, I'm no longer having this issue, but I'll still leave this question up in case anyone else happens to have this issue or has some insight that may still be relevant, I'm still having an issue where the camera seems to freeze on the first frame it can capture over rtsp despite not having the issue when using the webcam, but I'll leave that for a separate question since this is not the issue here.编辑:所以,奇怪的是,我不再有这个问题,但我仍然会留下这个问题,以防其他人碰巧有这个问题或有一些可能仍然相关的见解,我仍然有一个问题尽管在使用网络摄像头时没有出现问题,但相机似乎冻结在它可以通过 rtsp 捕获的第一帧,但我将把它留给一个单独的问题,因为这不是这里的问题。

What was the last code you added before it started to freeze in the first frame calibration code?在第一帧校准代码开始冻结之前,您添加的最后一个代码是什么?

# Reference your sleep statement (which is in the first frame calibration code). # 参考你的睡眠语句(在第一帧校准代码中)。 I'm assuming you introduced to reduce CPU usage, I would remove it and modify the waitKey() method in the main loop at the bottom to waitKey (100) to wait 100 milliseconds (or less) in between reads from the stream.我假设您引入以减少 CPU 使用率,我将删除它并将底部主循环中的 waitKey() 方法修改为 waitKey (100) 以在从 stream 读取之间等待 100 毫秒(或更短)。

  1. The sleep statement where you have it is not where most of your CPU usage is.您拥有的 sleep 语句不是您的大部分 CPU 使用率所在的位置。 Your just in the calibration section of the app that is only executed once.你只是在应用程序的校准部分,只执行一次。 I would remove it.我会删除它。

  2. Where your computer really spins is the main while(1) loop at the bottom where it is continually reading from the stream.您的计算机真正旋转的地方是底部的主要 while(1) 循环,它不断地从 stream 读取数据。

  3. That said, you don't actually need to use a sleep statement in the main while loop at the bottom as you call the waitKey() function.也就是说,当您调用 waitKey() function 时,实际上不需要在底部的主 while 循环中使用 sleep 语句。 Simply change the call to waitKey(100).只需将调用更改为 waitKey(100)。

# Reference your scanf_s statements: Either convert those to #defines so we all know what your inputs are or show us the command line you entered to run this. # 引用您的 scanf_s 语句:将它们转换为 #defines 以便我们都知道您的输入是什么,或者向我们展示您输入的命令行来运行它。 Important piece of info.重要信息。

Hope that helps希望有帮助

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

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