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


Posted in Python onMay 27, 2021

一、操作流程

首先复制代码会吧?

1.有张照片

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

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

2.看看照片

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

3.选择角点

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

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

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

4.最终结果

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

二、代码分析

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写的PHPMyAdmin暴力破解工具代码
Aug 06 Python
简单的Python的curses库使用教程
Apr 11 Python
Python中将字典转换为XML以及相关的命名空间解析
Oct 15 Python
Windows下使Python2.x版本的解释器与3.x共存的方法
Oct 25 Python
详解JavaScript编程中的window与window.screen对象
Oct 26 Python
Django框架文件上传与自定义图片上传路径、上传文件名操作分析
May 10 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
Aug 01 Python
基于YUV 数据格式详解及python实现方式
Dec 09 Python
基于Django实现日志记录报错信息
Dec 17 Python
Tensorflow 实现将图像与标签数据转化为tfRecord文件
Feb 17 Python
使用python-cv2实现视频的分解与合成的示例代码
Oct 26 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
Jan 07 Python
用Python进行栅格数据的分区统计和批量提取
手把手教你怎么用Python实现zip文件密码的破解
Python基础学习之奇异的GUI对话框
教你使用pyinstaller打包Python教程
Matplotlib绘制混淆矩阵的实现
只需要100行Python代码就可以实现的贪吃蛇小游戏
PyTorch dropout设置训练和测试模式的实现
May 27 #Python
You might like
php中计算时间差的几种方法
2009/12/31 PHP
支持数组的ADDSLASHES的php函数
2010/02/16 PHP
解析php中const与define的应用区别
2013/06/18 PHP
javascript HTMLEncode HTMLDecode的完整实例(兼容ie和火狐)
2009/06/02 Javascript
深入领悟JavaScript中的面向对象
2013/11/18 Javascript
10条建议帮助你创建更好的jQuery插件
2015/05/18 Javascript
浅谈JS读取DOM对象(标签)的自定义属性
2016/11/21 Javascript
使用Bootrap和Vue实现仿百度搜索功能
2017/10/26 Javascript
微信小程序实战篇之购物车的实现代码示例
2017/11/30 Javascript
浅谈React高阶组件
2018/03/28 Javascript
vue-cli构建项目下使用微信分享功能
2018/05/28 Javascript
微信小程序使用wxParse解析html的方法教程
2018/07/06 Javascript
js实现简单选项卡功能
2020/03/23 Javascript
新手如何快速理解js异步编程
2019/06/24 Javascript
WEEX环境搭建与入门详解
2019/10/16 Javascript
详解Webpack4多页应用打包方案
2020/07/16 Javascript
[05:40]DOTA2荣耀之路6:Wings最后进攻
2018/05/30 DOTA
使用python3+xlrd解析Excel的实例
2018/05/04 Python
解决pycharm py文件运行后停止按钮变成了灰色的问题
2018/11/29 Python
Python之列表实现栈的工作功能
2019/01/28 Python
Python常用特殊方法实例总结
2019/03/22 Python
python把转列表为集合的方法
2019/06/28 Python
python实现微信自动回复及批量添加好友功能
2019/07/03 Python
利用python list完成最简单的DB连接池方法
2019/08/09 Python
python基于socket实现的UDP及TCP通讯功能示例
2019/11/01 Python
python实现根据给定坐标点生成多边形mask的例子
2020/02/18 Python
Python通过正则库爬取淘宝商品信息代码实例
2020/03/02 Python
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
英国乐购杂货:Tesco Groceries
2018/11/29 全球购物
银行实习生的自我评价
2014/01/13 职场文书
捐书活动总结
2014/05/04 职场文书
美术课外活动总结
2014/07/08 职场文书
优秀应届本科生求职信
2014/07/19 职场文书
python通过opencv调用摄像头操作实例分析
2021/06/07 Python
Jackson 反序列化时实现大小写不敏感设置
2021/06/29 Java/Android
Apache Hudi的多版本清理服务彻底讲解
2022/03/31 Servers