详解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/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

发表回复

登录后才能评论