图像处理一直是计算机视觉中的一个重要领域,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
微信扫一扫
支付宝扫一扫