gpt4 book ai didi

python - cv2.estimateRigidTransform 最小点数?

转载 作者:太空宇宙 更新时间:2023-11-03 22:18:54 24 4
gpt4 key购买 nike

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

据我所知,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

m = cv2.estimateRigidTransform(src_pts, tgt_pts, fullAffine=False)

给我 None

最佳答案

理论上,非完全仿射设置只需要 2 个对点,详见 ngia ho。 .但是查看openCV的源码发现,函数要返回RANSAC计算出的值,至少需要3对点。

我在下面包含了相应的功能供您引用。它位于 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;
}

关于python - cv2.estimateRigidTransform 最小点数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53698534/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com