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

问题描述 投票:0回答:1

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

http://aishack.in/tutorials/calibrate-un Distorting-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 捕获的第一帧上,但我将把它留给一个单独的问题,因为这不是这里的问题。

c++ visual-studio opencv exception camera-calibration
1个回答
0
投票

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

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

  1. 您所在的 sleep 语句并不是大部分 CPU 使用率所在的地方。您只需进入仅执行一次的应用程序的校准部分。我会把它删除。

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

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

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

希望有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.