目录
- 通用步骤
- 自定义保存操作
- 按键分类保存
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()才能持续接收按键。