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利用dir函数查看类中所有成员函数示例代码
Sep 08 Python
Python实现学校管理系统
Jan 11 Python
详解Python locals()的陷阱
Mar 26 Python
Python数据类型之String字符串实例详解
May 08 Python
python每5分钟从kafka中提取数据的例子
Dec 23 Python
pycharm 设置项目的根目录教程
Feb 12 Python
jupyternotebook 撤销删除的操作方式
Apr 17 Python
Python基于字典实现switch case函数调用
Jul 22 Python
python利用线程实现多任务
Sep 18 Python
如何基于Python爬虫爬取美团酒店信息
Nov 03 Python
Python系统公网私网流量监控实现流程
Nov 23 Python
python中的plt.cm.Paired用法说明
May 31 Python
用Python进行栅格数据的分区统计和批量提取
手把手教你怎么用Python实现zip文件密码的破解
Python基础学习之奇异的GUI对话框
教你使用pyinstaller打包Python教程
Matplotlib绘制混淆矩阵的实现
只需要100行Python代码就可以实现的贪吃蛇小游戏
PyTorch dropout设置训练和测试模式的实现
May 27 #Python
You might like
PHP 编程安全性小结
2010/01/08 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
PHP输出数组中重名的元素的几种处理方法
2012/09/05 PHP
PHP中使用循环实现的金字塔图形
2014/11/08 PHP
PHP冒泡算法详解(递归实现)
2014/11/10 PHP
php将数组转换成csv格式文件输出的方法
2015/03/14 PHP
PHP水印类,支持添加图片、文字、填充颜色区域的实现
2017/02/04 PHP
javascript onkeydown,onkeyup,onkeypress,onclick,ondblclick
2009/02/04 Javascript
jMessageBox 基于jQuery的窗口插件
2009/12/09 Javascript
jquery隐藏标签和显示标签的实例
2013/11/11 Javascript
解释&&和||在javascript中的另类用法
2014/07/28 Javascript
jquery访问ashx文件示例代码
2014/08/11 Javascript
JavaScript数组常用操作技巧汇总
2014/11/17 Javascript
基于Node.js的强大爬虫 能直接发布抓取的文章哦
2016/01/10 Javascript
关于input全选反选恶心的异常情况
2016/07/24 Javascript
微信小程序 免费SSL证书https、TLS版本问题的解决办法
2016/12/14 Javascript
codeMirror插件使用讲解
2017/01/16 Javascript
使用JavaScriptCore实现OC和JS交互详解
2017/03/28 Javascript
JS传参及动态修改页面布局
2017/04/13 Javascript
javascript中神奇的 Date对象小结
2017/10/12 Javascript
通过JavaScript下载文件到本地的方法(单文件)
2019/03/17 Javascript
微信小程序自定义单项选择器样式
2019/07/25 Javascript
vuex实现数据状态持久化
2019/11/11 Javascript
Vue中el-form标签中的自定义el-select下拉框标签功能
2020/04/20 Javascript
js+audio实现音乐播放器
2020/09/13 Javascript
在vue中使用image-webpack-loader实例
2020/11/12 Javascript
[01:06:39]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第三局
2016/03/02 DOTA
[01:54]TI珍贵瞬间系列(五):压力
2020/08/29 DOTA
Django Admin后台添加数据库视图过程解析
2020/04/01 Python
浅析python 动态库m.so.1.0错误问题
2020/05/09 Python
建筑专业自我鉴定
2013/10/22 职场文书
教师个人鉴定材料
2014/02/08 职场文书
高考励志标语
2014/06/05 职场文书
幼儿园老师新年寄语2015
2014/12/08 职场文书
2015迎新晚会活动总结
2015/07/16 职场文书
2016年乡镇综治宣传月活动总结
2016/03/16 职场文书