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); }
效果截图



内容的提问来源于stack exchange,提问作者BlvckRazer
相关产品推荐
相关产品推荐

