news 2026/10/28 2:01:25

OpenCV用python处理图片

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenCV用python处理图片

目录

  • 通用步骤
  • 自定义保存操作
  • 按键分类保存

PyCharm 在导入 OpenCV 的包之后,最基础的是如何对一个图片进行操作。

通用步骤有几部:

1:导包(导入 OpenCV 图像处理库,cv2 就是它在 Python 里的名字。导入后你就能调用它的功能,比如读取图片、截图、做图像识别。)

2:读取图片

3:判断导入是否成功

4:输出图片

5:自定义操作

#导包 import cv2 #读取图片 img_path=r'C:\Users\Thinkpad\PycharmProjects\PythonProject\dog1.webp' #调用功能imread导入图片 img=cv2.imread(img_path) #判断是否导入成功 if img is not None: print('找不到图片,请检查图片路径') #输出图片 imshow title_img这是输出图片的名字 任意命名 可以看输出结果展示 cv2.imshow('title_img',img) #cv2.waitKey(0):等待键盘按键,0 代表无限等,直到你按下任意键,图片窗口才关闭。 小提示:写图片展示代码时搭配 cv2.imshow() 使用,不加这句窗口会一闪而过。 cv2.waitKey(0)

输出结果展示

好啦准备好了吗

现在我们准备做一些自定义操作

举个栗子,在图片找到之后,我们想将这个文件保存到我们自己分类好的文件夹中,

宠物文件夹中有【猫、狗、小鸡、羊驼、荷兰猪、小仓鼠】狗狗的图片,

我们准备将这个图片放入宠物文件夹中并命名为“二哈”,我们就可以这样做:

key=cv2.waitKey(0) #根据用户按键执行操作 判断键入的值 if key==ord('s'): #s对应着ASCII码 可以输入115,表示小写的s 不过键入s可读性更强 #保存图像 output_path=r'C:\Users\Thinkpad\PycharmProjects\PythonProject\.venv\二哈.jpg' #调用保存图片函数 cv2.imwrite(output_path,img) print(f'图片已保存为:{output_path}') else: #如果按下了其他键 print('图像未保存')

看下输出结果能发现一个问题:保存进入文件夹之后图片名字不叫“二哈”,而是乱码。这是因为 Windows 默认文件系统编码是 GBK,而 OpenCV 底层很多版本接收路径的时候默认按 UTF-8 解析。
所以 up 主建议优先使用英文命名!!!!!!!!!!

说到这里有些姥爷问了,博主,俺就是懒 有很多图片的话不想一次一次的去实现,有没有省事的方法??????

有的有的,你看你急炸了吧?!!

我们接下来开始看一下用什么办法实现 OpenCV 按键分类保存图片。


功能目标:
打开一张图片,按下不同按键,自动把图片保存到对应的宠物分类文件夹;文件夹不存在就自动创建;图片自动编号,不会覆盖旧图;按 q 退出窗口。
• 按键 c → 猫 (cat) 文件夹
• 按键 d → 狗 (dog) 文件夹
• 按键 z → 仓鼠 (hamster) 文件夹
• 按键 j → 小鸡 (chicken)
• 按键 y → 羊驼 (alpaca)
• 按键 h → 荷兰猪 (guinea_pig)
• 按键 q → 退出程序


用到的技术
1. cv2.imshow():弹窗展示图片
2. cv2.waitKey(0):等待键盘按下,获取按键 ASCII 码
3. os.path.join():安全拼接路径(Windows、Linux 都兼容,避免斜杠写错)
4. os.makedirs(..., exist_ok=True):创建文件夹,文件夹已存在不会报错
5. os.listdir():读取文件夹里面所有文件,统计 jpg 数量,实现图片自增命名
6. cv2.imwrite():保存图片

来了两个新朋友os.path.join(): 以及os.makedirs(..., exist_ok=True)和 os.listdir()

咳咳!!! 是三个,我当然知道是三个 我就是想看看你们睡着没--。。--

他们的能干什么苦力我们等会就知道了 ⭐嘻嘻🤭

首先第一步仍然是导包

import cv2 #导入 opencv 库,用来读图、显示、保存图片

import os #操作系统模块,用来创建文件夹、读取文件夹里面的文件、拼接路径

第二步 配置一个根目录

root_dir = r'C:\Users\Thinkpad\PycharmProjects\PythonProject\.venv\pet'

root_dir 是我们所有分类子文件夹(cat、dog、hamster…)的统一 “总仓库”,把它单独抽出来写在配置区,是工程上的好习惯,不是随便写的。

r" ":原始字符串,Window路径里的\不会被当成转义符号,防止报错

所有的分类文件夹 cat、dog 都会自动生成在pet这个文件夹里

第三步是搞一个字典

为什么搞一个字典呢字典就是专门用来做【按键 → 分类名】这种一一对应的映射关系,方便管理、好扩展、代码干净。 女士,你也不想你的小手去写一堆的if/else语句吧 丑陋又难以维护。

苦活我干 好了先生,这是你要的一堆if/else

if key == ord('c'): folder_name = "cat"

elif key == ord('d'): folder_name = "dog"

elif key == ord('z'): folder_name = "hamster"

elif key == ord('j'): folder_name = "chicken"

elif key == ord('y'): folder_name = "alpaca"

elif key == ord('h'): folder_name = "guinea_pig"

else: print("无效按键")

允许我歇几分钟!!!

这是我们的字典大人 简单明了

class_map = { ord('c'): "cat", ord('d'): "dog", ord('z'): "hamster", ord('j'): "chicken", ord('y'): "alpaca", ord('h'): "guinea_pig" }
if key in class_map: folder_name = class_map[key]

比如你要加s → sheep: 只在字典追加一行:

ord('s'): "sheep"

完事。 如果是 elif 写法,你还要多写一整条分支。分类多了差距巨大(比如几十类标注)。

整体代码就是

import cv2 import os ========== 1. 配置区:我们自己改这里 ========== 根目录:所有宠物文件夹都放在这个pet文件夹下面 root_dir = r'C:\Users\Thinkpad\PycharmProjects\PythonProject.venv\pet' 按键和分类文件夹的映射字典:key=按键ASCII,value=文件夹名字 class_map = { ord('c'): "cat", ord('d'): "dog", ord('z'): "hamster", ord('j'): "chicken", ord('y'): "alpaca", ord('h'): "guinea_pig" } 读取图片,这里你后面可以换成摄像头画面 img = cv2.imread("test.jpg") 创建窗口,显示图片,窗口名字叫 pet_img cv2.imshow("pet_img", img) ========== 2. 循环监听按键 ========== while True: # 等待按键,按下之后拿到key的值(ASCII码) key = cv2.waitKey(0) # 如果按下 q 键,退出循环,结束程序 if key == ord('q'): print("退出程序") break 判断:按下的键是不是我们上面字典里写好的分类按键 if key in class_map: # 根据按键,拿到对应的文件夹名称 folder_name = class_map[key] # 拼接完整保存路径:根目录 + 当前分类文件夹 save_folder = os.path.join(root_dir, folder_name) # 创建文件夹,exist_ok=True:文件夹已经存在,不报错 os.makedirs(save_folder, exist_ok=True) # 统计这个文件夹里面已经有多少张jpg图片 count = 0 for f in os.listdir(save_folder): # 把文件名转小写,判断后缀是不是.jpg if f.lower().endswith(".jpg"): count += 1 # 拼接文件名:dog_001.jpg、dog_002.jpg 这种格式 # :03d 代表数字占3位,不够前面补0 filename = f"{folder_name}_{count+1:03d}.jpg" # 完整保存路径 save_path = os.path.join(save_folder, filename) # opencv保存图片 cv2.imwrite(save_path, img) print(f"✅ 保存成功:{save_path}") else: # 按了c/d/z/j/y/h/q以外的按键 print("❌ 无效按键,不保存图片") 循环结束,销毁图片窗口 cv2.destroyAllWindows()

AI总结

本文围绕 OpenCV 图片读取、显示、保存以及文件目录操作,梳理了最常用的几个函数,回顾要点如下:

  • cv2.imread():按路径读取图片,返回图像矩阵;路径错误或文件损坏时返回None,使用前务必先判断。
  • cv2.imshow():在弹窗中展示图片,需要配合cv2.waitKey()使用,否则窗口会一闪而过。
  • cv2.waitKey():等待键盘输入并返回按键的 ASCII 码,参数为 0 表示无限等待,是按键交互和分类保存的核心。
  • cv2.imwrite():把图像按指定路径保存到磁盘,路径中的目录必须已存在,否则保存失败。
  • os.path.join():安全拼接路径,自动适配 Windows 和 Linux 的分隔符,避免手写斜杠出错。
  • os.makedirs(..., exist_ok=True):递归创建文件夹,文件夹已存在时不会报错,适合按分类自动建目录。
  • os.listdir():列出文件夹内所有文件名,常用来统计已有图片数量,实现文件自增编号、避免覆盖。

常见报错排查

  • 图片路径含中文乱码:Windows 默认文件系统编码为 GBK,而 OpenCV 部分版本按 UTF-8 解析路径。建议优先使用英文命名;确需中文路径时,可用cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_COLOR)读取,保存时用cv2.imencode配合tofile。
  • imread 返回 None:检查路径是否写错、文件是否存在、后缀名是否正确;路径中不要出现未转义的反斜杠,建议使用原始字符串r"...";同时确认当前工作目录与相对路径的基准一致。
  • 窗口一闪而过:cv2.imshow()后缺少cv2.waitKey(0),程序执行完立即退出。补上等待按键的语句即可让窗口保持显示。
  • 按键无响应:确认图片窗口处于激活状态(鼠标点一下窗口再按键);waitKey()的参数不能省略;若在循环中调用,注意每次循环都要重新调用waitKey()才能持续接收按键。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 2:01:23

大模型微调手记:从显存账本到 vLLM 上线,我踩过的那些坑

上个月给一个知识库项目收尾,模型训完上线,业务方第一句话是"它怎么说话跟以前一样"。翻训练日志才发现 eval loss 早就不动了,我一直在看 train loss 往下掉。那次之后我改了自己的顺序:先算显存,再定数据&…

作者头像 李华
网站建设 2026/10/28 2:00:55

数组,一维数组,二维数组

1、数组的概念数组是一组相同类型元素的集合数组中存放的是1个或者多个数据,但数组的元素个数不能为0数组中存放的多个数据,类型是相同的数组分为一维数组和多维数组,多维数组比较常见的是二维数组2、一维数组的创建与初始化2.1 数组创建基本…

作者头像 李华
网站建设 2026/10/28 2:00:03

代码漏洞检测-python+Flask

本项目为前几天收费帮学妹做的一个项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。 一、项目描述 基于pythonFlask代码安全检测系统通过Mysql数据库连接数据库 http://127.0.0.1:510…

作者头像 李华
网站建设 2026/10/28 1:59:53

两三万字毕业长文怎么降AI:2027主流降AIGC工具比较与复核

两三万字毕业长文怎么降AI:2027主流降AIGC工具比较与复核【工具功能与核对要点】BunnyScholar:比较长文处理与术语保留情况,逐段核对学术论证、引用和原意。助研君:比较分段处理、输出质量与费用,修改后保留版本并人工…

作者头像 李华
网站建设 2026/10/28 1:59:50

一文搞懂QObject 和Q_OBJECT

QObject *parent nullptr 和 Q_OBJECT 宏是 Qt 框架中两个至关重要的机制,它们分别从对象生命周期管理和元编程能力两个维度,构成了 Qt 对象模型的基础。🌳 QObject *parent nullptr:对象树与内存管理这个参数的核心作用是建立 …

作者头像 李华
网站建设 2026/10/28 1:59:46

手机销量创十年新低,价格却屡创新高,怎么回事?

说起最近一段时间的手机市场,相信大多数人的感觉都是气氛压抑,一边是持续下滑的销量,另一边却是持续上涨的价格,面对着手机销量创十年新低,价格却屡创新高的情况,我们到底该怎么看?一、手机销量…

作者头像 李华