Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android OpenCV透视图的问题_Android_C++_Opencv_Image Processing_Feature Detection - Fatal编程技术网

Android OpenCV透视图的问题

Android OpenCV透视图的问题,android,c++,opencv,image-processing,feature-detection,Android,C++,Opencv,Image Processing,Feature Detection,我正在做一个Android背景减法项目,有一个移动的摄像头。我尝试使用特征匹配、findHomography和warpPerspective来查找两帧之间的重叠像素。但是,我得到的输出有点不正确。我对图像处理相当陌生,所以我不熟悉所有的术语。我有两个主要问题: 1) 扭曲透视的结果是过度扭曲的-例如,图像倾斜,图像中的对象翻转、挤压等。如何解决此问题 2) 我有时会遇到“OpenCV错误:Assertation失败”错误,这会使我的应用程序崩溃。此错误映射到透视图。注:图1(前一帧)和图2(当前

我正在做一个Android背景减法项目,有一个移动的摄像头。我尝试使用特征匹配、findHomography和warpPerspective来查找两帧之间的重叠像素。但是,我得到的输出有点不正确。我对图像处理相当陌生,所以我不熟悉所有的术语。我有两个主要问题:

1) 扭曲透视的结果是过度扭曲的-例如,图像倾斜,图像中的对象翻转、挤压等。如何解决此问题

2) 我有时会遇到“OpenCV错误:Assertation失败”错误,这会使我的应用程序崩溃。此错误映射到透视图。注:图1(前一帧)和图2(当前帧)中的尺寸相同。在检测特征(当前来自RGB)之前,我将图像转换为灰色。我有时会在findHomography中遇到类似的“OpenCV断言失败”错误,但我了解到它至少需要4个点——因此添加一个if语句解决了它,但不确定如何使用warpPerspective解决该错误

我得到的错误是:

02-24 15:30:49.554: E/cv::error()(4589): OpenCV Error: Assertion failed (type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U)) 
    in void cv::batchDistance(cv::InputArray, cv::InputArray, cv::OutputArray, int, cv::OutputArray, int, int, cv::InputArray, int, bool), 
    file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/core/src/stat.cpp, line 2473
我的代码:

void stitchFrames(){

    //convert frames to grayscale
    image1 = prevFrame.clone();
    image2 = currFrame.clone();

    if(colourSpace==1){ //convert from RGB to gray
        cv::cvtColor(image1, image1Gray,CV_RGB2GRAY);
        cv::cvtColor(image2, image2Gray,CV_RGB2GRAY);
    }
    else if(colourSpace==2){ //convert from HSV to gray
        cv::cvtColor(image1, image1Gray,CV_HSV2RGB);
        cv::cvtColor(image1Gray,image1Gray,CV_RGB2GRAY);
        cv::cvtColor(image2, image1Gray,CV_HSV2RGB);
        cv::cvtColor(image2Gray,image1Gray,CV_RGB2GRAY);
    }

    else if(colourSpace==3){ //no need for conversion
        image1Gray = image1;
        image2Gray = image2;
    }

    //----FEATURE DETECTION----

    //key points
    std::vector<KeyPoint> keypoints1, keypoints2;

    int minHessian;

    cv::FastFeatureDetector detector;

    detector.detect(image1Gray,keypoints1); //prevFrame
    detector.detect(image2Gray,keypoints2); //currFrame

    KeyPoint kp = keypoints2[4];
    Point2f p = kp.pt;
    float i = p.y;

    //---FEATURE EXTRACTION----

    //extracted descriptors
    cv::Mat descriptors1,descriptors2;

    OrbDescriptorExtractor extractor;
    extractor.compute(image1,keypoints1,descriptors1); //prevFrame
    extractor.compute(image2,keypoints2,descriptors2); //currFrame

    //----FEATURE MATCHING----

    //BruteForceMacher

    BFMatcher matcher;

    std::vector< cv::DMatch > matches; //result of matching descriptors
    std::vector< cv::DMatch > goodMatches; //result of sifting matches to get only 'good' matches

    matcher.match(descriptors1,descriptors2,matches);

    //----HOMOGRAPY - WARP-PERSPECTIVE - PERSPECTIVE-TRANSFORM----

    double maxDist = 0.0; //keep track of max distance from the matches
    double minDist = 80.0; //keep track of min distance from the matches

    //calculate max & min distances between keypoints
    for(int i=0; i<descriptors1.rows;i++){
        DMatch match = matches[i];

        float dist = match.distance;
        if (dist<minDist) minDist = dist;
        if(dist>maxDist) maxDist=dist;
    }

    //get only the good matches
    for( int i = 0; i < descriptors1.rows; i++ ){
        DMatch match = matches[i];
        if(match.distance< 500){
            goodMatches.push_back(match);
        }
    }

    std::vector< Point2f > obj;
    std::vector< Point2f > scene;

    //get the keypoints from the good matches
    for( int i = 0; i < goodMatches.size(); i++ ){

        //--keypoints from image1
        DMatch match1 = goodMatches[i];
        int qI1 = match1.trainIdx;
        KeyPoint kp1 = keypoints2[qI1];
        Point2f point1 = kp1.pt;
        obj.push_back(point1);

        //--keypoints from image2
        DMatch match2 = goodMatches[i];
        int qI2 = match2.queryIdx;
        KeyPoint kp2 = keypoints1[qI2];
        Point2f point2 = kp2.pt;
        scene.push_back(point2);

    }

    //calculate the homography matrix
    if(goodMatches.size() >=4){
        Mat H = findHomography(obj,scene, CV_RANSAC);

        warpPerspective(image2,warpResult,H,Size(image1.cols,image1.rows));
    }
}
void缝合框架(){
//将帧转换为灰度
image1=prevFrame.clone();
image2=currFrame.clone();
如果(颜色空间==1){//从RGB转换为灰色
cv::CVT颜色(图像1、图像1灰色、cv_rgb2灰色);
cv::CVT颜色(图像2、图像2Gray、cv_RGB2GRAY);
}
else如果(颜色空间==2){//从HSV转换为灰色
cv::CVT颜色(图像1、图像1Gray、cv_HSV2RGB);
cv::CVT颜色(image1Gray、image1Gray、cv_RGB2GRAY);
cv::CVT颜色(图像2、图像1Gray、cv_HSV2RGB);
cv::CVT颜色(image2Gray、image1Gray、cv_RGB2GRAY);
}
else如果(colorspace==3){//不需要转换
image1Gray=image1;
image2Gray=image2;
}
//----特征检测----
//要点
std::向量关键点1,关键点2;
minHessian国际酒店;
cv::FastFeatureDetector检测器;
detector.detect(image1Gray,keypoints1);//prevFrame
detector.detect(image2Gray,keypoints2);//当前帧
关键点kp=关键点2[4];
点2f p=kp.pt;
浮点数i=p.y;
//---特征提取----
//提取描述符
cv::Mat描述符1,描述符2;
ORB牵引器;
compute(image1,keypoints1,描述符1);//prevFrame
compute(image2,keypoints2,描述符2);//currFrame
//----特征匹配----
//布鲁特福斯马赫
BFMatcher匹配器;
std::vector匹配;//匹配描述符的结果
std::vectorgoodMatches;//筛选匹配以仅获得“良好”匹配的结果
匹配(描述符1,描述符2,匹配);
//----同形-扭曲-透视-透视-变换----
double maxDist=0.0;//跟踪与匹配项的最大距离
double Minist=80.0;//记录与比赛的最小距离
//计算关键点之间的最大和最小距离
对于(int i=0;i obj;
std::vector场景;
//从好的匹配中获取关键点
对于(int i=0;i=4){
Mat H=findHomography(obj、场景、CV_RANSAC);
warpPerspective(image2,warpResult,H,Size(image1.cols,image1.rows));
}
}

关于你的第一个问题,我认为你提到的失真是因为:

  • 您估计单应
    H
    将图像1中的坐标映射为图像2中的坐标。执行
    Mat H=findHomography(obj,scene,CV_RANSAC);
    obj
    是图像1中的点坐标,
    scene
    是图像2中的点坐标

  • 然后在函数
    warpPerspective
    中使用
    H
    ,就像它将图像2中的坐标映射到图像1中的坐标一样,因为您希望它将
    image2
    转换为
    warpResult
    ,我猜应该将其缝合到
    image1

因此,您应该如下估计单应性
H
math=findHomography(场景、obj、CV_RANSAC);

关于你的第二个问题,我认为这是由以下说明提出的:

matcher.match(descriptors1,descriptors2,matches);
错误表示表达式

(type == src2.type() && src1.cols == src2.cols && (type == CV_32F || type == CV_8U))
发现为false,而函数工作时应为true。解决了一个类似的问题:在调用
match
函数之前,需要手动检查以下内容是否为true:

(descriptors1.type()==descriptors2.type() && descriptors1.cols==descriptors2.cols)
关于(1),我猜你估计的单应性是基于错误的匹配

首先,我将使用ORB检测器而不是FAST,然后更改
ransacreprojectthreshold
参数。默认值为3,详细信息:

ransacreprojectthreshold:

将点对视为输入帧时允许的最大重投影错误 (仅在RANSAC方法中使用)。即,如果:

|dstPoints_i-ConvertPointsShamogeneous(H*srcPoints_i)|>TransacreProjectThreshold

然后点i被视为异常值。如果srcPoints和dstPoints 如果以像素为单位进行测量,则设置此参数通常是有意义的 在1到10之间的某个地方

换句话说,假设默认为3个像素,如果在将单应性应用于SRC点后,其到DST点的距离超过3个像素,则该对被视为内部(即:良好)

这仅仅是一个开始,它还将帮助您为g找到更好的过滤器