使OpenCV可以读取中文路径图片的方法

使OpenCV可以读取中文路径图片的方法

码农世界 2024-05-28 前端 80 次浏览 0个评论

一.问题复现

1.代码

#! /usr/bin/env python
# -*- coding: utf-8 -*-
# File: show_img.py
import 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

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.py
import cv2
import numpy as np
from PIL import Image
import os
def 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_bgr
def 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:
        None
    Raises:
        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()可以保存图片

转载请注明来自码农世界,本文标题:《使OpenCV可以读取中文路径图片的方法》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,80人围观)参与讨论

还没有评论,来说两句吧...

Top