Python常用图片数据方法

本文详细介绍了Python中图片数据类型(如cv2的ndarray和PIL的Image),展示了如何使用plt.imshow进行图片显示,以及如何通过turtle绘制图片。还涵盖了ndarray的切片操作,包括RGB通道获取和BGR转RGB,以及cv2对中文路径的支持问题。最后提到将PIL转换为QImage和QPixmap的方法。
摘要由CSDN通过智能技术生成

1. 常用图片数据类型

在这里插入图片描述

  1. 使用 cv2.imread

    返回的是一个 numpy.ndarray类型, 同时 cv2.Mat 也是ndarray的包装类 ,数据默认是 BGR 形式的

    img = cv2.imread('./image/test.png')  # 100 x 78,32bpp
    print(type(img))  # <class 'numpy.ndarray'>
    print(img.shape)  # (78, 100, 3)
    print(img)  # cv2 的 image 是 BGR 格式 [[[ 90 108  68] ...	BGR
    
  2. PIL.Image

    Image.open返回了一个Image类, 具体数据可以 通过 tobytes() 方法返回, 数据默认是RGBA形式

    img = Image.open("./image/test.png")
    print(img)  # <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=100x78 at 0x261D5255A90>
    print(img.width)
    print(img.height)
    print(img.mode)
    

    同时 Image 类 兼容了 ndarray, 也就是说 Image的数据可以直接转换成 ndarray 类型

    img_data = np.array(img)    # 这里面也是用 tobytes 来获取原始数据的
    print(img_data)         # [[[ 68 108  90 255] .... RGBA
    print(img_data.shape)   # (78, 100, 4)
    
  3. QImage

    QImage 中存储的数据 从 bits() 获取, 为了方便, 统一转成 RGBA8888

    q_img = QImage()
    q_img.load("./image/test.png")
    
    w, h = q_img.width(), q_img.height()
    q_img.convertTo(QImage.Format.Format_RGBA8888)
    
    print(q_img.sizeInBytes())
    
    dataPtr = q_img.bits()
    dataPtr.setsize(q_img.sizeInBytes())
    
    img = Image.frombytes(mode='RGBA', data=dataPtr, size=(w, h))       # 转换成 PIL.Image 类型
    
    img_array = np.array(dataPtr).reshape((h, w, 4))    # 转换成 ndarray 类型
    

2. 图片的显示

图片显示有很多方法, cv2.imshow, plt.imshow, QLabel.setPixmap 也能show, tkinter 的Label 也可以, 但最方便感觉还是使用plt

2.1 plt.imshow()

def imshow(
    X: ArrayLike | PIL.Image.Image,
    cmap: str | Colormap | None = None,
    norm: str | Normalize | None = None,
....
) -> AxesImage:
# plt 可是直接显示 PIL.Image 以及 ndarray

使用方法也很简单

import numpy as np
from PIL import Image
from matplotlib import pyplot as plt

img = Image.open("./image/test.png")
print(img)  # <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=100x78 at 0x261D5255A90>

plt.imshow(img)
plt.show()

2.2 使用 turtle 来绘制图片

turtle 可以用来绘制图片

原理其实很简单, 获取像素数据,画笔设置像素颜色, 再直接落笔就🆗

import turtle as t
import cv2

print(t.colormode())
t.colormode(255)
img1 = cv2.imread('./image/test.png')[:, :, ::-1]	# BGR 形式 转成 RGB 形式

height = img1.shape[0]
width = img1.shape[1]

t.setup(width=width * 2, height=height * 2)
print(t.pos())
t.pu()
t.goto(-width / 2, height / 2)
t.pd()
t.tracer(2000)
for k1, i in enumerate(img1):
    for j in i:
        t.pencolor((j[0], j[1], j[2]))
        t.fd(1)
    t.pu()
    t.goto(-width / 2, height / 2 - k1 - 1)
    t.pd()
t.done()

3.图片ndarray数据的常用切片操作

为了讲解这一部分的知识,特地缩小了一张图片(test.png 100*28) 来讲解

使用 cv2 来读取图片

img = cv2.imread('./image/test.png')  # 100 x 78,32bpp

打印数据

一张图片解码后的像素数据大概是这个样子的, 以BGR为例, 就是一个[h][w][3] 形状 3 维数据

二维的像素数组, 每个像素又是一个3列的列表分别表示BGR的颜色组成

print(img)
[
    [ [ 90 108  68] [ 88 107  66] [ 80  98  57]   ...]
    [ [ 24  40  12] [ 24  40  12] [ 23  40  12]   ...]
    ...
]

R G B 通道的获取

直接使用 ndarray 的切片 ,分别获取 R G B 的颜色分量

二维的像素数组, 每个像素只有一个颜色分量

# print(img[..., 0])
# print(img[:, :, 0])  # 第 1 个通道    [[ 90  88  80 ...  24  24  23] ...
# print(img[:, :, 1])  # 第 2 个通道    [[108 107  98 ...  40  40  40] ...
# print(img[:, :, 2])  # 第 3 个通道    [[ 68  66  57 ...  12  12  12]

BGR 转成 RGB

img_RGB = img[..., ::-1]   # 还是切片

cv2 不支持中文路径的解决方法

cv 库 不支持图片文件名包含中文, 用 np.fromfile 读取数据,并重新解码数据来解决

img = cv2.imdecode(np.fromfile('./image/测试.png', dtype=np.uint8), 
                   cv2.IMREAD_COLOR)

4 PIL.Image 转成 QImageQPixmap

PIL.Image 有两个函数 可以分别转成 QImageQPixmap

  • toqimage() -> ImageQt
  • toqpixmap()-> QPixmap
  • 21
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值