这篇教程Python图片处理之图片裁剪教程写得很实用,希望能帮到您。
一、操作流程首先复制代码会吧? 1.有张照片 这是网上随便找的一张照片,自行保存测试 
2.看看照片 运行代码,其中show_img函数是展示照片 3.选择角点 按照左上,右上,右下,左下的顺序选择四个角点 
如果担心自己选不好,可以直接去除我代码里的points的注释,那是我自己用的原版 4.最终结果 
二、代码分析import 没什么好说的 #如果python没有安装cv2,那么就安装python-opencv就好import cv2 as cvimport numpy as np 获取图片的长宽 #输入cv.imread后的图片,通过点击四个点选择要裁剪的部分def get_window_size(src, bound=600): h,w = src.shape[0], src.shape[1] if h > w: h, w = bound, int(w*bound/h) else: h, w = int(h*bound/w), bound return (h, w) 通过鼠标获取图片的坐标点,顺序是左上,右上,右下,左下 class Indexer: def __init__(self, bound=4): self.id = 0 self.bound = bound def get_id(self): self.id = (self.id + 1) return (self.id)def on_EVENT_LBUTTONDOWN(event, x, y, flags, param): if event == cv.EVENT_LBUTTONDOWN: img = param['src'] win_name = param['window'] indexer = param['indexer'] points = param['points'] curr_id = indexer.get_id() points.append((x, y)) print('第{}个顶点: ({},{})'.format(curr_id, x, y)) cv.circle(img, (x, y), 10, (0, 0, 255), thickness=2) cv.putText( img, str(curr_id), # 文字 (x, y), # 坐标 cv.FONT_HERSHEY_PLAIN, 5, # 字号 (0, 0, 255), # 字体颜色 thickness=2 # 粗细 ) cv.imshow(win_name, img)#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分def get_points(src): points = [] indexer = Indexer() h, w=get_window_size(src) win_name = 'get_points' cv.namedWindow(win_name, cv.WINDOW_NORMAL) cv.resizeWindow(win_name, width=w, height=h) cv.imshow(win_name, src) cv.setMouseCallback(win_name, on_EVENT_LBUTTONDOWN, param={'src': src, 'window': win_name, 'indexer': indexer, 'points': points}) cv.waitKey(0) cv.destroyAllWindows() if len(points)>4: return points[0:4] # print(points) # points=[(2, 14), (90, 50), (87, 194), (1, 204)] return points#输入cv.imread后的图片,展示图片长什么样def show_img(src): win_name = 'show_img' h, w=get_window_size(src) cv.namedWindow(win_name, cv.WINDOW_NORMAL) cv.resizeWindow(win_name, width=w, height=h) cv.imshow(win_name, src) cv.waitKey(0) cv.destroyAllWindows() 将图片截取,并按照指定的长宽比恢复成矩形 def photo_cut_restore(src,points,H,W): target_points = [(0, 0), (W, 0), (W, H), (0, H)] points, target_points = np.array(points, dtype=np.float32), np.array(target_points, dtype=np.float32) M = cv.getPerspectiveTransform(points, target_points) # print('透视变换矩阵:', M) result = cv.warpPerspective(src_copy, M, (0, 0)) result = result[:H, :W] win_name = 'Result' cv.namedWindow(win_name, cv.WINDOW_NORMAL) cv.resizeWindow(win_name, width=W, height=H) cv.imshow(win_name,result) cv.waitKey(0) cv.destroyAllWindows() return result 主程序 if __name__ == '__main__': path = './1.jpg' src = cv.imread(path) src_copy = src.copy() show_img(src) W = 20 H = 20 # points=[(112, 308), (175, 310), (176, 369), (113, 369)] points=get_points(src) n = 20 W = int(W * n) H = int(H * n) result=photo_cut_restore(src_copy,points,H,W) output_file = 'result.jpg' cv.imwrite(output_file, result)
三、懒人一键复制代码诶,气不气,好不容易一段段复制完,结果最后居然有一键复制的地方 import cv2 as cvimport numpy as np#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分def get_window_size(src, bound=600): h,w = src.shape[0], src.shape[1] if h > w: h, w = bound, int(w*bound/h) else: h, w = int(h*bound/w), bound return (h, w)class Indexer: def __init__(self): self.id = 0 def get_id(self): self.id = (self.id + 1) return (self.id)def on_EVENT_LBUTTONDOWN(event, x, y, flags, param): if event == cv.EVENT_LBUTTONDOWN: img = param['src'] win_name = param['window'] indexer = param['indexer'] points = param['points'] curr_id = indexer.get_id() points.append((x, y)) print('第{}个顶点: ({},{})'.format(curr_id, x, y)) cv.circle(img, (x, y), 10, (0, 0, 255), thickness=2) cv.putText( img, str(curr_id), # 文字 (x, y), # 坐标 cv.FONT_HERSHEY_PLAIN, 5, # 字号 (0, 0, 255), # 字体颜色 thickness=2 # 粗细 ) cv.imshow(win_name, img)#输入cv.imread后的图片,通过点击四个点选择要裁剪的部分def get_points(src): points = [] indexer = Indexer() h, w=get_window_size(src) win_name = 'get_points' cv.namedWindow(win_name, cv.WINDOW_NORMAL) cv.resizeWindow(win_name, width=w, height=h) cv.imshow(win_name, src) cv.setMouseCallback(win_name, on_EVENT_LBUTTONDOWN, param={'src': src, 'window': win_name, 'indexer': indexer, 'points': points}) cv.waitKey(0) cv.destroyAllWindows() if len(points)>4: return points[0:4] # print(points) # points=[(2, 14), (90, 50), (87, 194), (1, 204)] return points#输入cv.imread后的图片,展示图片长什么样def show_img(src): win_name = 'show_img' h, w=get_window_size(src) cv.namedWindow(win_name, cv.WINDOW_NORMAL) cv.resizeWindow(win_name, width=w, height=h) cv.imshow(win_name, src) cv.waitKey(0) cv.destroyAllWindows()def photo_cut_restore(src,points,H,W): target_points = [(0, 0), (W, 0), (W, H), (0, H)] points, target_points = np.array(points, dtype=np.float32), np.array(target_points, dtype=np.float32) M = cv.getPerspectiveTransform(points, target_points) # print('透视变换矩阵:', M) result = cv.warpPerspective(src_copy, M, (0, 0)) result = result[:H, :W] win_name = 'Result' cv.namedWindow(win_name, cv.WINDOW_NORMAL) cv.resizeWindow(win_name, width=W, height=H) cv.imshow(win_name,result) cv.waitKey(0) cv.destroyAllWindows() return resultif __name__ == '__main__': path = './3.jpg' src = cv.imread(path) src_copy = src.copy() # show_img(src) W = 20 H = 20 # points=[(124, 182), (181, 177), (180, 243), (125, 266)] points=get_points(src) print(points) n = 20 W = int(W * n) H = int(H * n) result=photo_cut_restore(src_copy,points,H,W) output_file = 'result.jpg' cv.imwrite(output_file, result) 到此这篇关于Python图片处理之图片裁剪教程的文章就介绍到这了,更多相关Python图片裁剪内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net! 用Python进行栅格数据的分区统计和批量提取 用Python监控你的朋友都在浏览哪些网站? |