基礎學習筆記之opencv(24):imwrite函數的使用


 

  前言

  OpenCV中保存圖片的函數在c++版本中變成了imwrite(),這應該是向matlab中圖像處理的的一些函數風格靠近吧。保存圖片這個功能還是很重要的,比如說在寫科研論文的時候需要把一些中間圖片給貼出來,這樣就可以在程序中間利用該函數保存圖片了。甚至還可以將這些保存的圖片供后續的matlab處理。本文就簡單介紹下OpenCV中imwrite()函數的用法。不過個人感覺這個函數功能還是不夠強大,使用時有很多限制。

  開發環境:QtCreato2.5.1+OpenCV2.4.3

 

  實驗基礎

  本次實驗主要是測試imwrite()函數的2個功能:

  1. 測試其是否能夠保存Mat圖像中截取的一部分圖像,比如說用Rect矩陣截取大的圖像中的一部分,由於此時兩者只是用了自己的文件頭,數據是共享的(沒有采用copyTo()函數或者clone()函數復制),所以這種測試想法很正常。

  2. 測試imwrite()函數的第3個參數的使用。

  在針對第1個測試時,是給定一張原圖,截取一部分,然后保存。針對第2個功能是采用OpenCV官網文件中的一個例子,創建一個alpha表,然后保存為png格式的圖片,壓縮參數自設定。

 

  首先來看看imwrite()函數的具體用法。

  bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector<int>() )

  該函數是把程序中的Mat類型的矩陣保存為圖像到指定位置。

  參數filename為所需保存圖像的文件目錄和文件名。這里的文件名需要帶有圖像格式后綴的,目前OpenCV該函數只支持JPEG,PNG,PPM,PGM,PBM,TIFF等。並不是所有Mat類型都支持。

  img參數為圖像數據來源,其類型為Mat。注意也不是所有格式的Mat型數據都能被使用保存為圖片,目前OpenCV主要只支持單通道和3通道的圖像,並且此時要求其深度為8bit和16bit無符號(即CV_16U)。所以其他一些數據類型是不支持的,比如說float型等。如果Mat類型數據的深度和通道數不滿足上面的要求,則需要使用convertTo()函數和cvtColor()函數來進行轉換。convertTo()函數負責轉換數據類型不同的Mat,即可以將類似float型的Mat轉換到imwrite()函數能夠接受的類型。而cvtColor()函數是負責轉換不同通道的Mat,因為該函數的第4個參數就可以設置目的Mat數據的通道數(只是我們一般沒有用到它,一般情況下這個函數是用來進行色彩空間轉換的)。另外也可以不用imwrite()函數來存圖片數據,可以直接用通用的XML IO接口函數將數據存在XML或者YXML中。

  參數params是用來設置對應圖片格式的參數的,因為一般情況下這些圖片格式都是經過了壓縮的,這里就是設置這些壓縮參數來控制圖片的質量。該參數是一個vector<int>類型,里面分別存入paramId_1, paramValue_1, paramId_2, paramValue_2, ... 也就是說存入一對屬性值。如果不設置該參數的話,則程序會自動根據所保存的圖像格式采用一個默認的參數。

  本實驗中還用到了下面這個函數。

  template<...> _Tp saturate_cast(_Tp2 v)

  將參數v轉換成模板中的類型,比如說:

  uchar a = saturate_cast<uchar>(-100); 

 

  OpenCV知識點總結:

  Rect的構造函數中不能重載3個參數,比如左上角點的坐標,寬和高這時候應該改成4個,左上角點的坐標直接分開為2個寫,對應着了點的x和y。

 

  實驗結果

  程序執行后工程文件夾中顯示如下:

   

  說明截取圖像部分並保存是成功的。

 

  原圖像和截取原圖中間1/4大小的圖像如下:

   

 

  后台輸出如下:

  

  說明此時也保存成功了。

 

  生成的alpha表圖像顯示如下:

   

 

  實驗代碼及注釋

  main.cpp:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

Mat src;
Mat image;
string str = "./";

/*創建alpha表,整體偏紅色,左上角到右下角呈現從完全透明到完全不透明變化趨勢*/
void createAlphaMat(Mat &mat)
{
    for (int i = 0; i < mat.rows; ++i) {
        for (int j = 0; j < mat.cols; ++j) {
            Vec4b& rgba = mat.at<Vec4b>(i, j);
            rgba[0] = UCHAR_MAX;    //r分量一直最大,所以整體偏紅
            rgba[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
            rgba[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
            rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
        }
    }
}

int main()
{
    /*采用默認參數進行圖片的保存*/
    src = imread("test.jpg");
    imwrite(str+"原圖.jpg", src); //c版本中的保存圖片為cvSaveImage()函數,c++版本中直接與matlab的相似,imwrite()函數。
    imshow("src", src);
    Rect rect(src.cols/4, src.rows/4, src.cols/2, src.rows/2);
    image = src(rect);
    imwrite(str+"截取原圖中的一部分區域小圖.jpg", image);
    imshow("image", image);

    /*采用自己設置的參數來保存圖片*/
    Mat mat(480, 640, CV_8UC4);
    createAlphaMat(mat);
    vector<int> compression_params;
    compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
    compression_params.push_back(9);    //png格式下,默認的參數為3.
    try {
        imwrite("alpha.png", mat, compression_params);
    }
    catch (runtime_error& ex) {
        fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
        return 1;
    }
    fprintf(stdout, "Saved PNG file with alpha data.\n");

    waitKey(0);
    return 0;
}

 

 

  實驗總結

  Imwrite()函數可以保存截取出的圖像,但是這個函數使用時受限制太多,希望后面的版本對其進行加強。

 

 

  參考資料

     http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html?highlight=imwrite#bool imwrite(const string& filename, InputArray img, const vector<int>& params)

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM