Try   HackMD

在實做 flask 時,我透過 curl 指令取得了張圖片,但它的資料格式是 'werkzeug.datastructures.FileStorage',不能直接用 cv2.imread ,但我又不想跟範例程式碼一樣,先存出再讀回。所以找了其他的方法來實做。

先存出再讀回

一般常見的範例都會先存出再讀回,將像下面程式碼一樣。

data =request.files['file'] filename = secure_filename(file.filename) filepath = os.path.join("/tmp", filename); file.save(filepath) img = cv2.imread(filepath)

直接從記憶體中讀取

不過要先存出再讀回,我實在不是很喜歡,所以找到的 cv2.imdecode,根據解釋:

cv2.imdecode()
函數從指定的記憶體快取中讀取數據,並把數據解碼成圖像格式;主要用於從網路傳輸數據中恢復出圖像。


看到網路傳輸數據眼睛就亮起來了有沒有!當下就決定把 cv.imread 換成 cv2.imdecod,並搭配 numpyfromstring 使用字串來建立一個矩陣,完整程式碼如下:

filestr = request.files['file'].read() npimg = numpy.fromstring(filestr, numpy.uint8) img = cv2.imdecode(npimg, cv2.IMREAD_COLOR)

資料型態

用這方式讀進來的資料型態是 uint8,在我的應用中,我會接著喂進 TensorFlow 做 predict,結果會跳出:

TensorFlow TypeError: Value passed to parameter input has DataType uint8 not in list of allowed values: float16, float32


所以我又在最後加了行型態轉換:

filestr = request.files['file'].read() npimg = numpy.fromstring(filestr, numpy.uint8) img = cv2.imdecode(npimg, cv2.IMREAD_COLOR) img = img.astype("float32")



Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
關於 IO 錯誤描述
之前文句中出現 省下那兩次的 IO 的敘述有誤,感謝 Chi Gas 的指正。

在使用 imdecode()imencode() 也是進行了 IO,所以用省下 IO 的描述並不正確。

參考資料

  1. -牧野- (2018-01-25)。OpenCV-Python cv2.imdecode()和cv2.imencode() 图片解码和编码 。檢自 牧野的博客-CSDN博客(2020-02-19)。
  2. flamelite (2017-12-28)。Reading image file (file storage object) using CV2 。檢自 Stack Overflow (2020-02-19)。
  3. tbicr (2013-11-16)。Read file data without saving it in Flask 。檢自 Stack Overflow (2020-02-19)。

更新紀錄

最後更新日期: 2020-08-19
  • 2020-08-19 更新 修正錯誤描述
  • 2020-02-19 發布



本文作者: 辛西亞.Cynthia
本文連結辛西亞的技能樹 / hackmd 版本
版權聲明: 部落格中所有文章,均採用 姓名標示-非商業性-相同方式分享 4.0 國際 (CC BY-NC-SA 4.0) 許可協議。轉載請標明作者、連結與出處!