一.问题复现
1.代码
#! /usr/bin/env python
# -*- coding: utf-8 -*-# File: show_img.pyimport cv2# 读取图片
img = cv2.imread("车牌素材/冀A.png")# 显示图片
cv2.imshow("img", img)
cv2.waitKey(0)
2.报错截图
3.报错内容
[ WARN:0@0.057] global loadsave.cpp:248 cv::findDecoder imread_(‘***’): can’t open/read file: check file path/integrity
Traceback (most recent call last):
File “***”, line 7, in <module>
cv2.imshow(“img”, img)
cv2.error: OpenCV(4.9.0) D:\a\opencv-python\opencv-python\opencv\modules\highgui\src\window.cpp:971: error: (-215:Assertion failed) size.width>0 && size.height>0 in function ‘cv::imshow’
二.解决方法
1.代码
#! /usr/bin/env python
# -*- coding: utf-8 -*-# File: show_img_with_CNpath.pyimport cv2
import numpy as np
from PIL import Image
import osdef cv_imread(file_path: str):"""使用PIL读取一张图片并转换成OpenCV格式, 从而支持读取中文路径的图片。Args:file_path (str): 图片文件的路径。这个路径可以包含中文字符, 因为PIL库能够正确处理Unicode字符串。Returns:np.ndarray: 转换后的OpenCV格式的图像数据, 形状为(H, W, C), 数据类型为np.uint8。其中H代表图像的高度, W代表图像的宽度, C代表图像的通道数( 对于彩色图像通常是3 )。OpenCV中图像的颜色通道顺序是BGR( 蓝-绿-红 ), 与PIL的RGB( 红-绿-蓝 )不同。Raises:IOError: 如果文件无法打开或读取, 将抛出IOError异常。流程说明:1. 使用PIL库的Image.open()函数打开指定路径的图片文件。PIL库能够正确处理包含中文的文件路径。2. 将PIL图像对象转换为NumPy数组。PIL图像对象本质上是一个NumPy数组, 所以这一步是直接转换。3. 使用OpenCV库的cvtColor()函数将图像从RGB颜色空间转换为BGR颜色空间。这是因为OpenCV默认使用BGR格式,而PIL和其他图像处理库通常使用RGB格式。4. 返回转换后的NumPy数组, 这个数组现在可以被OpenCV函数直接使用。注意:- 确保已经安装了Pillow和OpenCV库, 可以通过pip安装: `pip install Pillow opencv-python`。- 该函数假设输入的图片是RGB格式。如果图片是灰度图或其他格式, 可能需要额外的处理步骤。- 在使用该函数之前, 确保`cv2`和`Image`模块已经被正确导入。"""# 使用PIL打开图片文件img = Image.open(file_path)# 将PIL图像转换为NumPy数组( RGB格式 )cv_img_rgb = np.array(img)# 使用OpenCV将RGB格式的NumPy数组转换为BGR格式cv_img_bgr = cv2.cvtColor(cv_img_rgb, cv2.COLOR_RGB2BGR)# 返回转换后的BGR格式的NumPy数组return cv_img_bgrdef cv_imwrite(file_path: str, img: cv2.typing.MatLike):"""使用OpenCV将图像写入指定的文件路径, 支持中文路径。Args:file_path (str): 要保存图像的文件路径。这个路径可以包含中文字符。img (np.ndarray): 要保存的图像数据, 应该是一个OpenCV格式的NumPy数组, 形状为(H, W, C),其中H是高度, W是宽度, C是通道数。数据类型应该是np.uint8。Returns:NoneRaises:ValueError: 如果图像数据不是NumPy数组或者数据类型不正确。流程说明:1. 使用os.path.splitext()函数从文件路径中提取文件扩展名。2. 使用cv2.imencode()函数对图像进行编码。这个函数接受文件扩展名和图像数组作为参数,并返回一个包含编码图像数据的元组。3. 通过索引[1]获取cv2.imencode()返回的元组中的图像数据部分。4. 使用tofile()方法将编码后的图像数据写入指定的文件路径。如果文件已存在, 将被覆盖。注意:- 确保已经安装了OpenCV库。- 该函数假设输入的图像数据是OpenCV格式的NumPy数组, 并且数据类型为np.uint8。- 如果文件路径包含中文字符, 该函数应该能够正确处理。- 如果保存过程中发生任何错误(如文件写入权限问题), 将抛出异常。"""# 从文件路径中提取文件扩展名extension = os.path.splitext(file_path)[1]# 使用OpenCV的imencode函数对图像进行编码# 注意: extension包括点(.), 例如 '.jpg' 而不是 'jpg'# 编码后的图像数据将根据文件扩展名自动选择正确的格式encoded_img = cv2.imencode(extension, img)[1]# 将编码后的图像数据写入文件encoded_img.tofile(file_path)# 读取图片
img = cv_imread("车牌素材/冀A.png")# 显示图片
cv2.imshow("img", img)
cv2.waitKey(0)# 保存图片
cv_imwrite("车牌素材/冀A_保存.png", img)
三.其他
使用cv2.imdecode()
配合np.fromfile()
并不能读取中文路径的图片,但是使用cv2.imencode()
可以保存图片