今天看啥  ›  专栏  ›  LaoYuanPython

狗狗变形记:任选4点的投影变换warpPerspective OpenCV-Python案例

LaoYuanPython  · CSDN  ·  · 2021-02-23 08:15

☞ ░ 老猿Python博文目录:https://blog.csdn.net/LaoYuanPython

仿射变换博文传送门(带星号的为付费专栏文章):
  1. *图像仿射变换原理1:齐次坐标来龙去脉详解
  2. *图像仿射变换原理2:矩阵变换、线性变换和图像线性变换矩阵
  3. *图像仿射变换原理3:仿射变换类型及变换矩阵详解
  4. *图像仿射变换原理4:组合变换及对应变换矩阵
  5. *图像仿射变换原理5:组合变换矩阵的OpenCV-Python实现
  6. OpenCV-Python图像处理:仿射变换详解及案例
  7. OpenCV-Python仿射变换开发中遇到的坑
  8. openCV仿射变换:getAffineTransform的案例
  9. 为什么称图像旋转、错切、缩放变换是线性变换?
  10. 图像仿射变换:绕点旋转和指定直线依赖轴shear错切变换矩阵
  11. 图像仿射变换shear怎么翻译?剪切、错切、推移哪个译词好?
  12. 仿射变换原理和其OpenCV-Python实现知识汇总
狗狗变形记:任选4点的投影变换warpPerspective案例

一、引言

在《 https://blog.csdn.net/LaoYuanPython/article/details/113924512 openCV仿射变换:getAffineTransform的案例 》我们介绍了任选三个点使用getAffineTransform获取仿射矩阵进行图像仿射变换,这节我们来选择四个点进行投影变换。

二、案例说明

2.1、输入图像

图像文件名: f:\pic\dogandcat.JPG
在这里插入图片描述

2.2、功能说明

在图像上依次选择四个点,分别对应结果图像的左上、右上、左下、右下四个点,将这两组点作为参数使用getPerspectiveTransform获得投影变换(又称为透视变换)矩阵,然后调用warpPerspective进行投影变换。

三、示例代码

import cv2
import numpy as np

def OnMouseEvent( event, x, y, flags, param):
    global lbtDownPos
    global pos
    global pointList
    img = param
    ignoreEvent = [cv2.EVENT_MBUTTONDOWN, cv2.EVENT_MBUTTONUP, cv2.EVENT_MBUTTONDBLCLK, cv2.EVENT_MOUSEWHEEL,
                        cv2.EVENT_MOUSEHWHEEL,cv2.EVENT_MOUSEMOVE,cv2.EVENT_LBUTTONDBLCLK, cv2.EVENT_RBUTTONDBLCLK, cv2.EVENT_RBUTTONDOWN, cv2.EVENT_RBUTTONUP]  # 需要忽略的鼠标事件
    needRecordEvent = [ cv2.EVENT_LBUTTONDOWN, cv2.EVENT_LBUTTONUP]  # 需要记录当前信息的鼠标事件

    if event == cv2.EVENT_LBUTTONUP:
        pos = (x,y)
        print("OnMouseEvent EVENT_LBUTTONUP:",pos)
        n = len(pointList)
        if pos==lbtDownPos:
            n += 1
            if n <= 4:
                pointList.append(pos)
                cv2.putText(img, '.', (x-15, y+3), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=3, color=(255, 0, 0)) #坐标调整是因为点放大了占用了不止一个像素
                cv2.circle(img,(x , y),10,(0,0,255))
                cv2.putText(img, f'select point{n}:({x},{y})', (x + 20, y), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=0.3, color=(255, 0, 0))

        lbtDownPos = None

    elif event == cv2.EVENT_LBUTTONDOWN:
        lbtDownPos = (x,y)
        print("OnMouseEvent EVENT_LBUTTONDOWN:", lbtDownPos)

    else:lbtDownPos = None



def getPoint(imgfile):
    global pos
    global pointList

    pointList = []
    img = cv2.imread(imgfile)
    img = cv2.resize(img,None,fx=0.5,fy=0.5)
    cv2.putText(img, 'https://blog.csdn.net/LaoYuanPython', (100, 120), fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=0.5, color=(255, 0, 0))
    imgbak = np.array(img)
    rows,cols = img.shape[:2]
    winName = 'select 4 points'
    cv2.namedWindow(winName)
    cv2.setMouseCallback(winName, OnMouseEvent, img)
    print("请将要单独放大的部分从其左上角、右上角、左下角、右下角分别鼠标左键点击选择4个点,选择后在图像上有提示信息,选择完成后按ESC退出")


    while True:#通过鼠标左键点击选择4个点,分别代表要映射到左上角、右上角、左下角、右下角4个点
        cv2.imshow(winName, img)
        ch = cv2.waitKey(100)
        if ch == 27: break

    destPoint = [(0,0),(cols,0),(0,rows),(cols,rows)]
    if len(pointList)==4:
        pts1 = np.float32(pointList)
        pts2 = np.float32(destPoint)
        M = cv2.getPerspectiveTransform(pts1, pts2)
        dst = cv2.warpPerspective(imgbak, M, (cols, rows))
        cv2.imshow(winName, dst)
        ch = cv2.waitKey(0)
    else:
        print("没有选择足够的点")

getPoint(r'f:\pic\dogandcat.JPG')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

四、运行截图

选择4个点后的图像

下图中的红色圈标记的4个蓝点就是通过鼠标左键点击选择的4个点:
在这里插入图片描述
按ESC键退出。

投影变换后的图像

下图是投影变换后的狗狗图像:
在这里插入图片描述

五、小结

本节介绍了使用OpenCV-Python的getPerspectiveTransform函数,通过4个源图像的点映射到目标图像的四角对应点得到投影变换的变换矩阵,然后使用warpPerspective进行投影变换,可以对选择4个点进行投影变换的步骤有清晰的理解。

更多图像处理的介绍请参考专栏《 OpenCV-Python图形图像处理 https://blog.csdn.net/laoyuanpython/category_9979286.html 》和《 https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集 》相关文章。

更多图像处理的数学基础知识请参考专栏《 人工智能数学基础 https://blog.csdn.net/laoyuanpython/category_10382948.html

写博不易,敬请支持:

如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

参考资料

  1. [Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移

关于老猿的付费专栏

  1. 付费专栏《 https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt开发图形界面Python应用》 专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt开发图形界面Python应用专栏目录 》;
  2. 付费专栏《 https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音视频开发专栏 )详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音视频开发专栏文章目录 》;
  3. 付费专栏《 https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集 》为《 https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初学者疑难问题集专栏目录
  4. 付费专栏《 https://blog.csdn.net/laoyuanpython/category_10762553.html Python爬虫入门 》 站在一个互联网前端开发小白的角度介绍爬虫开发应知应会内容,包括爬虫入门的基础知识,以及爬取CSDN文章信息、博主信息、给文章点赞、评论等实战内容。

前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《 https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《 https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录 )从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python!

☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython




原文地址:访问原文地址
快照地址: 访问文章快照