You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OpenCV+C++实现JPEG时浮点转无符号类型后结果异常求助

问题:OpenCV+C++实现JPEG压缩的DCT转换异常问题

在使用OpenCV和C++实现JPEG压缩时遇到以下问题:

  • 编码器执行DCT后,将32位浮点平面转换为8位无符号类型时,输出结果异常,甚至原图像也受影响(尚未实现量化模块);
  • 改为转换为16位无符号类型后,原图像不受影响,但解码结果仍不合格。

相关代码

constexpr int blocksize = 8;

struct block {
    cv::Rect roi;
    cv::Mat subimage;
};

int main()
{
    // 读取图像并存储必要信息
    std::string addr("C:\\Users\\lena.jpg");
    const cv::Mat img = cv::imread(addr, cv::IMREAD_COLOR);
    if (img.empty()) {
        std::cerr << "Could not open the image!" << std::endl;
        return -1;
    }
    int height = img.size().height;
    int width = img.size().width;
    std::cout << "width * height: " << width << " * " << height << std::endl;

    // 构建8x8块
    std::vector<block> blocks;

    for (int y = 0; y < height; y += blocksize){
        for (int x = 0; x < width; x += blocksize){
            int block_width = std::min(blocksize, width - x);
            int block_height = std::min(blocksize, height - y);
            block temp;
            cv::Rect newROI(x, y, block_width, block_height);
            temp.roi = newROI;
            temp.subimage = img(newROI);
            blocks.push_back(temp);
        }
    }
    // 离散余弦变换与量化(未实现量化)
    for (int bIdx = 0; bIdx < blocks.size(); ++bIdx) {
        std::vector<cv::Mat> planes;
        cv::split(blocks[bIdx].subimage, planes);

        std::vector<cv::Mat> resultPlanes(planes.size());
        for (int k = 0; k < planes.size(); ++k) {
            planes[k].convertTo(planes[k], CV_32FC1);

            cv::dct(planes[k], resultPlanes[k]);
            // 此处为问题提及的转换代码行
            resultPlanes[k].convertTo(resultPlanes[k], CV_8UC1);
        }
        cv::merge(resultPlanes, blocks[bIdx].subimage);
    }

    // 逆DCT与量化(未实现量化)
    for (int bIdx = 0; bIdx < blocks.size(); ++bIdx) {
        std::vector<cv::Mat> planes;
        cv::split(blocks[bIdx].subimage, planes);

        std::vector<cv::Mat> resultPlanes(planes.size());
        for (int k = 0; k < planes.size(); ++k) {
            planes[k].convertTo(planes[k], CV_32FC1);
            cv::idct(planes[k], resultPlanes[k]);
            
            resultPlanes[k].convertTo(resultPlanes[k], CV_8UC1);
        }
        cv::merge(resultPlanes, blocks[bIdx].subimage);
    }

    // 重建完整图像
    cv::Mat modifiedImg = img.clone();
    for (int bIdx = 0; bIdx < blocks.size(); ++bIdx) {
        blocks[bIdx].subimage.copyTo(modifiedImg(blocks[bIdx].roi));
    }

    // 显示结果
    cv::imshow("JPEG", img);
    cv::imshow("My JPEG", modifiedImg);
    cv::waitKey(0);
}

效果截图

原图像
8位转换后的解码结果
16位转换后的解码结果

内容的提问来源于stack exchange,提问作者BlvckRazer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 11:35:19