OpenCV错误:断言失败(a_size.width == len) [英] OpenCV Error: Assertion failed (a_size.width == len)

查看:812
本文介绍了OpenCV错误:断言失败(a_size.width == len)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试在运行 Ubuntu MATE 16.04 LTS Raspberry Pi 上使用 ROS 构建自动无人机.到目前为止,解决了识别红色圆圈的计算机视觉问题.由于无人机的本质是不稳定的(因为有内置的PID控制器可以使无人机稳定),并且由于光照条件的原因,无人机通常会以非常不稳定的方式检测到相同的圆圈.为了解决此问题,对[this] [1]问题的评论建议我尝试视频稳定.

I am currently trying to build an autonomous drone using ROS on my Rapsberry Pi which is running an Ubuntu MATE 16.04 LTS. Solving the Computer Vision problem of recognising red circles as of now. Since by nature, the drone is not stable (as there is an internal PID controller stabilising the drone) and due to lighting conditions, the drone often detects the same circle but in a very unstable way. To tackle this problem, comments on [this][1] question suggested that I try video stabilization.

这是我当前正在查看的错误:

This is the error I am currently looking at:

OpenCV Error: Assertion failed (a_size.width == len) in gemm, file
/tmp/binarydeb/ros-kinetic-opencv3-3.1.0/modules/core/src/matmul.cpp,
line 900 terminate called after throwing an instance of
'cv::Exception'   what(): 
/tmp/binarydeb/ros-kinetic-opencv3-3.1.0/modules/core/src/matmul.cpp:900:
error: (-215) a_size.width == len in function gemm

代码

class Tracker {

    cv::Mat prevGray;
    vector<cv::Point2f> trackedFeatures;

    void processImage(const sensor_msgs::ImageConstPtr& msg) {

        // ROS declarations 
        cv_bridge::CvImagePtr cv_ptr;

        // Function Initializations
        if (freshStart == true) {
            cv::Mat rightTransform = cv::Mat::eye(3,3,CV_32FC1);
        }
        cv::Mat gray; 
        cv::Mat copy_img;
        vector<cv::Point2f> corners;

        try { 
             cv_ptr = cv_bridge::toCvCopy(msg, 
                        sensor_msgs::image_encodings::BGR8);
        } 
        catch (cv_bridge::Exception& e) {
            ROS_INFO("cv_bridge exception");
            return;
        }

        copy_img = cv_ptr->image;
        cv::cvtColor(cv_ptr->image, gray, cv::COLOR_BGR2GRAY);

        if (trackedFeatures.size() < 200) {
            cv::goodFeaturesToTrack(gray,corners,200,0.01,10);
            for (int i = 0; i < corners.size(); ++i) {
                trackedFeatures.push_back(corners[i]);
            }
        }

        if (!prevGray.empty()) {
            vector<uchar> status;
            vector<float> errors; 

            calcOpticalFlowPyrLK(prevGray, gray, trackedFeatures, corners,
                    status, errors, Size(10,10));

            if (countNonZero(status) < status.size() * 0.8) {
                cout << "cataclysmic error\n";
                rigidTransform = cv::Mat::eye(3,3,CV_32FC1);
                trackedFeatures.clear();
                prevGray.release();
                freshStart = true;
                return;
            } else {
                freshStart = false;
            }

            cv::Mat_<float> newRigidTransform = estimateRigidTransform(
                    trackedFeatures, corners, false);
            cv::Mat_<float> nrt33 = cv::Mat_<float>::eye(3,3);
            newRigidTransform.copyTo(nrt33.rowRange(0,2));
            rigidTransform *= nrt33;

            trackedFeatures.clear();
            for (int i = 0; i < status.size(); ++i) {
                if (status[i]) {
                    trackedFeatures.push_back(corners[i]);
                }
            }
        }

        // Debugging to see the tracked features as of now
        for (int i = 0; i < trackedFeatures.size(); ++i) {
            circle(cv_ptr->image, trackedFeatures[i], 3, Scalar(0,0,255), 
                CV_FILLED);
        }

        imshow(OPENCV_WINDOW, cv_ptr->image); 
        cv::waitKey(3);

        gray.copyTo(prevGray);
    }
};

现在,我知道错误在于语句gray.copyTo(prevGray).这是由于这样的事实,当我对此发表评论时,我没有出现任何错误.

Now I know the error lies in the statement gray.copyTo(prevGray). This is due to the fact that I get no errors when I comment this out.

class Tracker {

    // The ROS declarations 
    ...

    // Internal Declarations
    ...

    public:
    bool freshStart;
    Mat_<float> rigidTransform;
    ...

    Tracker():it_(nh1_) {
        image_sub_ = it_.subscribe("/ardrone/bottom/image_raw", 1,
                                        &Tracker::processImage, this);
        image_pub_ = it_.advertise("/stabImage", 1);

        cv::namedWindow(OPENCV_WINDOW);
    }

    ~Tracker() {
        cv::destroyWindow(OPENCV_WINDOW);
    }

    void processImage(const sensor_msgs::ImageConstPtr& msg) {
    ...
    }

int main(int argc, char** argv)
{
  ros::init(argc, argv, "video_stabilizer");
  Tracker tr;
  ros::spin();
  return 0;
}

推荐答案

问题似乎是matmul问题.您在哪里初始化rigidTransform?

The problem seems to be a matmul issue. Where do you initialize rigidTransform?

我认为不是这样:

cv::Mat rightTransform = cv::Mat::eye(3,3,CV_32FC1);

您需要:

rigidTransform = cv::Mat::eye(3,3,CV_32FC1);

注释掉gray.copyTo(prevGray)时不会发生此问题,因为没有它,如果if (!prevGray.empty())不运行,则循环.

The problem does not happen when you comment out gray.copyTo(prevGray) because without it the loop if if (!prevGray.empty()) does not run.

这篇关于OpenCV错误:断言失败(a_size.width == len)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆