OpenCV 4基础篇| OpenCV图像的裁切

目录

  • 1. Numpy切片
    • 1.1 注意事项
    • 1.2 代码示例
  • 2. cv2.selectROI()
    • 2.1 语法结构
    • 2.2 注意事项
    • 2.3 代码示例
  • 3. Pillow.crop
    • 3.1 语法结构
    • 3.2 注意事项
    • 3.3 代码示例
  • 4. 扩展示例:单张大图裁切成多张小图
  • 5. 总结

1. Numpy切片

语法结构:

retval = img[y:y+h, x:x+w] #对图像 img 裁剪并返回指定的矩阵区域图像。
  • img:图像数据,nparray 多维数组
  • x, y:整数,像素值,裁剪矩形区域左上角的坐标值
  • w, h:整数,像素值,裁剪矩形区域的宽度、高度
  • retval:裁剪后获得的 OpenCV 图像,nparray 多维数组

1.1 注意事项

  • Numpy 多维数组的切片是原始数组的浅拷贝,切片修改后原始数组也会改变。推荐采用 .copy() 进行深拷贝,得到原始图像的副本。
  • Numpy 数组切片,当上界或下界为数组边界时可以省略,如:img[y:, :x] 表示高度方向从 y 至图像底部(像素ymax),宽度方向从图像左侧(像素 0)至 x。

1.2 代码示例

import cv2

imgFile = "./img/lena.jpg"
img1 = cv2.imread(imgFile, flags=1)  # flags=1 读取彩色图像(BGR)
xmin, ymin, w, h = 200, 200, 200, 200  # 矩形裁剪区域 (ymin:ymin+h, xmin:xmin+w) 的位置参数
imgCrop = img1[ymin:ymin + h, xmin:xmin + w].copy()  # 切片获得裁剪后保留的图像区域
cv2.imshow("CropDemo", imgCrop)  # 在窗口显示 彩色随机图像
cv2.waitKey(0)
cv2.destroyAllWindows()

1

2. cv2.selectROI()

2.1 语法结构

cv2.selectROI(windowName, img, showCrosshair=None, fromCenter=None):#可以通过鼠标选择感兴趣的矩形区域(ROI)
  • windowName:选择的区域被显示在的窗口的名字
  • img:要在什么图片上选择ROI
  • showCrosshair:是否在矩形框里画十字线.
  • fromCenter:是否是从矩形框的中心开始画

2.2 注意事项

  • 由于 cv2.selectROI 是一个交互式的函数,它可能不适合用于自动化脚本或没有图形用户界面的环境。在这种情况下,你可能需要寻找其他方法来选择图像中的 ROI,例如使用固定坐标、图像分割算法等。

2.3 代码示例

import cv2

imgFile = "img/lena.jpg"  
img1 = cv2.imread(imgFile, flags=1)  # flags=1 读取彩色图像(BGR)
roi = cv2.selectROI(img1, showCrosshair=True, fromCenter=False)
xmin, ymin, w, h = roi  # 矩形裁剪区域 (ymin:ymin+h, xmin:xmin+w) 的位置参数
imgROI = img1[ymin:ymin + h, xmin:xmin + w].copy()  # 切片获得裁剪后保留的图像区域
cv2.imshow("RIODemo", imgROI)
cv2.waitKey(0)
cv2.destroyAllWindows()

1

3. Pillow.crop

3.1 语法结构

retval = Image.crop(left, up, right, lower) #可以通过鼠标选择感兴趣的矩形区域(ROI)
  • left: 整数,表示裁剪区域左上角的 x 坐标。
  • up:整数,表示裁剪区域左上角的 y 坐标。
  • right:整数,表示裁剪区域右下角的 x 坐标。这个值通常大于 left。
  • below:整数,表示裁剪区域右下角的 y 坐标。这个值通常大于 upper。
  • retval:一个新的 Image 对象,原始图像中被裁剪出来的矩形区域

3.2 注意事项

  • crop()函数接受一个包含四个数字的元组参数,表示裁剪区域的左上角和右下角的坐标。这个元组的格式是(left, upper, right, lower),其中left和upper是裁剪区域的左上角坐标,right和lower是右下角坐标。坐标的原点(0,0)通常在图像的左上角。
  • Pillow库使用坐标系的原点在左上角,x轴向右增加,y轴向下增加。这与一些其他图像处理库(如OpenCV)的坐标系原点在左下角的约定不同,需要注意坐标的顺序和方向。
  • 裁剪区域的坐标必须在图像的边界内。如果裁剪区域的坐标超出了图像的边界,将会引发一个ValueError异常。因此,在调用crop()函数之前,最好先检查裁剪区域的坐标是否有效。
  • crop()函数不会修改原始图像,而是返回一个新的裁剪后的图像对象。原始图像保持不变,如果需要保存裁剪后的图像,需要将其保存到文件或进行其他操作。

3.3 代码示例

from PIL import Image
import matplotlib.pyplot as plt

imgFile = "./img/lena.jpg"
img = Image.open(imgFile)  # W*H
plt.rcParams['font.sans-serif'] = ['FangSong']  # 支持中文标签
plt.subplot(221), plt.title("原图"), plt.axis('off')
plt.imshow(img)  
img_c = img.crop([img.size[0] / 4, img.size[1] / 4, img.size[0] * 3 / 4, img.size[1] * 3 / 4])
plt.rcParams['font.sans-serif'] = ['FangSong']  # 支持中文标签
plt.subplot(222), plt.title("裁切之后"), plt.axis('off')
plt.imshow(img_c)  
plt.show()

11

4. 扩展示例:单张大图裁切成多张小图

from PIL import Image

imgFile = "./img/lena.jpg"
img = Image.open(imgFile)
size = img.size
print(size)
# 准备将图片切割成9张小图片
weight = int(size[0] // 3)
height = int(size[1] // 3)
# 切割后的小图的宽度和高度
print(weight, height)
for j in range(3):
    for i in range(3):
        box = (weight * i, height * j, weight * (i + 1), height * (j + 1))
        region = img.crop(box)
        region.save('{}{}.png'.format(j, i))

1

5. 总结

  • Numpy切片和Pillow.crop()都是非交互式的裁剪方法,适用于在代码中直接指定裁剪区域。
  • cv2.selectROI()是一个交互式的裁剪方法,允许用户通过图形界面选择ROI。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/425144.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

单源最短路的综合应用

1135. 新年好 - AcWing题库 单源最短路和暴搜的结合 import java.util.*;class PII implements Comparable<PII>{int num, distance;public PII(int num, int distance){this.num num;this.distance distance;}public int compareTo(PII o){return distance - o.dista…

解读OWASP软件保障成熟度模型SAMM

OWASP软件保证成熟度模型&#xff08;SAMM&#xff09;可为所有类型的组织分析和改进其软件安全态势提供有效和可衡量的方法。OWASP SAMM支持完整的软件生命周期&#xff0c;包括开发和获取&#xff0c;并且与技术和过程无关。 1. 简介 OWASP软件保证成熟度模型&#xff08;SA…

文生视频基础1:sora技术报告学习

sora技术报告学习 背景学后理解训练流程技术拆解编码解码扩散模型训练用数据 28号直播交流会后的一些想法自身的一点点想法 参考 原文地址&#xff1a;Video generation models as world simulators 背景 此项目的背景是基于Datawhale的关于sora技术文档的拆解和相关技术讲解…

什么是支持向量机(Support vector machine)和其原理

作为机器学习的基础算法&#xff0c;SVM被反复提及&#xff0c;西瓜书、wiki都能查到详细介绍&#xff0c;但是总是觉得还差那么点&#xff0c;于是决定自己总结一下。 一、什么是SVM&#xff1f; 1、解决什么问题&#xff1f; SVM&#xff0c;最原始的版本是用于最简单的线…

部署bpmn项目实现activiti流程图的在线绘制

本教程基于centos7.6环境中完成 github开源项目: https://github.com/Yiuman/bpmn-vue-activiti软件&#xff1a;git、docker 1. 下载源代码 git clone https://github.com/Yiuman/bpmn-vue-activiti.git2. 修改Dockerfile文件 声明基础镜像&#xff0c;将项目打包&#xff…

vue2+若依框架plus交互 路由介绍

本周及寒假 参加了校企合作的工程过程管理&#xff0c;和学长学姐一起写项目&#xff0c;之前学了vue也没有应用&#xff0c;然后对框架很多组件的用法不太了解&#xff0c;前期耽误了一些时间。 框架模块 首先是框架模块的介绍 api存了一些系统管理及发送请求的方法 例如p…

智能驾驶规划控制理论学习04-基于车辆运动学的规划方法

目录 一、线性二自由度汽车模型&#xff08;自行车模型&#xff09; 1、二自由度模型概述 2、不同参考点下的状态空间方程 3、前向仿真 二、运动基元生成方法 1、杜宾斯曲线&#xff08;Dubins Curve&#xff09; 2、Reeds Shepp Curve 三、多项式曲线&#xff08;Poly…

redis7.2.2|Dict

文章目录 StructredisDBdictdictTypedictEntry 宏定义散列函数散列冲突dictEntry pointer bit tricks[指针位技巧]API implementation_dictReset_dictInitdictCreatedictGetHashdictSetKeydictSetValdictSetNextdictGetNextdictGetValdictGetKey_dictCleardictEmptydictRelease…

五、西瓜书——集成学习

1.个体与集成 集成学习通过将多个学习器进行结合,常可获得比单一学习器显著优越的泛化性能&#xff0c;这对“弱学习器”(weak learner)尤为明显因此集成学习的很多理论研究都是针对弱学习器进行的而基学习器有时也被直接称为弱学习器。 要获得好的集成个体学习器应“好而不同”…

详解JavaScript的函数

详解 JavaScript 的函数 函数的语法格式 创建函数/函数声明/函数定义 function 函数名(形参列表) { 函数体 return 返回值; // return 语句可省略 } 函数调用 函数名(实参列表) // 不考虑返回值 返回值 函数名(实参列表) // 考虑返回值 示例代码 //定义的没有参数列表&am…

5个好玩神奇还免费的工具网站收藏不后悔-搜嗖工具箱

生命倒计时 http://www.thismuchlonger.com 这是一个相哇塞的网站&#xff0c;可以让我们静下心来好好想想我们来这个世界究竟为了什么&#xff0c;因为当我们作为命运的主宰者。敲打键盘设定好自己一生长度的时候&#xff0c;我们的剩余寿命已经成绝对值&#xff0c;一旦生命…

mysql5.7配置主从

原理&#xff1a; MySQL主从复制的工作原理如下:1. 主服务器产生Binlog日志当主服务器的数据库发生数据修改操作时,如INSERT、UPDATE、DELETE语句执行,主服务器会记录这些操作的日志信息到二进制日志文件中。2. 从服务器读取Binlog日志 从服务器会向主服务器发送请求,主服务器把…

Linux网络编程——socket 通信基础

Linux网络编程——socket 通信基础 1. socket 介绍2. 字节序2.1 简介2.2 字节序举例2.3 字节序转换函数 3. socket 地址3.1 通用 socket 地址3.2 专用 socket 地址 4. IP地址转换&#xff08;字符串ip -> 整数&#xff0c;主机、网络字节序的转换 &#xff09;5. TCP 通信流…

智能驾驶规划控制理论学习05-车辆运动学规划案例分析

目录 案例一——Hybrid A*&#xff08;基于正向运动学&#xff09; 1、基本思想 2、 实现流程 3、启发函数设计 4、分析扩张&#xff08;Analytic Expansions&#xff09; 5、分级规划&#xff08;Hierarchical planning&#xff09; 案例二——State Lattice Planning&…

Vue3快速上手(十六)Vue3路由传参大全

Vue3路由传参 一、传参的多种方式 1.1 拼接方式 这种方式适合传递单个参数的情况&#xff0c;比如点击查看详情&#xff0c;传个id这样的场景 传参&#xff1a; <RouterLink to"/person?id1" active-class"active">person</RouterLink> …

RabbitMQ相关问题

RabbitMQ相关问题 一、RabbitMQ的核心组件和工作原理&#xff1f;二、如何保证消息可靠投递不丢失的&#xff1f;三、RabbitMQ如何保证消息的幂等性&#xff1f;四、什么是死信队列&#xff1f;死信队列是如何导致的&#xff1f;五、RabbitMQ死信队列是如何导致的&#xff1f;六…

PDF 解析问题调研

说点真实的感受 &#xff1a;网上看啥组件都好&#xff0c;实际测&#xff0c;啥组件都不行。效果好的不开源收费&#xff0c;开源的效果不好。测试下来&#xff0c;发现把组件融合起来&#xff0c;还是能不花钱解决问题的&#xff0c;都是麻烦折腾一些。 这里分享了目前网上能…

数据结构 第3章 栈、队列和数组(一轮习题总结)

第3章 栈、队列和数组 3.1 栈3.2 队列3.3 栈与队列的应用3.4 数组和特殊矩阵 3.1 栈&#xff08;1 10 11 20&#xff09; 3.2 队列&#xff08;6 12 14 17&#xff09; 3.3 栈与队列的应用&#xff08;6 11&#xff09; 3.4 数组和特殊矩阵 3.1 栈 T1 栈和队列具有相同的逻辑…

一周学会Django5 Python Web开发-Django5详细视图DetailView

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计28条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

Linux-信号2

文章目录 前言一、信号是如何保存的&#xff1f;int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset (sigset_t *set, int signo);int sigdelset(sigset_t *set, int signo);int sigismember&#xff08;const sigset_t *set, int signo);int sigpen…