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中的数据对象持久化存储模块pickle的使用示例
Mar 03 Python
在Python中使用AOP实现Redis缓存示例
Jul 11 Python
python利用正则表达式搜索单词示例代码
Sep 24 Python
用pandas中的DataFrame时选取行或列的方法
Jul 11 Python
python使用webdriver爬取微信公众号
Aug 31 Python
对Python的交互模式和直接运行.py文件的区别详解
Jun 29 Python
利用pyecharts实现地图可视化的例子
Aug 12 Python
Django中间件拦截未登录url实例详解
Sep 03 Python
Django框架 querySet功能解析
Sep 04 Python
在 Python 中使用 7zip 备份文件的操作
Dec 11 Python
python 基于selenium实现鼠标拖拽功能
Dec 24 Python
Python first-order-model实现让照片动起来
Jun 25 Python
用Python进行栅格数据的分区统计和批量提取
手把手教你怎么用Python实现zip文件密码的破解
Python基础学习之奇异的GUI对话框
教你使用pyinstaller打包Python教程
Matplotlib绘制混淆矩阵的实现
只需要100行Python代码就可以实现的贪吃蛇小游戏
PyTorch dropout设置训练和测试模式的实现
May 27 #Python
You might like
php使用curl简单抓取远程url的方法
2015/03/13 PHP
PHP中foreach()用法汇总
2015/07/02 PHP
php正则表达式学习笔记
2015/11/13 PHP
关于ThinkPhp 框架表单验证及ajax验证问题
2017/07/19 PHP
PHP实现本地图片转base64格式并上传
2020/05/29 PHP
Javascript & DHTML 实例编程(教程)DOM基础和基本API
2007/06/02 Javascript
jQuery实现的立体文字渐变效果
2010/05/17 Javascript
js解析xml字符串和xml文档实现原理及代码(针对ie与火狐)
2013/02/02 Javascript
js replace 与replaceall实例用法详解
2013/08/03 Javascript
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
2014/02/13 Javascript
jQuery实现简单下拉导航效果
2015/09/07 Javascript
JS+CSS实现闪烁字体效果代码
2016/04/05 Javascript
BootStrap中的表单大全
2016/09/07 Javascript
深入理解Angularjs中的$resource服务
2016/12/31 Javascript
Bootstrap表单控件使用方法详解
2017/01/11 Javascript
angular实现商品筛选功能
2017/02/01 Javascript
JQuery form表单提交前验证单选框是否选中、删除记录时验证经验总结(整理)
2017/06/09 jQuery
python下如何让web元素的生成更简单的分析
2008/07/17 Python
Python中几种导入模块的方式总结
2017/04/27 Python
决策树剪枝算法的python实现方法详解
2019/09/18 Python
使用Python paramiko模块利用多线程实现ssh并发执行操作
2019/12/05 Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
2020/08/07 Python
python打包生成so文件的实现
2020/10/30 Python
python 读取串口数据的示例
2020/11/09 Python
10 套华丽的CSS3 按钮小结
2012/10/03 HTML / CSS
限量版运动鞋和街头服饰:TheDrop
2020/09/06 全球购物
实习期自我鉴定
2013/10/11 职场文书
办公室年终个人自我评价
2013/10/28 职场文书
仓库理货员岗位职责
2013/12/18 职场文书
自荐信写法介绍
2014/01/25 职场文书
团拜会策划方案
2014/06/07 职场文书
房屋租赁委托书范本
2014/10/04 职场文书
2014年幼儿园保育工作总结
2014/12/02 职场文书
化验室岗位职责
2015/02/14 职场文书
小学教师教学反思
2016/02/24 职场文书
JAVA SpringMVC实现自定义拦截器
2022/03/16 Python