OpenCV,计算两幅图像的单应矩阵



面射影变换是关于其次3维矢量的一种线性变换,可以使用一个非奇异的 3×3 矩阵H表示, X=HX ,射影变换也叫做单应(Homography)。计算出两幅图像之间的单应矩阵H,那么应用这个关系可以将一个视图中的

所有点变换到另一个视图中。

lenna4image

上图,最右边图像是将最左边图像进行了一次射影变换,变换到中间图像视图后的图像。

使用OpenCV可以调用库函数findHomography计算两幅图像的单应矩阵,其声明如下

Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray() )

单应矩阵的计算需要两幅图像中相对应的点,srcPoints,dstPoints是两幅图像中相对应的点,可以是Vector<Point2f>或者是CV_32FC2类型的矩阵,Method是计算单应矩阵时所使用的方法。

得到了图像的单应矩阵H就可以使用函数warpPerspective将图像变换到另一个视图中

void warpPerspective(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags=INTER_LINEAR, int borderMode=BORDER_CONSTANT, const Scalar& borderValue=Scalar())

下面就使用上面提到的两个函数,计算出两幅图像之间的单应矩阵H,并且将两幅图像合并为一副图像。

image

其操作过程非常简单,

  • 在“大”图像(目标图像)上选择4个点和“小”图像(被合并图像)的四角做对应,然后根据这4对对应的点计算两幅图像的单应矩阵。
  • 得到单应矩阵H后,利用函数warpPerspective将H应用到“小”图像上,得到图像M
  • 将图像M合并到目标图像中选择的四个点的位置

实现

首先定义两个vector保存对应的4对点

//4对相对应的像点计算图像的单应 Homography
vector<Point2f> left_image;
vector<Point2f> right_image;

将小图像的四角坐标插入到left_image中

left_image.push_back(Point2f(0, 0));
    left_image.push_back(Point2f(0, image_logo.rows));
    left_image.push_back(Point2f(image_logo.cols, image_logo.rows));
    left_image.push_back(Point2f(image_logo.cols, 0));

在在大图中选择4个点,并用这4对相对应的点计算单应矩阵H

复制代码
if (e == EVENT_LBUTTONDOWN){

        if (right_image.size() < 4){

            right_image.push_back(Point2f(float(x), float(y)));
            cout << x << " " << y << endl;
        }
        else {

            cout << "Calculating Homography" << endl;
            setMouseCallback("Display window", nullptr, nullptr);
            Mat H = findHomography(left_image, right_image, 0);
            Mat logoWarped;
            warpPerspective(image_logo, logoWarped,H, image_main.size());
            showFinal(image_main, logoWarped);
        }
    }
复制代码

最后,将logoWarped和main图像相加就得到最后结果。

详细代码:https://github.com/brookicv/opencvSample/tree/master/Homography

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单应矩阵(Homography Matrix)是计算机视觉中常用的一种变换矩阵,可以将一个平面上的点映射到另一个平面上的对应点。在OpenCV中,可以使用findHomography函数来估计两个平面之间的单应矩阵。下面是一个简单的示例代码: ``` #include <opencv2/opencv.hpp> using namespace cv; int main() { // 读取图像 Mat src1 = imread("image1.jpg"); Mat src2 = imread("image2.jpg"); // 定义特征点向量和描述子向量 std::vector<KeyPoint> keypoints1, keypoints2; Mat descriptors1, descriptors2; // 提取特征点和描述子 Ptr<ORB> orb = ORB::create(); orb->detectAndCompute(src1, noArray(), keypoints1, descriptors1); orb->detectAndCompute(src2, noArray(), keypoints2, descriptors2); // 匹配特征点 BFMatcher matcher(NORM_HAMMING); std::vector<DMatch> matches; matcher.match(descriptors1, descriptors2, matches); // 筛选出最佳匹配 double min_dist = 1000; for (int i = 0; i < descriptors1.rows; i++) { double dist = matches[i].distance; if (dist < min_dist) min_dist = dist; } std::vector<DMatch> good_matches; for (int i = 0; i < descriptors1.rows; i++) { if (matches[i].distance < 3 * min_dist) { good_matches.push_back(matches[i]); } } // 提取匹配点对 std::vector<Point2f> points1, points2; for (int i = 0; i < good_matches.size(); i++) { points1.push_back(keypoints1[good_matches[i].queryIdx].pt); points2.push_back(keypoints2[good_matches[i].trainIdx].pt); } // 计算单应矩阵 Mat H = findHomography(points1, points2, RANSAC); return 0; } ``` 在这个示例代码中,我们首先使用ORB算法提取了两幅图像的特征点和描述子。然后使用BFMatcher算法匹配两幅图像的特征点,并筛选出最佳匹配。接下来,我们使用findHomography函数估计了两个平面之间的单应矩阵。最后,我们可以使用这个单应矩阵来进行图像配准或者图像拼接等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值