【opencv】示例-imgcodecs_jpeg.cpp使用OpenCV库来创建和处理图像,并保存为不同JPEG采样因子的版本...

0e7f92201ca9f58feb5a735838d32b9f.png

上层-原始图像  下层:编码+解码后的lossy_img

f9c38587c00cf9897ae05af1e1e7f704.png

#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图像压缩效果的差异。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值