cv2 五边形矫正,python ,多边形透视变换

news2024/11/20 4:49:57
#图像透视变换--矫正
#根据最大的5边形进行透视变换
#获取最大和最次长   周长对应的轮廓
#该轮廓进行5边形拟合逼近
#进行透视变换:应用两线交点
import numpy as np
import cv2


#大津阈值法 OSTU
def myApprox(con,pointnum=5):# con为预先得到的最大轮廓
    num = 0.001
    # 初始化时不需要太小,因为四边形所需的值并不很小
    ep = num * cv2.arcLength(con, True)
    con = cv2.approxPolyDP(con, ep, True)
    while (1):
        if len(con) == pointnum:#防止程序崩溃设置的==pointnum
            break
        else:
            num = num * 1.5
            if num >2:
                break
            ep = num * cv2.arcLength(con, True)
            con = cv2.approxPolyDP(con, ep, True)
            continue
    return con

#多边形矫正
def Polygon_correction(img):
    if len(img.shape) > 2:
        img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    contours, hierarchy = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    perimeter_list, area_list, cnt_list, center_lsit, box_list = [], [], [], [], []
    ori_img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
    ori_w,ori_h = ori_img.shape[0],ori_img.shape[1]
    print('ori_w,ori_h:',ori_w,ori_h)

    #ori_img = cv2.drawContours(ori_img, contours, -1, (0, 0, 255), 2)
    cv2.imshow('binary7', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    #筛选面积最大的三个候选轮廓
    if len(contours) > 0:
        cnts = sorted(contours,
                      key=cv2.contourArea,  # 根据该函数计算的结果排序
                      reverse=True)
        cnts = cnts[:2]
        docCnt =None
        x, y, w, h = 0,0,ori_w,ori_h
        for cnt in cnts:
            #逼近法五边形拟合
            approx =myApprox(cnt, pointnum=5)
            if len(approx)==5:
                docCnt = approx
                x, y, w, h = cv2.boundingRect(docCnt) #左上角,w,h
                # 绘制矩形
                #cv2.rectangle(ori_img, (x, y + h), (x + w, y), (0, 255, 255))
                break

        #获取得到五边形边框五个原始点
        if not docCnt is None:
            points = [] #逆时针旋转排序,五个点
            for doc in docCnt:
                peak = doc[0]
                # 在角点绘制小圆圈
                #cv2.circle(ori_img, tuple(peak), 10, (0, 0, 255), 2) #橙色
                points.append(tuple(peak))

            p1, p2, p3, p4, p5 = points[0], points[1], points[2], points[3], points[4]
            #求四点确定的两条线段的交点,p1,p2,crossp,p5 作为ori转移矩阵前坐标点
            from util import get_crosss_point
            crossp = get_crosss_point(p2, p3, p4, p5)
            #如果有交点,让交点作为四个点之一,如果无交点则选择点3或则点4即可
            if crossp is not None:
                src = np.float32([p1,p2,crossp,p5])
                #外接矩阵,水平垂直矩形
                afterp1 = (x, y)
                afterp2 = (x, y + h-1)
                afterpcrossp = (x + w-1, y + h-1)
                afterp5 = (x + w-1, y)
                afterpoints = np.float32([afterp1, afterp2, afterpcrossp, afterp5])
            else:
                src = np.float32([p1,p2,p3,p5])#存在一定误差
                #根据自己需求得到多边形点
                xmin, ymin = np.array(points)[:, 0].min(), np.array(points)[:, 1].min()
                xmax, ymax = np.array(points)[:, 0].max(), np.array(points)[:, 1].max()
                sigma = (xmax - p3[0] + ymax - p4[1])/2
                sigma = int(sigma)

                afterp1 = (xmin, ymin)
                afterp2 = (xmin, ymax)
                afterp3 = (xmax - sigma, ymax)
                afterp4 = (xmax, ymax - sigma)
                afterp5 = (xmax, ymin)
                afterpoints = [afterp1, afterp2, afterp3,afterp5]

            print("原始点:", src)
            print("after点:",afterpoints)

            m = cv2.getPerspectiveTransform(src,afterpoints)
            result = cv2.warpPerspective(ori_img, m,(ori_h,ori_w))  # 透视变换

            cv2.circle(result, afterp1, 5, (0, 255, 0), 2)
            cv2.circle(result, afterp2, 5, (0, 255, 0), 2)
            cv2.circle(result, afterpcrossp, 5, (0, 255, 0), 2)
            cv2.circle(result, afterp5, 5, (0, 255, 0), 2)
            print(result.shape)
            cv2.polylines(result,[np.array(afterpoints, np.int32)], True,(255, 255, 0),1)
            cv2.imshow('result', result)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
            return result
        else:
            return img
    else:
        return img



if __name__ == '__main__':
    img = cv2.imread('./data/binary7.png')#二值图
    afterPolygonimg = Polygon_correction(img)
    


 

 

 ps:求交点函数,链接为:(85条消息) python 已知四点,两条线,求交点_Lee魅儿的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/444522.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年CDGA/CDGP数据治理工程师认证报名需要什么条件?

DAMA认证为数据管理专业人士提供职业目标晋升规划,彰显了职业发展里程碑及发展阶梯定义,帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力,促进开展工作实践应用及实际问题解决,形成企业所需的新数字经济下的核心职业…

mybatis01-Lombok、mybatis原理、参数处理、模糊查询、结果封装

mybatis01 Lombok 一、Lombok的使用 Lombok 是一个Java库,能自动插入编辑器并构建工具,简化Java开发。通过加注解的方式,不需要为类编写getter、setter、constructor或equals,同时可以自动化日志变量。 第一步、在pom.xml中加…

基于动态车辆模型的百度Apollo LQR和MPC横向控制算法分析(Matlab代码实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 👨‍💻4 Matlab代码 💥1 概述 Apollo 是由百度发起的一个高效、灵活的基于自动驾驶的测试和研发的平台。Apollo 的主要逻辑为局部规划 轨道跟踪。在局部规划…

4.1 插值概念与基础理论

学习目标: 学习插值的基础理论可以从以下几个方面入手: 理解插值的概念:插值是指根据已知数据点的函数值,构造出经过这些点的函数,用于在已知数据点之间估计函数值。可以将其看做是一种函数逼近的方法。 掌握插值多项…

【Linux】MySQL高可用之Mysql读写分离实践

一、MySQL读写分离原理 读写分离就是在主服务器上修改,数据会同步到从服务器,从服务器只能提供读取数据,不能写入,实现备份的同时也实现了数据库性能的优化,以及提升了服务器安全。 二、读写分离实践 绝大多数的企业的…

居家办公远程控制电脑怎么操作

居家办公或者混合办公,正成为一种新的流行趋势。如何更好地居家办公,实现更高的工作效率和更舒适办公体验,我们总结出如下建议。 无论您是每周远程工作几天还是全职工作,无论是出于选择还是因为健康状况或天气事件,都…

部署YUM仓库及NFS共享服务

一、YUM仓库服务 1)YUM概述 YUM(Yellow dog Updater Modified) 基于RPM包构建的软件更新机制 可以自动解决依赖关系 所有软件包由集中的YUM软件仓库提供 linux本身就是以系统简洁为自身优势,所以在安装操作系统的时候并没有将…

Kaggle往期赛 | 多目标推荐系统大赛baseline

来源:深度之眼 作者:比赛教研部 编辑:学姐 Kaggle OTTO – Multi-Objective Recommender System多目标推荐系统大赛 赛题分析baseline 1、赛题链接 https://www.kaggle.com/competitions/otto-recommender-system/overview 2、赛题描述 本…

聚观早报 |字节与Meta争夺VR开发者;苹果设备无故要求输入ID密码

今日要闻:字节与Meta争夺VR应用开发者;苹果设备无故要求输入ID密码;余承东称25年是智能电动汽车分水岭;小鹏回应G6售价及配置信息曝光;亚马逊将在爱尔兰裁员200人 字节与Meta争夺VR应用开发者 4 月 14 日消息&#xf…

运筹说 第89期|网络计划-网络计划的优化

通过画网络图并计算时间参数,我们已得到了一个初步的网络计划,而网络计划技术的核心却在于从工期、成本、资源等方面对这个初步方案做进一步的改善和调整,以求得最佳效果,这一过程,就是网络计划的优化。接下来让我们跟…

家用洗地机到底好不好用?国产性价比高的品牌

洗地机作为一种高效、节能、环保、卫生的清洁设备,不仅能够提升清洁效率,还能有效减少清洁成本,更重要的是,它可以帮助我们创造一个更加健康和舒适的生活环境。而且除菌方面大部分都是采用电解水的除菌方式,更加环保和…

【我的创作纪念日—5周年】

序言 用心生活,用力向上,微笑前行,就是对生活最好的回馈。 机缘 最开始写文章,没想那么多,主要是记录一下,就随便写了下,后来认识了一些写文章的小伙伴,在和他们的沟通中越来越体会到…

PACS/RIS影像管理系统源码,采用VC++编程语言,提供三维图像后处理和算法

PACS/RIS影像管理系统源码 医学影像管理(PACS/RIS)系统是一套完整的提供DICOM标准遵从、高效的实现医学影像归档存储、通讯和诊断处理功能的医学影像信息管理系统,其基于DICOM/HL7标准的开放性架构和模块化的结构体系,确保了系统…

自动驾驶就是在扯?比亚迪你凭什么?

比亚迪“炮轰”自动驾驶 上周,在比亚迪2022年财报交流会上,有投资人问比亚迪在自动驾驶方面的发展进度和规划,比亚迪集团董事长王传福直言:“无人驾驶那都是扯淡,弄个虚头巴脑的东西那都是忽悠,它就是一场皇…

【超算/先进计算学习】日报4

目录 今日已完成任务列表遇到的问题及解决方案任务完成详细笔记高性能算法计算机算法的特征及内涵科学计算算法的主要分类高性能算法与传统算法的异同稀疏矩阵向量乘法 SpMV 与稀疏矩阵存储结构常见的稀疏矩阵传统存储与其SpMV算法不同的稀疏矩阵传统存储结构存储效率与稀疏度针…

Linux进程概念及状态

Linux进程概念及进程状态 目录 Linux进程概念及进程状态引入1、什么是进程1.1 描述进程1.2 task_struct组织进程1.3 proc目录 2、进程标识符3、查看进程4、bash进程5、初始fork6、进程状态6.1 操作系统层面6.2 Linux内核源代码RSDX 6.3 僵尸进程6.4 孤儿进程关于kill指令 引入 …

nssctf web 入门(9)

[SWPUCTF 2021 新生赛]sql [SWPUCTF 2021 新生赛]sql 可以猜测做了过滤 这里可以bp跑一下看过滤了哪些 尝试发现过滤了空格/**/在sql中代表注释符在mysql中这个可以用来代表空格 发现--被过滤 #也不行我们试下url编码的#也就是%23 成功了 3个字段 得到库名test_db 这里提示非…

一篇文章让你彻底学会--防抖(并且自己可以手写)

Hi,有的小伙伴们在面试的时候会被要求手写防抖函数,很多都被难着了吧,宝贝,那你你没有理解防抖函数。 今天,就让我带你攻克它! 1.防抖 防抖:单位时间内,频繁触发事件,只执行最后一次。 人话:说…

嵌入式Linux(1):make menuconfig图形化界面

文章目录 搜索功能配置驱动状态退出和make menuconfig有关的三个文件make menuconfig会读取哪个目录下的Kconfig文件?为什么要复制成.config而不复制成其他的文件呢?在默认的deconfig上面通过make menuconfig来改配置,然后保存怎么和Makefile…

门店智能经营平台能解决哪些问题?应该如何选购?

现在很多实体店都开始借助第三方软件或系统,来为自家门店搭建门店智能经营平台,来智能管理自家门店的商品和库存,提高门店运营效率。 一、使用门店智能经营平台能解决哪些难题? 1、实现数据化决策 通过门店智能经营平台&#xff…