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进阶教程之循环相关函数range、enumerate、zip
Aug 30 Python
python迭代器实例简析
Sep 25 Python
Python检测生僻字的实现方法
Oct 23 Python
Python中的pygal安装和绘制直方图代码分享
Dec 08 Python
Python中xrange与yield的用法实例分析
Dec 26 Python
python正则表达式面试题解答
Apr 28 Python
用Django实现一个可运行的区块链应用
Mar 08 Python
python抓取网站的图片并下载到本地的方法
May 22 Python
使用Python打造一款间谍程序的流程分析
Feb 21 Python
基于matplotlib中ion()和ioff()的使用详解
Jun 16 Python
python3中for循环踩过的坑记录
Dec 14 Python
python requests模块的使用示例
Apr 07 Python
用Python进行栅格数据的分区统计和批量提取
手把手教你怎么用Python实现zip文件密码的破解
Python基础学习之奇异的GUI对话框
教你使用pyinstaller打包Python教程
Matplotlib绘制混淆矩阵的实现
只需要100行Python代码就可以实现的贪吃蛇小游戏
PyTorch dropout设置训练和测试模式的实现
May 27 #Python
You might like
全国FM电台频率大全 - 15 山东省
2020/03/11 无线电
PHP扩展模块memcached长连接使用方法分析
2014/12/24 PHP
php通过修改header强制图片下载的方法
2015/03/24 PHP
php getcwd与dirname(__FILE__)区别详解
2016/09/24 PHP
PHP实现防盗链的方法分析
2017/07/25 PHP
PHP中echo与print区别点整理
2021/03/09 PHP
Ext.MessageBox工具类简介
2009/12/10 Javascript
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
用jquery模仿的a的title属性的例子
2014/10/22 Javascript
Javascript中call和apply函数的比较和使用实例
2015/02/03 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
2015/08/31 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
浅谈react 同构之样式直出
2017/11/07 Javascript
vue实现在一个方法执行完后执行另一个方法的示例
2018/08/25 Javascript
JS document对象简单用法完整示例
2020/01/14 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
python错误:AttributeError: 'module' object has no attribute 'setdefaultencoding'问题的解决方法
2014/08/22 Python
Windows下安装python MySQLdb遇到的问题及解决方法
2017/03/16 Python
pandas 透视表中文字段排序方法
2018/11/16 Python
django 信号调度机制详解
2019/07/19 Python
python获取全国城市pm2.5、臭氧等空气质量过程解析
2019/10/12 Python
Python之——生成动态路由轨迹图的实例
2019/11/22 Python
Python&&GDAL实现NDVI的计算方式
2020/01/09 Python
大四自我鉴定范文
2013/10/06 职场文书
施工资料员的岗位职责
2013/12/22 职场文书
2014年应届大学生毕业自我鉴定
2014/01/31 职场文书
工作时间上网检讨书
2014/02/03 职场文书
企业内控岗位的职责
2014/02/07 职场文书
导购员的岗位职责
2014/02/08 职场文书
个人实习生的自我评价
2014/02/16 职场文书
给学校建议书范文
2014/05/13 职场文书
大学计划书范文800字
2014/08/14 职场文书
2014年学校国庆主题活动方案
2014/09/16 职场文书
安全月宣传标语
2014/10/07 职场文书
Python打包为exe详细教程
2021/05/18 Python