詳解cv::imdecode函數

圖像處理一直是計算機視覺中的一個重要領域,opencv作為開源的計算機視覺庫,實現了很多經典的圖像處理演算法。其中,cv::imdecode函數是非常重要的一個函數,它能夠將存儲在內存中的圖像解碼成opencv的Mat數據類型。這篇文章將從不同的角度對這個函數進行詳細的講解。

一、使用cv::imdecode函數讀取圖片文件

cv::imdecode函數最常見的用法是讀取圖片文件。它可以將圖片文件讀取到內存中,並將其解碼為opencv的Mat格式。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
    string img_path = "test.png";
    vector<uchar> img_data;
    Mat img;

    // 讀取圖片文件到內存中
    ifstream in(img_path, std::ios::binary);
    in.unsetf(std::ios::skipws); // 不跳過空白字元
    streampos file_size;
    in.seekg(0, ios::end);
    file_size = in.tellg();
    in.seekg(0, ios::beg);
    img_data.reserve(file_size);
    img_data.insert(img_data.begin(),
                    istream_iterator<uchar>(in),
                    istream_iterator<uchar>());
    in.close();

    // 解碼圖片並顯示
    img = imdecode(img_data, CV_LOAD_IMAGE_COLOR);
    imshow("Image", img);
    waitKey(0);

    return 0;
}

上述代碼中,我們首先讀取了一張圖片文件到內存中,然後將其解碼為opencv的Mat格式,並使用imshow函數顯示圖片。這是最常見的使用cv::imdecode函數的方式,它對於讀取網路上的圖片等場景非常方便。

二、使用cv::imdecode函數解碼編碼過的圖像

有一些場景下,圖像在傳輸過程中可能會進行編碼。比如,JPEG圖像和PNG圖像就是經過編碼的。在這種情況下,我們可以使用cv::imdecode函數將編碼後的圖像解碼為opencv的Mat格式。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
    string img_path = "test.jpg";
    vector<uchar> img_data;
    Mat img1, img2;

    // 讀取JPEG圖片文件到內存中
    ifstream in(img_path, std::ios::binary);
    in.unsetf(std::ios::skipws); // 不跳過空白字元
    streampos file_size;
    in.seekg(0, ios::end);
    file_size = in.tellg();
    in.seekg(0, ios::beg);
    img_data.reserve(file_size);
    img_data.insert(img_data.begin(),
                    istream_iterator<uchar>(in),
                    istream_iterator<uchar>());
    in.close();

    // 解碼JPEG圖片並顯示
    img1 = imdecode(img_data, CV_LOAD_IMAGE_COLOR);
    imshow("JPEG Image", img1);

    // 編碼圖像
    vector<int> params; // JPEG參數
    params.push_back(CV_IMWRITE_JPEG_QUALITY); // JPEG質量
    params.push_back(60); // 圖片質量,0~100
    imencode(".jpg", img1, img_data, params);

    // 解碼編碼後的JPEG圖片並顯示
    img2 = imdecode(img_data, CV_LOAD_IMAGE_COLOR);
    imshow("Encoded and Decoded JPEG Image", img2);
    waitKey(0);

    return 0;
}

上述代碼中,我們首先讀取了一張JPEG圖片文件到內存中,然後將其解碼為opencv的Mat格式並顯示。接著,我們將圖片編碼為JPEG格式,將編碼後的圖片重新解碼為opencv的Mat格式並顯示。這種方式可以用於測試編碼和解碼演算法。注意,這裡需要將編碼後的數據存儲到vector<uchar>類型中,因為它是不定長的。

三、使用cv::imdecode函數解碼從網路收到的圖像

在一些應用場景下,我們需要從網路中接收圖像,然後進行處理。這時,cv::imdecode函數也能夠非常方便地解碼從網路收到的圖像。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 
#include 

#pragma comment(lib, "ws2_32.lib")

using namespace std;
using namespace cv;

int main()
{
    string server_ip = "127.0.0.1";
    int server_port = 8080;
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
    sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(server_ip.c_str());
    server_addr.sin_port = htons(server_port);
    connect(sock, (sockaddr*)&server_addr, sizeof(server_addr));
    
    // 接收圖像數據並解碼成opencv的Mat格式
    vector<uchar> img_data;
    int img_size;
    recv(sock, (char*)&img_size, sizeof(img_size), 0);
    img_size = ntohl(img_size);
    img_data.resize(img_size);
    recv(sock, (char*)&img_data[0], img_size, 0);
    Mat img = imdecode(img_data, CV_LOAD_IMAGE_COLOR);

    imshow("Image", img);
    waitKey(0);

    closesocket(sock);
    WSACleanup();

    return 0;
}

上述代碼中,我們首先通過socket從伺服器接收一個圖像數據包。接著,將數據包的長度和內容存儲到img_size和img_data中,並使用cv::imdecode函數將其解碼成opencv的Mat格式,最後使用imshow函數顯示圖片。

四、使用cv::imdecode函數解碼指定格式圖片

除了讀取文件和解碼編碼過的圖像以外,cv::imdecode函數還能夠解碼指定格式的圖片。比如,如果我們要讀取一張20通道的圖像,就可以使用cv::imdecode函數解碼。這種情況下,我們需要先將圖像編碼成一種通用格式,比如JPEG或PNG。

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
    string img_path = "test.tif";
    vector<uchar> img_data;
    Mat img1, img2;

    // 讀取20通道的圖像文件到內存中
    ifstream in(img_path, std::ios::binary);
    in.unsetf(std::ios::skipws); // 不跳過空白字元
    streampos file_size;
    in.seekg(0, ios::end);
    file_size = in.tellg();
    in.seekg(0, ios::beg);
    img_data.reserve(file_size);
    img_data.insert(img_data.begin(),
                    istream_iterator<uchar>(in),
                    istream_iterator<uchar>());
    in.close();

    // 將20通道的圖像編碼為PNG格式
    vector<int> params; // PNG參數
    params.push_back(CV_IMWRITE_PNG_COMPRESSION); // PNG壓縮程度
    params.push_back(3); // 壓縮程度,0~9
    imencode(".png", Mat(100, 100, CV_8UC(20), Scalar(0)), img_data, params);

    // 解碼PNG格式的圖像並顯示
    img1 = imdecode(img_data, CV_LOAD_IMAGE_UNCHANGED);
    imshow("20-channel Image", img1);

    // 將20通道的圖像編碼為JPEG格式
    params.clear(); // 清空參數
    params.push_back(CV_IMWRITE_JPEG_QUALITY); // JPEG質量
    params.push_back(60); // 圖片質量,0~100
    imencode(".jpg", Mat(100, 100, CV_8UC(20), Scalar(0)), img_data, params);

    // 解碼JPEG格式的圖像並顯示
    img2 = imdecode(img_data, CV_LOAD_IMAGE_UNCHANGED);
    imshow("20-channel Image Encoded and Decoded", img2);
    waitKey(0);

    return 0;
}

上述代碼中,我們首先讀取了一張20通道的圖像文件到內存中。接著,我們將圖像編碼為PNG格式,並使用cv::imdecode函數將其解碼為opencv的Mat格式。同樣地,我們將圖像編碼為JPEG格式,並使用cv::imdecode函數將其解碼為opencv的Mat格式。這種方式可以用於特殊的圖像格式處理。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/188676.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-28 13:33
下一篇 2024-11-28 13:33

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字元串操作中,capitalize函數常常被用到,這個函數可以使字元串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • 單片機列印函數

    單片機列印是指通過串口或並口將一些數據列印到終端設備上。在單片機應用中,列印非常重要。正確的列印數據可以讓我們知道單片機運行的狀態,方便我們進行調試;錯誤的列印數據可以幫助我們快速…

    編程 2025-04-29
  • 三角函數用英語怎麼說

    三角函數,即三角比函數,是指在一個銳角三角形中某一角的對邊、鄰邊之比。在數學中,三角函數包括正弦、餘弦、正切等,它們在數學、物理、工程和計算機等領域都得到了廣泛的應用。 一、正弦函…

    編程 2025-04-29
  • Python3定義函數參數類型

    Python是一門動態類型語言,不需要在定義變數時顯示的指定變數類型,但是Python3中提供了函數參數類型的聲明功能,在函數定義時明確定義參數類型。在函數的形參後面加上冒號(:)…

    編程 2025-04-29
  • Python定義函數判斷奇偶數

    本文將從多個方面詳細闡述Python定義函數判斷奇偶數的方法,並提供完整的代碼示例。 一、初步了解Python函數 在介紹Python如何定義函數判斷奇偶數之前,我們先來了解一下P…

    編程 2025-04-29
  • Python實現計算階乘的函數

    本文將介紹如何使用Python定義函數fact(n),計算n的階乘。 一、什麼是階乘 階乘指從1乘到指定數之間所有整數的乘積。如:5! = 5 * 4 * 3 * 2 * 1 = …

    編程 2025-04-29
  • Python函數名稱相同參數不同:多態

    Python是一門面向對象的編程語言,它強烈支持多態性 一、什麼是多態多態是面向對象三大特性中的一種,它指的是:相同的函數名稱可以有不同的實現方式。也就是說,不同的對象調用同名方法…

    編程 2025-04-29
  • 分段函數Python

    本文將從以下幾個方面詳細闡述Python中的分段函數,包括函數基本定義、調用示例、圖像繪製、函數優化和應用實例。 一、函數基本定義 分段函數又稱為條件函數,指一條直線段或曲線段,由…

    編程 2025-04-29

發表回復

登錄後才能評論