Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.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
Python cv2.1变换最小点数?_Python_Opencv_Matrix_Linear Algebra - Fatal编程技术网

Python cv2.1变换最小点数?

Python cv2.1变换最小点数?,python,opencv,matrix,linear-algebra,Python,Opencv,Matrix,Linear Algebra,cv2.Transform所需的最小点数是多少 正如我对fullAffine=False的理解,它有4个自由度,所以2个点就足够了 然而: 使用2个numpy数组作为输入: src_pts_subset.shape (2, 2) tgt_pts_subset.shape (2, 2) type(src_pts_subset) <class 'numpy.ndarray'> type(tgt_pts_subset) <class 'numpy.ndarray'> src_p

cv2.Transform
所需的最小点数是多少

正如我对
fullAffine=False的理解,它有4个自由度,所以2个点就足够了

然而:

使用2个numpy数组作为输入:

src_pts_subset.shape (2, 2)
tgt_pts_subset.shape (2, 2)
type(src_pts_subset) <class 'numpy.ndarray'>
type(tgt_pts_subset) <class 'numpy.ndarray'>
src_pts_subset.dtype int64
tgt_pts_subset.dtype int64

理论上,非完全仿射设置只需要2对点,如所述。但是,在检查openCV中的源代码后,函数至少需要3对点才能返回RANSAC计算的值

我在下面包含了相应的函数供您参考。它位于openCV源文件的lkpyramid.cpp文件中

cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullAffine )
{
    return estimateRigidTransform(src1, src2, fullAffine, 500, 0.5, 3);
}

cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullAffine, int ransacMaxIters, double ransacGoodRatio,
                                    const int ransacSize0)
{
    CV_INSTRUMENT_REGION()

    Mat M(2, 3, CV_64F), A = src1.getMat(), B = src2.getMat();

    const int COUNT = 15;
    const int WIDTH = 160, HEIGHT = 120;

    std::vector<Point2f> pA, pB;
    std::vector<int> good_idx;
    std::vector<uchar> status;

    double scale = 1.;
    int i, j, k, k1;

    RNG rng((uint64)-1);
    int good_count = 0;

    if( ransacSize0 < 3 )
        CV_Error( Error::StsBadArg, "ransacSize0 should have value bigger than 2.");

    if( ransacGoodRatio > 1 || ransacGoodRatio < 0)
        CV_Error( Error::StsBadArg, "ransacGoodRatio should have value between 0 and 1");

    if( A.size() != B.size() )
        CV_Error( Error::StsUnmatchedSizes, "Both input images must have the same size" );

    if( A.type() != B.type() )
        CV_Error( Error::StsUnmatchedFormats, "Both input images must have the same data type" );

    int count = A.checkVector(2);

    if( count > 0 )
    {
        A.reshape(2, count).convertTo(pA, CV_32F);
        B.reshape(2, count).convertTo(pB, CV_32F);
    }
    else if( A.depth() == CV_8U )
    {
        int cn = A.channels();
        CV_Assert( cn == 1 || cn == 3 || cn == 4 );
        Size sz0 = A.size();
        Size sz1(WIDTH, HEIGHT);

        scale = std::max(1., std::max( (double)sz1.width/sz0.width, (double)sz1.height/sz0.height ));

        sz1.width = cvRound( sz0.width * scale );
        sz1.height = cvRound( sz0.height * scale );

        bool equalSizes = sz1.width == sz0.width && sz1.height == sz0.height;

        if( !equalSizes || cn != 1 )
        {
            Mat sA, sB;

            if( cn != 1 )
            {
                Mat gray;
                cvtColor(A, gray, COLOR_BGR2GRAY);
                resize(gray, sA, sz1, 0., 0., INTER_AREA);
                cvtColor(B, gray, COLOR_BGR2GRAY);
                resize(gray, sB, sz1, 0., 0., INTER_AREA);
            }
            else
            {
                resize(A, sA, sz1, 0., 0., INTER_AREA);
                resize(B, sB, sz1, 0., 0., INTER_AREA);
            }

            A = sA;
            B = sB;
        }

        int count_y = COUNT;
        int count_x = cvRound((double)COUNT*sz1.width/sz1.height);
        count = count_x * count_y;

        pA.resize(count);
        pB.resize(count);
        status.resize(count);

        for( i = 0, k = 0; i < count_y; i++ )
            for( j = 0; j < count_x; j++, k++ )
            {
                pA[k].x = (j+0.5f)*sz1.width/count_x;
                pA[k].y = (i+0.5f)*sz1.height/count_y;
            }

        // find the corresponding points in B
        calcOpticalFlowPyrLK(A, B, pA, pB, status, noArray(), Size(21, 21), 3,
                             TermCriteria(TermCriteria::MAX_ITER,40,0.1));

        // repack the remained points
        for( i = 0, k = 0; i < count; i++ )
            if( status[i] )
            {
                if( i > k )
                {
                    pA[k] = pA[i];
                    pB[k] = pB[i];
                }
                k++;
            }
        count = k;
        pA.resize(count);
        pB.resize(count);
    }
    else
        CV_Error( Error::StsUnsupportedFormat, "Both input images must have either 8uC1 or 8uC3 type" );

    good_idx.resize(count);

    if( count < ransacSize0 )
        return Mat();

    Rect brect = boundingRect(pB);

    std::vector<Point2f> a(ransacSize0);
    std::vector<Point2f> b(ransacSize0);

    // RANSAC stuff:
    // 1. find the consensus
    for( k = 0; k < ransacMaxIters; k++ )
    {
        std::vector<int> idx(ransacSize0);
        // choose random 3 non-complanar points from A & B
        for( i = 0; i < ransacSize0; i++ )
        {
            for( k1 = 0; k1 < ransacMaxIters; k1++ )
            {
                idx[i] = rng.uniform(0, count);

                for( j = 0; j < i; j++ )
                {
                    if( idx[j] == idx[i] )
                        break;
                    // check that the points are not very close one each other
                    if( fabs(pA[idx[i]].x - pA[idx[j]].x) +
                        fabs(pA[idx[i]].y - pA[idx[j]].y) < FLT_EPSILON )
                        break;
                    if( fabs(pB[idx[i]].x - pB[idx[j]].x) +
                        fabs(pB[idx[i]].y - pB[idx[j]].y) < FLT_EPSILON )
                        break;
                }

                if( j < i )
                    continue;

                if( i+1 == ransacSize0 )
                {
                    // additional check for non-complanar vectors
                    a[0] = pA[idx[0]];
                    a[1] = pA[idx[1]];
                    a[2] = pA[idx[2]];

                    b[0] = pB[idx[0]];
                    b[1] = pB[idx[1]];
                    b[2] = pB[idx[2]];

                    double dax1 = a[1].x - a[0].x, day1 = a[1].y - a[0].y;
                    double dax2 = a[2].x - a[0].x, day2 = a[2].y - a[0].y;
                    double dbx1 = b[1].x - b[0].x, dby1 = b[1].y - b[0].y;
                    double dbx2 = b[2].x - b[0].x, dby2 = b[2].y - b[0].y;
                    const double eps = 0.01;

                    if( fabs(dax1*day2 - day1*dax2) < eps*std::sqrt(dax1*dax1+day1*day1)*std::sqrt(dax2*dax2+day2*day2) ||
                        fabs(dbx1*dby2 - dby1*dbx2) < eps*std::sqrt(dbx1*dbx1+dby1*dby1)*std::sqrt(dbx2*dbx2+dby2*dby2) )
                        continue;
                }
                break;
            }

            if( k1 >= ransacMaxIters )
                break;
        }

        if( i < ransacSize0 )
            continue;

        // estimate the transformation using 3 points
        getRTMatrix( a, b, 3, M, fullAffine );

        const double* m = M.ptr<double>();
        for( i = 0, good_count = 0; i < count; i++ )
        {
            if( std::abs( m[0]*pA[i].x + m[1]*pA[i].y + m[2] - pB[i].x ) +
                std::abs( m[3]*pA[i].x + m[4]*pA[i].y + m[5] - pB[i].y ) < std::max(brect.width,brect.height)*0.05 )
                good_idx[good_count++] = i;
        }

        if( good_count >= count*ransacGoodRatio )
            break;
    }

    if( k >= ransacMaxIters )
        return Mat();

    if( good_count < count )
    {
        for( i = 0; i < good_count; i++ )
        {
            j = good_idx[i];
            pA[i] = pA[j];
            pB[i] = pB[j];
        }
    }

    getRTMatrix( pA, pB, good_count, M, fullAffine );
    M.at<double>(0, 2) /= scale;
    M.at<double>(1, 2) /= scale;

    return M;
}
cv::Mat cv::EstimaterialGidTransform(输入阵列src1、输入阵列src2、布尔全仿射)
{
返回变换(src1,src2,fullAffine,500,0.5,3);
}
cv::Mat cv::EstimaterialGidTransform(输入阵列src1、输入阵列src2、布尔全仿射、int-ransacMaxIters、双ransacGoodRatio、,
const int transacsize0)
{
CV_仪器_区域()
Mat M(2,3,CV_64F),A=src1.getMat(),B=src2.getMat();
常数int计数=15;
常数int宽度=160,高度=120;
std::载体pA,pB;
std::矢量良好_idx;
病媒状态;
双刻度=1。;
int i,j,k,k1;
RNG RNG((uint64)-1);
int良好计数=0;
如果(ransacSize0<3)
CV_错误(错误::StsBadArg,“ransacSize0的值应大于2”);
如果(ransacGoodRatio>1 | | ransacGoodRatio<0)
CV_错误(错误::StsBadArg,“ransacGoodRatio的值应介于0和1之间”);
如果(A.size()!=B.size())
CV_错误(错误::StsUnmatchedSizes,“两个输入图像必须具有相同的大小”);
如果(A.type()!=B.type())
CV_错误(错误::StsUnmatchedFormats,“两个输入图像必须具有相同的数据类型”);
int count=A.checkVector(2);
如果(计数>0)
{
A.重塑(2,计数)。转换为(pA,CV_32F);
B.重塑(2,计数)。转换为(pB,CV_32F);
}
否则如果(A.深度()==CV_8U)
{
int cn=A.channels();
CV|U断言(cn==1 | | cn==3 | | cn==4);
大小sz0=A.Size();
尺寸sz1(宽度、高度);
比例=标准::最大值(1.,标准::最大值((双)sz1.width/sz0.width,(双)sz1.height/sz0.height));
sz1.width=cvRound(sz0.width*刻度);
sz1.height=cvRound(sz0.height*刻度);
bool equalsies=sz1.width==sz0.width&&sz1.height==sz0.height;
如果(!等于| | cn!=1)
{
马萨,;
如果(cn!=1)
{
席灰色;
CVT颜色(A、灰色、灰色);
调整大小(灰色、sA、sz1、0、0、中间区域);
CVT颜色(B,灰色,颜色为灰色);
调整大小(灰色、sB、sz1、0、0、中间区域);
}
其他的
{
调整大小(A、sA、sz1、0、0、内部区域);
调整大小(B、sB、sz1、0、0、内部区域);
}
A=sA;
B=某人;
}
int count_y=计数;
int count_x=cvRound((双)计数*sz1.宽度/sz1.高度);
计数=计数x*计数y;
pA.调整大小(计数);
pB.调整大小(计数);
状态。调整大小(计数);
对于(i=0,k=0;ik)
{
pA[k]=pA[i];
pB[k]=pB[i];
}
k++;
}
计数=k;
pA.调整大小(计数);
pB.调整大小(计数);
}
其他的
CV_错误(错误::StsUnsupportedFormat,“两个输入图像必须具有8uC1或8uC3类型”);
好的。调整大小(计数);
如果(计数cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullAffine )
{
    return estimateRigidTransform(src1, src2, fullAffine, 500, 0.5, 3);
}

cv::Mat cv::estimateRigidTransform( InputArray src1, InputArray src2, bool fullAffine, int ransacMaxIters, double ransacGoodRatio,
                                    const int ransacSize0)
{
    CV_INSTRUMENT_REGION()

    Mat M(2, 3, CV_64F), A = src1.getMat(), B = src2.getMat();

    const int COUNT = 15;
    const int WIDTH = 160, HEIGHT = 120;

    std::vector<Point2f> pA, pB;
    std::vector<int> good_idx;
    std::vector<uchar> status;

    double scale = 1.;
    int i, j, k, k1;

    RNG rng((uint64)-1);
    int good_count = 0;

    if( ransacSize0 < 3 )
        CV_Error( Error::StsBadArg, "ransacSize0 should have value bigger than 2.");

    if( ransacGoodRatio > 1 || ransacGoodRatio < 0)
        CV_Error( Error::StsBadArg, "ransacGoodRatio should have value between 0 and 1");

    if( A.size() != B.size() )
        CV_Error( Error::StsUnmatchedSizes, "Both input images must have the same size" );

    if( A.type() != B.type() )
        CV_Error( Error::StsUnmatchedFormats, "Both input images must have the same data type" );

    int count = A.checkVector(2);

    if( count > 0 )
    {
        A.reshape(2, count).convertTo(pA, CV_32F);
        B.reshape(2, count).convertTo(pB, CV_32F);
    }
    else if( A.depth() == CV_8U )
    {
        int cn = A.channels();
        CV_Assert( cn == 1 || cn == 3 || cn == 4 );
        Size sz0 = A.size();
        Size sz1(WIDTH, HEIGHT);

        scale = std::max(1., std::max( (double)sz1.width/sz0.width, (double)sz1.height/sz0.height ));

        sz1.width = cvRound( sz0.width * scale );
        sz1.height = cvRound( sz0.height * scale );

        bool equalSizes = sz1.width == sz0.width && sz1.height == sz0.height;

        if( !equalSizes || cn != 1 )
        {
            Mat sA, sB;

            if( cn != 1 )
            {
                Mat gray;
                cvtColor(A, gray, COLOR_BGR2GRAY);
                resize(gray, sA, sz1, 0., 0., INTER_AREA);
                cvtColor(B, gray, COLOR_BGR2GRAY);
                resize(gray, sB, sz1, 0., 0., INTER_AREA);
            }
            else
            {
                resize(A, sA, sz1, 0., 0., INTER_AREA);
                resize(B, sB, sz1, 0., 0., INTER_AREA);
            }

            A = sA;
            B = sB;
        }

        int count_y = COUNT;
        int count_x = cvRound((double)COUNT*sz1.width/sz1.height);
        count = count_x * count_y;

        pA.resize(count);
        pB.resize(count);
        status.resize(count);

        for( i = 0, k = 0; i < count_y; i++ )
            for( j = 0; j < count_x; j++, k++ )
            {
                pA[k].x = (j+0.5f)*sz1.width/count_x;
                pA[k].y = (i+0.5f)*sz1.height/count_y;
            }

        // find the corresponding points in B
        calcOpticalFlowPyrLK(A, B, pA, pB, status, noArray(), Size(21, 21), 3,
                             TermCriteria(TermCriteria::MAX_ITER,40,0.1));

        // repack the remained points
        for( i = 0, k = 0; i < count; i++ )
            if( status[i] )
            {
                if( i > k )
                {
                    pA[k] = pA[i];
                    pB[k] = pB[i];
                }
                k++;
            }
        count = k;
        pA.resize(count);
        pB.resize(count);
    }
    else
        CV_Error( Error::StsUnsupportedFormat, "Both input images must have either 8uC1 or 8uC3 type" );

    good_idx.resize(count);

    if( count < ransacSize0 )
        return Mat();

    Rect brect = boundingRect(pB);

    std::vector<Point2f> a(ransacSize0);
    std::vector<Point2f> b(ransacSize0);

    // RANSAC stuff:
    // 1. find the consensus
    for( k = 0; k < ransacMaxIters; k++ )
    {
        std::vector<int> idx(ransacSize0);
        // choose random 3 non-complanar points from A & B
        for( i = 0; i < ransacSize0; i++ )
        {
            for( k1 = 0; k1 < ransacMaxIters; k1++ )
            {
                idx[i] = rng.uniform(0, count);

                for( j = 0; j < i; j++ )
                {
                    if( idx[j] == idx[i] )
                        break;
                    // check that the points are not very close one each other
                    if( fabs(pA[idx[i]].x - pA[idx[j]].x) +
                        fabs(pA[idx[i]].y - pA[idx[j]].y) < FLT_EPSILON )
                        break;
                    if( fabs(pB[idx[i]].x - pB[idx[j]].x) +
                        fabs(pB[idx[i]].y - pB[idx[j]].y) < FLT_EPSILON )
                        break;
                }

                if( j < i )
                    continue;

                if( i+1 == ransacSize0 )
                {
                    // additional check for non-complanar vectors
                    a[0] = pA[idx[0]];
                    a[1] = pA[idx[1]];
                    a[2] = pA[idx[2]];

                    b[0] = pB[idx[0]];
                    b[1] = pB[idx[1]];
                    b[2] = pB[idx[2]];

                    double dax1 = a[1].x - a[0].x, day1 = a[1].y - a[0].y;
                    double dax2 = a[2].x - a[0].x, day2 = a[2].y - a[0].y;
                    double dbx1 = b[1].x - b[0].x, dby1 = b[1].y - b[0].y;
                    double dbx2 = b[2].x - b[0].x, dby2 = b[2].y - b[0].y;
                    const double eps = 0.01;

                    if( fabs(dax1*day2 - day1*dax2) < eps*std::sqrt(dax1*dax1+day1*day1)*std::sqrt(dax2*dax2+day2*day2) ||
                        fabs(dbx1*dby2 - dby1*dbx2) < eps*std::sqrt(dbx1*dbx1+dby1*dby1)*std::sqrt(dbx2*dbx2+dby2*dby2) )
                        continue;
                }
                break;
            }

            if( k1 >= ransacMaxIters )
                break;
        }

        if( i < ransacSize0 )
            continue;

        // estimate the transformation using 3 points
        getRTMatrix( a, b, 3, M, fullAffine );

        const double* m = M.ptr<double>();
        for( i = 0, good_count = 0; i < count; i++ )
        {
            if( std::abs( m[0]*pA[i].x + m[1]*pA[i].y + m[2] - pB[i].x ) +
                std::abs( m[3]*pA[i].x + m[4]*pA[i].y + m[5] - pB[i].y ) < std::max(brect.width,brect.height)*0.05 )
                good_idx[good_count++] = i;
        }

        if( good_count >= count*ransacGoodRatio )
            break;
    }

    if( k >= ransacMaxIters )
        return Mat();

    if( good_count < count )
    {
        for( i = 0; i < good_count; i++ )
        {
            j = good_idx[i];
            pA[i] = pA[j];
            pB[i] = pB[j];
        }
    }

    getRTMatrix( pA, pB, good_count, M, fullAffine );
    M.at<double>(0, 2) /= scale;
    M.at<double>(1, 2) /= scale;

    return M;
}