將QImage轉換爲numpy array

最近在做手寫體識別,需要將QT中手寫的數字轉換成像訓練集一樣圖片。因此需要將QImage轉換爲numpy array。

前言

筆者使用的是PyQt,但是對QT和Python之間數據之間的轉換不太熟悉。查了很長時間,也沒有找到詳細的說明,最後在stackoverflow中查到了轉換方法,但是說的也不清楚。

終於,經過查閱QT的參考手冊終於明白了轉換過程。

詳細過程

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

image = self.canvas_label.canvas.toImage()
size = image.size()
s = image.bits().asstring(size.width() * size.height() * image.depth() // 8)  # format 0xffRRGGBB

arr = np.fromstring(s, dtype=np.uint8).reshape((size.height(), size.width(), image.depth() // 8))

new_image = Image.fromarray(array)

# convert to gray
new_image.convert("L")
new_image.thumbnail((28, 28))
plt.imshow(new_image, cmap='gray')
plt.show()

1. 將QImage轉換爲字符串

筆者的原圖是通過QPixmap繪製的一幅RGB圖。之後將其轉換爲QImage。

通過s = image.bits().asstring(size.width() * size.height() * image.depth() // 8)將圖像數據轉換成字符串。

參數是圖像中字節數,字節數等於圖像寬度 × 圖像高度 × 通道數,即bytes=widthheightchannelsbytes = width * height * channels

需要注意的是通道數,查看QT的手冊知道QT的RGB圖像的格式是0xFFRRGGBB,其實就是將Alpha通道全部置爲了0xFF。

之前以爲只有3個通道,所以一直有問題。QImage.depth()可以返回圖像深度的比特數,對於RGB圖QImage.depth()返回值爲32,所以整除8之後就是通道數。

2. 將字符串轉換爲Numpy array

之後使用np.fromstring()即可通過字符串構造numpy array。

到這裏QImage轉換爲numpy array的任務就完成了。之後需要將原圖進行灰度處理和壓縮。

3. 灰度處理 & 壓縮

  1. 使用Image.convert()可以進行格式轉換,詳細用法見https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.convert
  2. 使用Image.thumbnail()進行壓縮,注意該方法只能進行壓縮,不能放大,而且是等比例壓縮。如果需要放大可以使用Image.resize()方法。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章