解密 | OpenCV加載圖像大小是有限制的 ?

  • 2020 年 3 月 10 日
  • 筆記

問題來由

最近有人問一個問題,就是它有個大小800MB的圖像文件,發現無法通過OpenCV的imread函數加載,只要一讀取,程序就直接崩潰了。我問了圖像的大小,計算像素數量之後發現總像素數目已經超過了OpenCV聲明最大像素數目限制,所以肯定無法讀取了!

大家都知道OpenCV中讀取圖像的函數是imread,函數功能如下:

Mat cv::imread(         const String &        filename,         int flags = IMREAD_COLOR)

參數解釋

  • filename 表示輸入圖像的文件路徑
  • flags 表示加載圖像的方式

支持包括bmp、jpg、png、webp、pfm、sr、ras、tiff、hdr等格式圖像文件

之前寫過一篇imread的各種讀圖像技巧跟方式,鏈接如下:

OpenCV中各種類型Mat數據讀取

OpenCV中高效的像素遍歷方法,寫出工程級像素遍歷代碼

加載超大圖像限制與突破

加載超大圖像遇到的最常見的一個錯誤就是

提示電腦內存不夠了,但是很多時候電腦內存是足夠,但是還是無法加載,原因很簡單,主要是OpenCV本身對加載的圖像大小是由限制的,這個限制定義在

modulesimgcodecssrcloadsave.cpp

這個源碼文件中,有三個關於圖像imread時候最大圖像寬、高、像素數目大小限制,定義的代碼為:

static const size_t CV_IO_MAX_IMAGE_WIDTH = utils::getConfigurationParameterSizeT("OPENCV_IO_MAX_IMAGE_WIDTH", 1 << 20);  static const size_t CV_IO_MAX_IMAGE_HEIGHT = utils::getConfigurationParameterSizeT("OPENCV_IO_MAX_IMAGE_HEIGHT", 1 << 20);  static const size_t CV_IO_MAX_IMAGE_PIXELS = utils::getConfigurationParameterSizeT("OPENCV_IO_MAX_IMAGE_PIXELS", 1 << 30);

解釋如下:

  • 支持的最大圖像寬度 2^20
  • 支持的最大圖像高度2^20
  • 支持的最大像素數目2^30

函數validateInputImageSize會首先校驗圖像的大小,

static Size validateInputImageSize(const Size& size)  {      CV_Assert(size.width > 0);      CV_Assert(static_cast<size_t>(size.width) <= CV_IO_MAX_IMAGE_WIDTH);      CV_Assert(size.height > 0);      CV_Assert(static_cast<size_t>(size.height) <= CV_IO_MAX_IMAGE_HEIGHT);      uint64 pixels = (uint64)size.width * (uint64)size.height;      CV_Assert(pixels <= CV_IO_MAX_IMAGE_PIXELS);      return size;  }

修改限制

想要加載超過這些限制的圖像文件,首先要確保你由足夠的內存,然後手動修改OpenCV源碼文件,把限制改到你想要的值,然後重新編譯OpenCV即可。關於如何從源碼編譯OpenCV生成安裝包,視頻教程在這裡,點擊即可觀看:

https://space.bilibili.com/365916694/#/