• 仿射变换随机在大图上面截取小图


    本代码python opencv运行,用鼠标在原图上面依次左击点三个点,左上,左下,右下。然后设定固定窗口大小,比如384128大小。
    就是把在原图上面点击的三个点映射到384
    128大小图像上来。不管你原图选中多大面积的图像都会映射到我们设定的大小上面来。
    这里就是仿射变换的原理映射。通过三对点映射关系求得仿射变换矩阵。然后通过矩阵来弄图像。
    这里需要注意的是大图上面的点可以映射到截取的小图上面,同样的,小图上面的点也可以映射到大图上!
    下面代码就是:

    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_LBUTTONDOWN:
            pos = (x,y)
            print("---1 pos 》OnMouseEvent EVENT_LBUTTONDOWN:",pos)
            n = len(pointList)
            if True:
                if len(pointList) <= 3:
                    pointList.append(pos)
                    cv2.putText(img, '.', (x - 10, y), fontFace=cv2.FONT_HERSHEY_SIMPLEX, fontScale=3, color=(255, 0, 0))
                    cv2.putText(img, f'select point{n}:({x},{y})', (x + 20, y), fontFace=cv2.FONT_HERSHEY_SIMPLEX,
                                fontScale=0.3, color=(255, 0, 0))
    
    def getPoint(imgfile):
        global pos
        global pointList
    
        pointList = []
        img = cv2.imread(imgfile)
        cv2.putText(img, 'https://www.cnblogs.com/yanghailin/', (100, 120), fontFace=cv2.FONT_HERSHEY_SIMPLEX,fontScale=0.5, color=(255, 0, 0))
        imgbak = np.array(img)
        rows,cols = img.shape[:2]
    
        rows = 128
        cols = 384
    
        winName = 'select three point'
        cv2.namedWindow(winName)
        cv2.setMouseCallback(winName, OnMouseEvent, img)
        print("请将要单独放大的部分从其左上角、左下角、右下角分别鼠标左键点击选择三个点,选择后在图像上有提示信息,选择完成后按ESC退出")
    
    
        while True:#通过鼠标左键点击选择三个点,分别代表要映射到左上、左下和右下三个点
            cv2.imshow(winName, img)
            ch = cv2.waitKey(100)
            if ch == 27: break
    
        destPoint = [(0,0),(0,rows),(cols,rows)]
        if len(pointList)==3:
            pts1 = np.float32(pointList)
            pts2 = np.float32(destPoint)
            M = cv2.getAffineTransform(pts1, pts2)
            print("=========M===========")
            print(M)
            dst = cv2.warpAffine(imgbak, M, (cols, rows))
    
            # b = np.array([cols/2,rows/2,1])
            # b = np.array([rows / 2, cols / 2, 1])
    
            b = np.array([1760 / 2 + 100, 540 / 2 + 40, 1])
            a = np.matmul(M,b)  #a = M * b      img384 = M * img1760   --->大图映射到小图
            cv2.circle(imgbak, (int(b[0]), int(b[1])), 8, (0, 255, 255), -1)
            cv2.circle(dst, (int(a[0]), int(a[1])), 4, (0, 255, 255), -1)
    
            # M_i = []
            M_i = cv2.invertAffineTransform(M)
            b = np.array([384 / 2 + 0, 128 / 2 + 0, 1])
            a = np.matmul(M_i, b)  # a = M * b      img1760 = M * img384   --->小图映射到大图
    
            cv2.circle(dst,(int(b[0]),int(b[1])),8,(255,0,0),-1)
            cv2.circle(imgbak, (int(a[0]),int(a[1])), 12, (255, 0, 0), -1)
    
            cv2.imshow(winName, dst)
            cv2.imshow("src", imgbak)
            ch = cv2.waitKey(0)
        else:
            print("没有选择足够的点")
    
    
    getPoint("/data_1/1.jpeg")
    

    鼠标左击分别点左上,左下,右下。然后按esc键。

    下图可以看到我们在原图上面设定的点可以正确映射到小图,反之也是可以。都能对应上。

  • 相关阅读:
    haproxy tcp 反向代理
    c# 字节高低位
    Mac Launchpad图标调整
    vsftp 777权限
    centos7下tomcat7 或tomcat8启动超慢原因
    mysql连接com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link
    Mac mysql 运行sql文件中文乱码的问题
    Mac Mysql [ERR] 2006
    记一次部署java项目的问题
    典型的响应式布局实例代码
  • 原文地址:https://www.cnblogs.com/yanghailin/p/16213432.html
Copyright © 2020-2023  润新知