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

标签 c++ visual-studio opencv exception camera-calibration

我会在解释我的问题后发布我的代码和异常。所以基本上,我正在制作一个程序,其最终目标是能够校准鱼眼相机,然后在相机的 rtsp 流上,该相机将使用 OpenCV 通过 zoneminder 记录,到目前为止我有很多代码从这里得到:

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

但我刚刚开始注意到在我的代码的第 53 行弹出了一个异常

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

我不知道到底是什么导致了它,我对我尝试做的很多事情以及一般的堆栈溢出仍然很陌生,所以请随意留下您认为可能有用的任何输入或提出任何可能需要提出的问题。

如果您自己运行代码,还有一个简短的注意事项是堆栈溢出似乎喜欢拆分某些行,因此请记住这一点以及您需要 OpenCV 的事实。

代码:

// 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;
}

控制台错误:

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.

编辑:所以,奇怪的是,我不再遇到这个问题,但我仍然会留下这个问题,以防万一其他人碰巧遇到这个问题或有一些可能仍然相关的见解,我仍然尽管在使用网络摄像头时没有问题,但相机似乎在第一帧卡住它可以通过 rtsp 捕获的问题,但我将把它留给一个单独的问题,因为这不是这里的问题。

最佳答案

在第一帧校准代码开始卡住之前,您添加的最后一个代码是什么?

# 引用您的 sleep 声明(在第一帧校准代码中)。我假设您引入了减少 CPU 使用率的方法,我将删除它并修改底部主循环中的 waitKey() 方法为 waitKey (100) 以在从流读取之间等待 100 毫秒(或更短)。

  1. 您拥有的 sleep 语句不是您的大部分 CPU 使用率所在的位置。你只是在应用程序的校准部分只执行一次。我会删除它。

  2. 您的计算机真正旋转的地方是底部的主要 while(1) 循环,它不断从流中读取数据。

  3. 也就是说,在调用 waitKey() 函数时,您实际上不需要在底部的主 while 循环中使用 sleep 语句。只需将调用更改为 waitKey(100)。

# 引用您的 scanf_s 语句:要么将它们转换为 #defines 以便我们都知道您的输入是什么,要么向我们展示您输入的命令行来运行它。重要信息。

希望对您有所帮助!

关于c++ - OpenCV(3.4.1) 错误:在 cv::Mat::locateROI 中断言失败(dims <= 2 && step[0] > 0),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50949024/

相关文章:

c++ - 在有人尝试写入文件之前,我如何读取文件?

C++ 移位方式

c++ - 在不可编辑的组合框中显示的默认项目

python - OpenCV videowriter 不写视频

c++ - QDir::rename:冗余参数?

c++ - UAC,需要管理员和文件访问

c# - Visual Studio 类似 Eclipse 的格式设置

visual-studio - CListCtrl 设置字体样式为粗体

python - python图像处理中如何做OR掩码操作?

python-2.7 - 计算边线斜率的有效方法