关于图像压缩算法的困惑

时间:2011-07-31 17:48:52

标签: c++ algorithm visual-c++ image-processing

我一直在Image Compression (Lossy and Non-lossy)上阅读网页。

现在这是我的问题,我成功地使用opencv进行面部检测项目 - 但是 - 我的项目指南不满意 - 我的项目只是捕获来自Capture设备[webcam]的帧并传递功能中的帧检测这些帧中的Faces并在Windows中输出检测帧。

我的项目指南要求我实现一些图像压缩或变形等算法,但是对于看到图书馆的大量使用感到不满意 -

所以我想知道 - 是否可以使用C或C ++进行编码 - 图像压缩算法?如果是,那么代码大小不会很大吗? (我的项目应该是次要项目)

请帮帮我,假设我想用C ++使用RLE压缩,我应该怎么做呢?

5 个答案:

答案 0 :(得分:2)

您想发明自己的图像压缩还是实现其中一种标准压缩? (我假设这是某种类/作业,你不会在现实世界中这样做!)

你可以使用像Run-Length这样的东西来压缩简单的图像,特别是如果你可以减少颜色的数量,即。一个卡通或图形,但对于一个真正的照片风格的图像它是行不通的 - 这就是为什么发明了诸如jpeg或小波等复杂的有损技术。

答案 1 :(得分:1)

这很有可能,而且RLE压缩非常简单。如果你想看一个相对直接的RLE方法,它不会使用大量的代码,那么看看实现packbits的版本。

以下是另一个链接:http://michael.dipperstein.com/rle/index.html(包括传统RLE和packbits的源代码实现)

顺便说一下,请记住,使用RLE方案,使用嘈杂的数据,实际上最终会得到更多数据。对于大多数“真实世界”的图像,虽然应用了某种形式的低通滤波,并且具有相对较好的信噪比(即,高于40db),但您应该预计压缩率约为1.5:1到1.7:1

无损压缩的另一个选择是霍夫曼编码......该算法更能容忍噪声图像,因为它通常可以防止使用RLE压缩算法编码时这些类型的图像可能发生的数据扩展。

最后,你没有提到你是使用彩色或灰度图像...如果它是彩色图像,请记住,如果你在平面颜色通道中压缩每个颜色通道,你会发现更大的冗余图像,而不是尝试压缩连续的RGB数据。

答案 2 :(得分:0)

您希望使用空间填充曲线或空间索引实现基于颜色缩减的压缩。 A si将2d复杂度降低到1d复杂度,它看起来像四叉树,有点像分形。你想找尼克的希尔伯特曲线四叉树空间索引博客!

这是另一个有趣的RLE编码理念:Lossless hierarchical run length encoding。也许这适合你?

答案 3 :(得分:0)

RLE是去这里的最佳方式。即使是“最简单”的压缩算法也是非常重要的,需要深入了解颜色空间变换,离散正弦/余弦变换,熵等。

回到RLE ...循环使用pixesls使用类似的东西:

cv::Mat img = cv::imread("lenna.png");
for(int i=0; i < img.rows; i++)
    for(int j=0; i < img.cols; j++)
        // You can now access the pixel value with cv::Vec3b
        std::cout << img.at<cv::Vec3b>(i,j)[0] << " " << img.at<cv::Vec3b>(i,j)[1] << " " << img.at<cv::Vec3b>(i,j)[2] << std::endl;

计算一行中相似像素的数量并将它们存储在任何数据结构中(可能是< #Occurences, Vec3b >中的vector元组?)。获得最终vector之后,请不要忘记使用前面提到的vector(可能是简单的compressedImage结构)将图像的大小存储在某处,并且只是压缩了一个图片。要将其存储在文件中,我建议您使用boost::serialize或类似的东西。

您的最终结构可能类似于:

struct compressedImage {
  int height;
  int width;
  vector< pair<int, Vec3b> > data;
};

快乐的编码!

答案 4 :(得分:0)

如果需要抽象栅格类型,可以使用GDAL C ++库。以下是默认支持或请求栅格格式的列表:

http://gdal.org/formats_list.html