• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Python图片处理之图片裁剪教程

    一、操作流程

    首先复制代码会吧?

    1.有张照片

    这是网上随便找的一张照片,自行保存测试

    2.看看照片

    运行代码,其中show_img函数是展示照片

    3.选择角点

    按照左上,右上,右下,左下的顺序选择四个角点

    如果担心自己选不好,可以直接去除我代码里的points的注释,那是我自己用的原版

    4.最终结果

    二、代码分析

    import 没什么好说的

    #如果python没有安装cv2,那么就安装python-opencv就好
    import cv2 as cv
    import 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 cv
    import 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  result
    
    
    if __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图片裁剪内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

    您可能感兴趣的文章:
    • Python图像处理之图片拼接和堆叠案例教程
    • python图片灰度化处理的几种方法
    • Python图像处理之图像拼接
    • Python图片检索之以图搜图
    • python图片合成的示例
    • 昨晚我用python帮隔壁小姐姐P证件照然后发现
    上一篇:用Python进行栅格数据的分区统计和批量提取
    下一篇:用Python监控你的朋友都在浏览哪些网站?
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    Python图片处理之图片裁剪教程 Python,图片,处理,之,裁剪,