Python图片处理之图片裁剪教程
作者:怪皮蛇皮怪 发布时间:2022-02-02 06:32:40
标签: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)
来源:https://blog.csdn.net/weixin_43958086/article/details/117250288


猜你喜欢
- 实例如下所示:# -*- coding:utf-8 -*- #os模块中包含很多操作文件和目录的函数 import os #获取目标文件夹的
- pandas获取csv指定行,列house_info = pd.read_csv('house_info.csv')1:取行
- 目录文件读写读文件写文件StringIO和BytesIOStringIOBytesIO操作文件和目录环境变量操作文件和目录文件读写读文件tr
- 1、安装类库pip install pyautogui2、代码:import pyautogui,time,randompyautogui.
- 最近github上开源了一个"新语言"vlang,火的不得了,我不信,于是乎,尝试了一下,真香。以下内存均来自https
- 注:以下所有操作都在CentOS 6.5 x86_64位系统下完成。#准备工作#在安装MySQL之前,请确保已经使用yum安装了以下各类基础
- 问题:自己写了个dataloader,为了部署方便,用OpenCV的接口进行数据读取,而没有用PIL,代码大致如下: &nbs
- 左右结构是平常页面中最经常看到的结构,简洁一些的页面就会使用边框将左右两边隔开,但往往由于左右两边的内容可能是不等高的,所以就会有一高一低的
- 今天看到了这个文章感觉内容挺多的,就是比较乱,实在不好整理,脚本之家小编就简单整理了一下,希望大家能凑合看吧分组后分组合计以及总计SQL语句
- 本文实例讲述了Python元组常见操作。分享给大家供大家参考,具体如下:不能修改的列表就叫做元组。1 访问元素元组是使用圆括号来标识的。 定
- 1. Python中的异常栈跟踪之前在做Java的时候,异常对象默认就包含stacktrace相关的信息,通过异常对象的相关方法printS
- 本文将介绍使用mutable对象作为Python函数参数默认值潜在的危害,以及其实现原理和设计目的陷阱重现我们就用实际的举例来演示我们今天所
- QQ邮箱最新推出了一个授权码,需已验证的手机号向QQ邮箱服务器发送一条短信获得。该授权码用于第三方客户端登录,代替了第三方登录时使用的个人邮
- 近期,MSN、江民等知名网站相继受到了黑客的威胁和攻击,一时间网络上风声鹤唳。本报编辑部接到本文作者(炽天使)的电话,他详细讲述了发现国内最
- OpenCV介绍OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Ma
- 在金融领域中,我们的y值和预测得到的违约概率刚好是两个分布未知的两个分布。好的信用风控模型一般从准确性、稳定性和可解释性来评估模型。一般来说
- 函数原型与参数详解OpenCV提供了cv.Canny()方法,该方法将输入的原始图像转换为边缘图像。该方法的原型为:cv.Canny(ima
- 本文实例讲述了python计算N天之后日期的方法。分享给大家供大家参考。具体如下:python计算N天之后的日期,可以自己写成一个函数,想得
- 如下所示:1. 在PyCharm下安装pyinstaller2. 在Terminal下输入:“pyinstaller -F -w *.py”
- 例子:Response.Cookies("letwego")("visiter")="84