1. 程式人生 > >opencv--圖片的讀寫【3】

opencv--圖片的讀寫【3】

1、讀寫影象檔案

將影象檔案讀入記憶體,可以使用 imread()函式;將 Mat 物件以影象檔案格式寫入記憶體,可以使用 imwrite()函式。

1.1、讀取影象檔案

imread()函式返回的是 Mat 物件,如果讀取檔案失敗,則會返回一個空矩陣,即Mat::data 的值是 NULL。執行 imread()之後,需要檢查檔案是否成功讀入,你可以使用 Mat::empty()函式進行檢查。

  • imread()函式的宣告如下:
    Mat imread(const string& filename, int flags=1)
    
    很明顯引數 filename 是被讀取或者儲存的影象檔名;
    在 imread()函式中,flag 引數值有三種情況:
    1. flag>0,該函式返回3 通道
    影象,如果磁碟上的影象檔案是單通道的灰度影象,則會被強制轉為 3 通道;
    2. flag=0,該函式返回單通道影象,如果磁碟的影象檔案是多通道影象,則會被強制轉為單通道;
    3. flag<0,則函式不對影象進行通道轉換。
  • imread()函式支援多種檔案格式,且該函式是根據影象檔案的內容來確定檔案格式,而不是根據檔案的副檔名來確定。所只是的檔案格式如下:
  1. Windows 點陣圖檔案 - BMP, DIB;
  2. JPEG 檔案 - JPEG, JPG, JPE;
  3. 行動式網路圖片 - PNG;
  4. 行動式影象格式 - PBM,PGM,PPM;
  5. Sun rasters - SR,RAS;
  6. TIFF 檔案 - TIFF,TIF;
  7. OpenEXR HDR 圖片 - EXR;
  8. JPEG 2000 圖片- jp2。
你所安裝的 OpenCV 並不一定能支援上述所有格式,檔案格式的支援需要特定的庫,只有在編譯 OpenCV 添加了相應的檔案格式庫,才可支援其格式。

1.2、寫影象檔案

將影象寫入檔案,可使用 imwrite()函式

  • 該函式的宣告如下:
bool imwrite(const string& filename, InputArray image,const vector<int>&
params=vector<int>())

引數:

  1. 檔案的格式由 filename 引數指定的副檔名確定。
    1. BMP 格式是無損格式,但是一般不進行壓縮,檔案尺寸非常大;
    2. JPEG 格式的檔案較小,但是 JPEG 是有失真壓縮,會丟失一些資訊。
    3. PNG 是無失真壓縮格式,推薦使用。
  2. 第三個引數 params 可以指定檔案格式的一些細節資訊。這個引數裡面的數值是跟檔案格式相關的:
    1. JPEG:表示影象的質量,取值範圍從 0 到 100。數值越大表示影象質量
      越高,當然檔案也越大。預設值是 95。
    2. PNG:表示壓縮級別,取值範圍是從 0 到 9。數值越大表示檔案越小,
      但是壓縮花費的時間也越長。預設值是 3。
    3. PPM,PGM 或 PBM:表示檔案是以二進位制還是純文字方式儲存,取值為
      0 或 1。如果取值為 1,則表示以二進位制方式儲存。預設值是 1。
  • 並不是所有的 Mat 物件都可以存為影象檔案,目前支援的格式只有 8U 型別的單通道和 3 通道(顏色順序為 BGR)矩陣;

    如果需要要儲存 16U 格式影象,只能使用 PNG、JPEG 2000 和 TIFF 格式。

    如果希望將其他格式的矩陣儲存為影象檔案,可以先用 Mat::convertTo()函式或者 cvtColor()函式將矩陣轉為可以儲存的格式。

    另外需要注意的是,在儲存檔案時,如果檔案已經存在,imwrite()函式不會
    進行提醒,將直接覆蓋掉以前的檔案

#include <iostream>
#include "opencv2/opencv.hpp"
using namespace std;
using namespace cv;
int main(int argc, char* argv[])
{

    //讀入影象,並將之轉為單通道影象
	Mat im = imread("D:\\2.jpg", 1);
	//namedWindow("yuan", WINDOW_AUTOSIZE);//窗戶的標誌。支援的標誌是:(cv :: WindowFlags)
	imshow("自拍原圖", im);
	//請一定檢查是否成功讀圖
	if (im.empty())
	{
		cout << "Can not load image." << endl;
		return -1;
	}

	//進行 Canny 操作,並將結果存於 result
	Mat result;
	Canny(im, result, 50, 150);

	//儲存結果
	imwrite("canny.png", result);
	imshow("我的自拍", result);
	waitKey(0);
	return 0;
}

在這裡插入圖片描述