在《https://blog.csdn.net/LaoYuanPython/article/details/113924512 openCV仿射变换:getAffineTransform的案例》我们介绍了任选三个点使用getAffineTransform获取仿射矩阵进行图像仿射变换,这节我们来选择四个点进行投影变换。
在图像上依次选择四个点,分别对应结果图像的左上、右上、左下、右下四个点,将这两组点作为参数使用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')
下图中的红色圈标记的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》
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!
参考资料:
前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。
对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。
如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。