OpenCV(3.4.1)错误:cv::Mat::locateROI中的Assert失败(尺寸〈= 2且步骤[0]>0)

sc4hvdpw  于 2022-11-15  发布在  其他
关注(0)|答案(1)|浏览(161)

我会在解释完我的问题后发布我的代码和异常。所以基本上,我正在做一个程序,最终目标是能够校准鱼眼摄像头,然后在摄像头的rtsp流上,通过zoneminder使用OpenCV和我从这里得到的很多代码进行记录:
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 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尽管没有问题时,使用网络摄像头,但我将把它留给另一个问题,因为这不是这里的问题。

3npbholx

3npbholx1#

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

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

1.你的sleep语句并不是你的CPU使用率最高的地方。你只是在应用程序的校准部分,只执行一次。我会删除它。
1.你的计算机真正旋转的地方是底部的while(1)循环,它在那里不断地从流中阅读数据。
1.也就是说,在调用waitKey()函数时,实际上不需要在底部的主while循环中使用sleep语句,只需将调用改为waitKey(100)即可。

引用您的scanf_s语句:要么将它们转换为#defines,这样我们就都知道你的输入是什么,要么给我们看你输入的命令行来运行这个。重要信息。

希望这对你有帮助!

相关问题