当前位置: 首页 > news >正文

落地 轮廓匹配

个人理解为将一幅不规则的图形,通过最轮廓发现,最大轮廓匹配来确定图像的位置,再通过pt将不规则的图像放在规定的矩形里面,在通过透视变换将不规则的图形放进规则的图像中。

1. findHomography 函数

• Mat h = findHomography(srcPts, dstPts, RANSAC);

• 功能:该函数用于计算从源点集 srcPts 到目标点集 dstPts 的单应性矩阵 h。单应性矩阵描述了两个平面之间的投影变换关系。

• 参数:

• srcPts:源图像中的点集,是一个 std::vector<cv::Point2f> 类型的向量,包含至少4个点。这些点在源图像平面上定义了一个区域。

• dstPts:目标图像中的对应点集,同样是 std::vector<cv::Point2f> 类型,与 srcPts 中的点一一对应。它定义了源图像区域要映射到的目标图像区域。

• RANSAC:这是一种稳健的估计方法,称为随机抽样一致算法(Random Sample Consensus)。使用 RANSAC 时,函数会通过多次随机抽样来估计单应性矩阵,并排除可能的误匹配点,从而得到更准确可靠的单应性矩阵。

• 返回值:返回一个 cv::Mat 类型的单应性矩阵 h,它是一个 3x3 的矩阵,用于后续的透视变换。如果无法找到合适的单应性矩阵(例如点集数量不足或匹配质量太差),返回的矩阵将是一个空矩阵。

2. warpPerspective 函数

• warpPerspective(image, dst, h, Size(600, 800));

• 功能:根据给定的单应性矩阵 h 对输入图像 image 进行透视变换,并将结果存储在 dst 中。透视变换可以将图像从一个平面投影到另一个平面,常用于纠正图像的透视畸变、图像拼接等任务。

• 参数:

• image:输入的源图像,是一个 cv::Mat 类型的对象。

• dst:输出的目标图像,也是 cv::Mat 类型。在调用函数前,不需要对其进行初始化,函数会根据变换结果自动分配内存。

• h:前面通过 findHomography 函数计算得到的单应性矩阵,它决定了图像如何进行透视变换。

• Size(600, 800):指定输出图像 dst 的大小,这里宽为600像素,高为800像素。变换后的图像会被调整到这个尺寸。

这两行代码在图像变换处理中是非常关键的步骤,先计算单应性矩阵,再基于此矩阵对图像进行透视变换,从而实现将源图像的特定区域映射到目标图像的指定区域。



#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
    // Mat image = imread("D:/images/butterfly.jpg");
    Mat image = imread("C:/newword/image/31.jpg");
        Mat gray, binary;
    cvtColor(image, gray, COLOR_BGR2GRAY);
    threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU);

    vector<vector<Point>> contours;
    vector<Vec4i> hierachy;
    findContours(binary, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    int index = -1;
    double max = -1;
    for (int i = 0; i < contours.size(); i++) {
        double area = contourArea(contours[i]);
        if (area > max) {
            max = area;
            index = i;
        }
    }
    drawContours(image, contours, index, Scalar(0, 255, 0), 2, 8);

    Mat approxCurves;
    vector<Point2f> srcPts;
    approxPolyDP(contours[index], approxCurves, 100, true);
    for (int i = 0; i < approxCurves.rows; i++) {
        Vec2i  pt = approxCurves.at<Vec2i>(i, 0);//0代表着索引值,访问坐标
        std::cout << pt << std::endl;
        srcPts.push_back(Point2f(pt[0], pt[1]));
        circle(image, Point(pt[0], pt[1]), 12, Scalar(0, 0, 255), 2, 8, 0);
    }
    vector<Point2f> dstPts;
    dstPts.push_back(Point2f(0, 0));
    dstPts.push_back(Point2f(0, 800));
    dstPts.push_back(Point2f(600, 800));
    dstPts.push_back(Point2f(600, 0));
    imshow("轮廓", image);
    imwrite("C:/newword/result_c1c.png", image);

    Mat h = findHomography(srcPts, dstPts, RANSAC);
    Mat dst;
    warpPerspective(image, dst, h, Size(600, 800));
    imwrite("C:/newword/dst.p1ng", dst);
    waitKey(0);
    return 0;
}

http://www.lryc.cn/news/527543.html

相关文章:

  • 【漫话机器学习系列】064.梯度下降小口诀(Gradient Descent rule of thume)
  • JAVA(SpringBoot)集成Kafka实现消息发送和接收。
  • AI刷题-蛋糕工厂产能规划、优质章节的连续选择
  • 在线可编辑Excel
  • 什么是词嵌入?Word2Vec、GloVe 与 FastText 的区别
  • WPS数据分析000010
  • Qt中QVariant的使用
  • Avalonia UI MVVM DataTemplate里绑定Command
  • 动态规划DP 数字三角型模型 最低通行费用(题目详解+C++代码完整实现)
  • deepseek R1的确不错,特别是深度思考模式
  • Linux 常用命令 - sort 【对文件内容进行排序】
  • MyBatis最佳实践:提升数据库交互效率的秘密武器
  • 选择困难?直接生成pynput快捷键字符串
  • DeepSeek-R1:强化学习驱动的推理模型
  • 国内优秀的FPGA设计公司主要分布在哪些城市?
  • 3.日常英语笔记
  • 基于RIP的MGRE实验
  • 【开源免费】基于Vue和SpringBoot的美食推荐商城(附论文)
  • Pandas DataFrame 拼接、合并和关联
  • 【Redis】Redis修改连接数参数
  • scratch变魔术 2024年12月scratch三级真题 中国电子学会 图形化编程 scratch三级真题和答案解析
  • 51单片机开发:点阵屏显示数字
  • mysql DDL可重入讨论
  • DAY01 面向对象回顾、继承、抽象类
  • 127周一复盘 (165)玩法与难度思考
  • 【C语言常见概念详解】
  • 弹性分组环——RPR技术
  • 定制Centos镜像
  • Java---判断素数的三种方法
  • 多级缓存(亿级并发解决方案)