2015-11-04 64 views
3

對於我正在編寫的程序,我從一臺計算機傳輸圖像 - 使用base64.b64encode(f.read(image)) - 並嘗試在接收中讀取它腳本而不將其保存到硬盤驅動器(以儘量減少處理時間)。我很難搞清楚如何將圖像讀入OpenCV而不保存在本地。從JPG到b64encode到cv2.imread()

這裏是我的發送圖像的代碼如下所示:

f = open(image.jpg) 
sendthis = f.read() 
f.close() 
databeingsent = base64.b64encode(sendthis) 
client.publish('/image',databeingsent,0) 
# this is an MQTT publish, details for SO shouldn't be relevant 

同時,這裏是代碼接受它。 (這是在ON_MESSAGE功能,因爲我使用MQTT爲轉移。)

def on_message(client, userdata, msg): # msg.payload is incoming data 
    img = base64.b64decode(msg.payload) 
    source = cv2.imread(img) 
    cv2.imshow("image", source) 

後所述消息進行解碼,我有錯誤: 「類型錯誤:你的輸入類型不是numpy的數組」。

我已經做了一些搜索,我似乎無法找到一個相關的解決方案 - 一些存在於使用b64從文本文件轉換爲numpy,但沒有真正涉及到使用圖像,並立即讀取解碼後的數據OpenCV沒有將其保存到硬盤的中間步驟(使用用於在「發送」腳本中讀取文件的逆過程)。

我對Python和OpenCV還很新,所以如果有更好的編碼方法發送圖像 - 無論如何解決問題。只要我可以在接收端讀取圖像而不將其保存爲.jpg到磁盤,圖像的發送方式就無關緊要。

謝謝!

+2

使用'imdecode',而不是'imread' – Miki

+0

「BUF是不是numpy的陣列,既不是標量」 試圖傳遞b64decode一步這裏,仍然得到這個錯誤。所以,仍然要求一個numpy數組 – godfreap

+0

看看[this](http://stackoverflow.com/a/6485943/5008845)有幫助。那麼你需要imdecode,因爲imread從磁盤加載圖像。 – Miki

回答

8

你可以得到一個numpy的陣列從你使用解碼後的數據:

import numpy as np 
... 
img = base64.b64decode(msg.payload) 
npimg = np.fromstring(img, dtype=np.uint8) 

然後,你需要imdecode從內存緩衝區讀取圖像。 imread旨在從文件加載圖像。

所以:

import numpy as np 
... 
def on_message(client, userdata, msg): # msg.payload is incoming data 
    img = base64.b64decode(msg.payload); 
    npimg = np.fromstring(img, dtype=np.uint8); 
    source = cv2.imdecode(npimg, 1) 
+0

您可能想要刪除最後一行cv2.imshow - 當我這樣做時它會鎖定。但是這對於程序來說並不重要 - 這只是我插入的一箇中間步驟,以使原始問題中的代碼更有意義。重要的一點是,在此之前的所有事情都能解決我所遇到的問題,現在一切都是美好的!謝謝! – godfreap

+0

好的謝謝。您可能需要cv2.waitKey(1)來查看_imshowed_圖像並避免阻塞。 – Miki

+0

是的,我有這個,它仍然鎖定。我的程序中與此交互的部分基本上是一樣的,這就是我在問題評論中提到的'新問題'。我認爲這只是一個數據類型問題,應該很容易解決。再次感謝! :d – godfreap

2

從OpenCV的documentation我們可以看到:

imread:從文件加載圖像。

imdecode:從內存中的緩衝區讀取圖像。

看起來更好的方式來做你想做的。