上层-原始图像 下层:编码+解码后的lossy_img
#include <opencv2/core.hpp> // 包含OpenCV核心功能的头文件
#include <opencv2/imgproc.hpp> // 包含OpenCV图像处理功能的头文件
#include <opencv2/imgcodecs.hpp> // 包含OpenCV图像编码解码功能的头文件
#include <iostream> // 包含标准输入输出流的头文件
#include <vector> // 包含标准模板库中的向量容器的头文件
using namespace std; // 使用标准命名空间
using namespace cv; // 使用OpenCV命名空间
int main(int /*argc*/, const char** /*argv*/) // 主函数入口
{
Mat framebuffer(160 * 2, 160 * 5, CV_8UC3, cv::Scalar::all(255)); // 创建一个320x800的8位3通道图像,初始为全白
Mat img(160, 160, CV_8UC3, cv::Scalar::all(255)); // 创建一个160x160的8位3通道图像,初始为全白
// 创建测试图像
{
const Point center(img.rows / 2, img.cols / 2); // 计算图像中心点
for (int radius = 5; radius < img.rows; radius += 3) // 从半径为5开始,到图片高度结束,以3为步长绘制圆
{
cv::circle(img, center, radius, Scalar(255, 0, 255)); // 在图像上绘制紫色的圆形
}
cv::rectangle(img, Point(0, 0), Point(img.rows - 1, img.cols - 1), Scalar::all(0), 2); // 绘制黑色边框的矩形
}
// 绘制原始图像
int top = 0; // 上面的图像
{
for (int left = 0; left < img.rows * 5; left += img.rows) // 从左到右依次复制原始图像
{
Mat roi = framebuffer(Rect(left, top, img.rows, img.cols)); // 在帧缓冲中定义一个感兴趣的区域
img.copyTo(roi); // 将原始图像复制到感兴趣的区域
cv::putText(roi, "original", Point(5, 15), FONT_HERSHEY_SIMPLEX, 0.5, Scalar::all(0), 2, 4, false); // 在每个图像上标记“original”文字
}
}
// 绘制损失压缩的图像
top += img.cols; // 下面的图像
{
struct test_config { // 定义测试配置的结构体
string comment;
uint32_t sampling_factor;
} config[] = {
{"411", IMWRITE_JPEG_SAMPLING_FACTOR_411},
{"420", IMWRITE_JPEG_SAMPLING_FACTOR_420},
{"422", IMWRITE_JPEG_SAMPLING_FACTOR_422},
{"440", IMWRITE_JPEG_SAMPLING_FACTOR_440},
{"444", IMWRITE_JPEG_SAMPLING_FACTOR_444},
};
const int config_num = 5; // 定义配置数量
int left = 0;
for (int i = 0; i < config_num; i++) // 遍历所有配置
{
// 用采样因子参数压缩图像
vector<int> param;
param.push_back(IMWRITE_JPEG_SAMPLING_FACTOR); // 指定压缩参数
param.push_back(config[i].sampling_factor);
vector<uint8_t> jpeg;
(void)imencode(".jpg", img, jpeg, param); // 将图像编码为JPEG格式
// 解压缩图像
Mat jpegMat(jpeg);
Mat lossy_img = imdecode(jpegMat, -1); // 将JPEG数据解码回图像格式
// 复制到帧缓冲并评论
Mat roi = framebuffer(Rect(left, top, lossy_img.rows, lossy_img.cols)); // 定义感兴趣的区域
lossy_img.copyTo(roi); // 将损失压缩的图像复制到帧缓冲
cv::putText(roi, config[i].comment, Point(5, 155), FONT_HERSHEY_SIMPLEX, 0.5, Scalar::all(0), 2, 4, false); // 在图像上标记采样因子
left += lossy_img.rows; // 移动到下一个位置
}
}
// 输出帧缓冲(无损压缩)
imwrite("imgcodecs_jpeg_samplingfactor_result.png", framebuffer); // 将帧缓冲保存为PNG文件
return 0; // 程序正常退出
}
该段代码主要演示了如何使用OpenCV库来创建和处理图像,并保存为不同JPEG采样因子的版本。它首先创建了一个原始的白色图像,并在其上绘制了紫色圆形及黑色边框。然后,代码使用不同的JPEG采样因子参数对图像进行了压缩,并将压缩后的图像保存到一个大的帧缓冲中,这个帧缓冲最终会展示所有原始图像和不同采样模式下的压缩图像。最后,帧缓冲被保存为一个PNG文件。此代码用于测试和展示JPEG图像压缩效果的差异。