[英]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()
從這里, numpy
和matplotlib
可以完成任務。 我知道圖像的分辨率,但是它也存儲在數據庫表的其他位置。
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.