天天看點

OpenCV中原始圖像加載與儲存壓縮技巧

加載圖像

OpenCV中關于圖像讀寫有兩個函數imread與imwrite,imread加載的時候支援灰階圖像、彩色圖像、原始圖像加載,預設情況下通過imread加載的圖像都是三通道的BGR彩色圖像。

但是實際上OpenCV支援加載任意通道的圖像,首先來仔細再看一下imread函數

Mat cv::imread(

    const String &  filename,

    int flags = IMREAD_COLOR 

)
           

在不修改第二個參數flags的預設值情況下,我們經常這樣使用該函數:

Mat image = imread("D:/images/test.png");
if (image.empty()) {

    printf("could not load image...\n");

    return -1;

}
           

當我們需要把加載圖像始終以灰階圖像出現時候:

Mat gray = imread("D:/images/dannis2.jpg", IMREAD_GRAYSCALE);
if (gray.empty()) {

    printf("could not load image...\n");

    return -1;

}
           

當我們需要把具有透明通道或者任意通道的圖像加載進來不做任何改變時候:

Mat anycolor = imread("D:/images/test1.png", IMREAD_ANYCOLOR);
if (anycolor.empty()) {

    printf("could not load image...\n");

    return -1;

}
           

儲存與壓縮圖像

一般情況下儲存圖像調用imwrite隻會設定兩個參數,但是實際上它還有第三個預設參數可以設定,這個參數可以幫助調整圖像的壓縮品質與儲存圖像的位圖深度與通道數目,當我們不想儲存為預設的三通道彩色圖像的時候,我們就需要使用第三個參數來對儲存圖像進行有針對性的寫入圖像檔案。首先我們需要重新認識一下imwrite這個函數。

bool cv::imwrite(

    const String & filename,

    InputArray img,

    const std::vector<int> & params = std::vector<int>()

)
           

參數解釋

filename

表示儲存檔案路徑與名稱,必須帶圖像檔案擴充名

img

記憶體中Mat對象

params

儲存圖像檔案時候需要優化的參數,預設為空

params解釋

對于第三個參數params來說,當我們儲存圖像為不同格式時候,params參數的内容也是不一樣的,當儲存圖像格式為PNG時候,調整壓縮品質參數為

IMWRITE_PNG_COMPRESSION 

等級為0~9之間,值越大壓縮時間越長,預設為1。值越大,圖像大小越小!

當儲存圖像格式為JPG時候,調整壓縮品質參數為

IMWRITE_JPEG_QUALITY 

等級為0~100之間,值越大圖像品質越高,預設為95。值越大,圖像大小也越大!

壓縮與儲存代碼示範

儲存為單通道灰階圖像

// 儲存為單通道灰階圖像
vector<int> opts;

opts.push_back(IMWRITE_PAM_FORMAT_GRAYSCALE);

imwrite("D:/gray.png", gray, opts);

opts.clear();
           

儲存為BGR彩色圖像

imwrite("D:/image.png", image);
           

儲存為PNG彩色壓縮圖像

Mat anycolor = imread("D:/images/test1.png", IMREAD_ANYCOLOR);
vector<int> opts;

opts.push_back(IMWRITE_PNG_COMPRESSION);

opts.push_back(9);

imwrite("D:/anycolor.png", anycolor, opts);
           

儲存為JPG高壓縮比圖像

Mat src = imread("D:/images/lovely-girl.jpg", IMREAD_COLOR);
vector<int> opts;

opts.push_back(IMWRITE_JPEG_QUALITY);

opts.push_back(50);

opts.push_back(IMWRITE_JPEG_OPTIMIZE);

opts.push_back(1);

imwrite("D:/src.jpg", src, opts);
           

lovely-girl.jpg原圖像大小:389KB

OpenCV壓縮儲存之後大小:128KB

對比壓縮前後的兩張圖,發現圖像品質并沒有明顯下降,證明OpenCV通過此方式可以有效降低圖像大小,在網絡傳輸時候節省帶寬資源!

儲存PNG帶透明通道的彩色圖像

// 儲存為四通道彩色圖像

Mat bgra;

cvtColor(anycolor, bgra, COLOR_BGR2BGRA);
int h = anycolor.rows;
int w = anycolor.cols;
for (int row = 0; row < h; row++) {

    for (int col = 0; col < w; col++) {

        Vec4b pixel = bgra.at<Vec4b>(row, col);

        pixel[3] = 127;

        bgra.at<Vec4b>(row, col) = pixel;

    }

}

imshow("alpha-demo", bgra);

opts.clear();

opts.push_back(IMWRITE_PAM_FORMAT_RGB_ALPHA);

imwrite("D:/bgra.png", bgra, opts);
           

總結

使用imread與imwrite兩個函數進行圖像讀寫的時候,特别需要注意預設的最後一個參數,它們可以有效的幫助開發者解決各種圖像加載與壓縮儲存需求。

原文釋出時間為:2018-11-08

本文作者:gloomyfish

本文來自雲栖社群合作夥伴“OpenCV學堂”,了解相關資訊可以關注“OpenCV學堂”。

繼續閱讀