簡體   English   中英

如何將Postgres bytea數據或Python memoryview對象轉換為NumPy數組?

[英]How do I convert Postgres bytea data or a Python memoryview object into a NumPy array?

我有一個PostgreSQL數據庫(v 9.6),其中圖像存儲為bytea數據。 我不知道圖像編碼。 (我沒有設置這個數據庫,雖然我願意,但是我不確定是否可以更改此設置,因為在PostgreSQL數據庫中存儲大圖像不是(IIUC)的最佳做法。)

我想將這些數據提取到圖像中,或者更好的是,直接提取到NumPy數組中。

使用SQLAlchemy,我可以連接並提取數據:

engine = create_engine(postgresql+psycopg2://user:password@server:port/database)
connection = engine.connect()
result = connection.execute('SELECT image FROM database.table LIMIT 1;')

有問題的圖像作為memoryview對象返回; 強制轉換numpy數組,如下所示(每個Cython:將內存視圖轉換為NumPy array ):

[b'\xaa' b'\x04' b'u' b'\x04' b'\x85' b'\x04' b'E' b'\x04' b'\x7f' b'\x04'
 b'\xa5' b'\x04' b'K' b'\x04' b'j' b'\x04' b'\x97' b'\x04' b';' b'\x04'
 b'w' b'\x04' b'k' b'\x04' b'E' b'\x04' b'b' b'\x04' b's' b'\x04']

我嘗試保存為jpg或tiff文件(通過將存儲在數據庫中的BLOB轉換為HTML網站上的圖像 ),但無法使用圖像查看器打開生成的文件。

我也嘗試過此操作( 從字節文件打開PIL圖像 ),但得到以下結果:

OSError: cannot identify image file <_io.BytesIO object at 0x000002299F4DD830>

或者,從如何在python中將十六進制字符串轉換為彩色圖像? ,出現此錯誤:

ValueError: non-hexadecimal number found in fromhex() arg at position 0

所以:我該如何將此bytea數據或此memoryview對象轉換為NumPy數組?

我可能缺少一些簡單的東西,或者這可能只是不應將圖像存儲在SQL數據庫中的原因之一。

對於后代,這是我得出的最簡單的解決方案。

最佳做法是不將圖像存儲在數據庫中,而是在文件系統中存儲多個版本(不同的分辨率,從縮略圖(64x64 ish)到完整分辨率(在這種情況下為2504x2504),並帶有這些圖像的文件路徑。可以按哈希(有些開銷)或類似時間戳進行排序;后者對我們有用,因為所有數據都來自一台攝像機,因此具有不同的時間戳。

所討論的數據是16位灰度TIFF文件。 Python圖像庫(PIL)無法轉換這些圖像。 OpenCV可以的。 但是,由於無論如何我都想要一個NumPy數組,所以這並不重要。 MatPlotLib可以直接顯示數組。 Numpy可以根據需要切片或下采樣。

engine = create_engine('postgresql+psycopg2://user:pass@server:port/database')
connection = engine.connect()

query = 'SELECT * FROM database.schema.table WHERE "ID" = 1234'
result = connection.execute(query)

for row in result:
    data = row[-1] # our image is the last column in the table

connection.close()

從這里, numpymatplotlib可以完成任務。 我知道圖像的分辨率,但是它也存儲在數據庫表的其他位置。

img_array = np.reshape(np.frombuffer(data, dtype="Int16"), (2504, 2504))

norm = cm.colors.Normalize(vmax=abs(img_array).max(), vmin=-abs(img_array).max())
plt.matshow(img_array, norm=norm, cmap="gray")
plt.show()

plt.imshow()也可以。

使用OpenCV,我們使用的代碼是這樣的:

cv2.namedWindow("Image", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
cv2.imshow("Image", img_array)
cv2.waitKey(0)
cv2.destroyAllWindows()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM