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


    本代码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键。

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

  • 相关阅读:
    docker学习-docker核心技术
    Ecmall 中国地区设置
    lazyload.js实现图片异步载入
    inpyt 按钮变透明 边框
    vertical-align0 垂直对齐- 图片 兼容个浏览器
    div文字超出
    jquery满屏滚动代码
    $().index() 两种用法
    setTimeout不断重复执行
    background属性
  • 原文地址:https://www.cnblogs.com/yanghailin/p/16213432.html
Copyright © 2020-2023  润新知