精华内容
下载资源
问答
  • 动态规划-图像压缩

    2020-10-30 20:43:50
    可参考:0016算法笔记——【动态规划】图像压缩问题 动态规划之--图像压缩
    展开全文
  • 支持压缩图片的大小,可以根据想要的高度进行压缩。也支持过大压缩变小。支持各种静态图片和gif动态图片。
  • 利用动态规划算法解决图形图像处理问题,用Java编写,代码经过调试健壮性良好
  • 动态图片制作与压缩

    千次阅读 2018-09-05 17:27:24
    gif压缩工具 https://ezgif.com/optimize

    10个有毒的设计神器 !

    毒性有多强?包你上瘾~

    这里写图片描述
    以下神器都是在线工具,无需下载,直接使用。

    NO.1双色图片生成器

    工具地址:duotone.shapefactory.co

    NO.2 故障艺术生成器

    工具地址:photomosh.com

    NO.3 炫光生成器

    工具地址:codepen.io/tsuhre/full/BYbjyg

    NO.4 镜像炫光生成器

    工具地址:weavesilk.com

    NO.5 渐变层生成器

    工具地址:codepen.io/pissang/full/geajpX

    NO.6 流动渐变层生成器

    工具地址:codepen.io/Yakudoo/full/rJjOJx/

    NO.7 体素生成器

    工具地址:demo.marpi.pl/biomes

    NO.8 图片体素化生成器

    工具地址:pissang.github.io/voxelize-image

    NO.9 剪纸风格生成器

    工具地址:pissang.github.io/papercut-box-art

    NO.10 万箭齐发背景生成器

    工具地址:wangyasai.github.io/Stars-Emmision

    具体详情信息参考:https://www.sohu.com/a/229383304_195127

    大部分gif 压缩工具只能压缩2Mb 以内的,大于2Mb的就要收费了,我找了一个国外好用的在线压缩工具

    gif制作工具 —– ScreenToGif (大小2MB多,开源免费功能很强大)
    https://www.screentogif.com/?l=zh_cn

    gif压缩工具
    https://ezgif.com/optimize

    简单制作的效果:

    这里写图片描述

    展开全文
  • 动态规划- 图像压缩

    2020-10-24 20:14:20
    前几天老师讲了下课本《计算机算法设计与分析》上的动态规划的一个问题,特地来这里实现下。 如果你提前知道了这个算法的背景,比如像素点啊,位长之类的概念,理解起来可能会比较好接受。 先将彩色图片转黑白图片...

    起因

    前几天老师讲了下课本《计算机算法设计与分析》上的动态规划的一个问题,特地来这里实现下。

    如果你提前知道了这个算法的背景,比如像素点啊,位长之类的概念,理解起来可能会比较好接受。

    先将彩色图片转黑白图片,然后按顺序像个贪吃蛇一样来回走,扫描出灰度值之后,如何压缩的过程。

    这个算法本身也有一定的难度,理解起来不太容易,不过按照定义直接推导也能实现出来,只是时间上的问题罢了。

    说起来还有点好笑的事,老师代码上写了灰度值序列10,12,15,255,1,2,经过压缩后的最小空间为:57

    擦,这比不压缩还大啊。

    不过不用担心,在日常生活上,照片上有很多像素点是冗余的,所以完全不必要质疑这个算法。只不过是因为数据选取的不够好的原因。

    代码方案和书上有所不同,但思路是相同的。

    代码如下

    #include <iostream>

    #include <algorithm>

    using namespace std;

    #define LMAX 256

    #define HEADER 11

    /**********************   Image_Compression  ************************

    /_____________________   图像压缩  _____________________ */

    // 函数声明

    int getBLength(int i);

    void printArray(int* array, int length);

    int Compress(int* p, int length);

    void output(int* Llength, int* BLength, int length);

    int Compress(int* p, int length, int* L, int* B);

    // main函数

    int main() {

        int p[] = { 0,10,9,12,40,50,35,15,12,8,10,9,15,11,130,160,240 };  //下标从1开始计数

        int length = sizeof(p) / 4;   // 求出数组长度

        printArray(p, length);  // 打印输入的 灰度值序列

        // 输入L[i]和B[i]

        int* Llength = new int[length]();//申请数组,下标从1开始计数

        int* Blength = new int[length]();//申请数组,下标从1开始计数

     

        cout << "该灰度值序列最小可压缩为: " << Compress(p, length, Llength, Blength) << endl;  // 对【灰度值序列】p进行压缩的函数

     

        // 上式 Llength[i] 存储了前i个灰度值后,当前最优排序方式的 灰度值元素数量, 即: 区间(i - Llength[i], i) 成为了一排

        // 上式 Blength[i] 存储了前i个灰度值后,当前最优排序方式下 灰度值的最大值, 即: 区间(i - Llength[i], i) 中最大的灰度值。

     

        output(Llength, Blength, length);  // 打印输出的 最优压缩方式,即 输出L[i]和B[i]

        system("pause");

        return 0;

    }

     

    int getBLength(int i) {   // 已知数字,求其所需最大二进制数的公式: 1 <= log[xi+1] <= 8

    // 返回灰度值i需要的存储位数 。

    // 例如:灰度值是0--1则返回1,灰度值是2--3则返回2,灰度值是4--7则返回3,... 灰度值是128--255则返回8

        int k = 1;

        i = i >> 1; 

        // >>1表示除于2。例子:4>>1 = 4/2。相比除法运算,位运算效率更高。

        while (i > 0) {

             k++;

             i = i >> 1;

        }

        return k;

    }

    /*  dp常规推导流程

    * 先下定义,不妨定义dp(i) 是灰度序列从【第1个】到【第i个】之间的最优压缩值

         定义bmax(i, j) 是灰度序列从【第i个】到【第j个】之间的最大的存储位数

    dp(1) = min (

        dp(0) + bmax(1,1) * 1,

    )  

     

    dp(2) = min (

        dp(1) + bmax(2, 2) * 1,

        dp(0) + bmax(1, 2) * 2,

     

    dp(3) = min (

        dp(2) + bmax(3, 3) * 1,

        dp(1) + bmax(2, 3) * 2,

        dp(0) + bmax(1, 3) * 3

    )

     

    dp(4) = min (

        dp(3) + bmax(4, 4) * 1,

        dp(2) + bmax(3, 4) * 2,

        dp(1) + bmax(2, 4) * 3,

        dp(0) + bmax(1, 4) * 4

    )

    ……

     

    dp(7) = min (

        dp(6) + bmax(7, 7) * 1,

        dp(5) + bmax(6, 7) * 2,

        dp(4) + bmax(5, 7) * 3,

        dp(3) + bmax(4, 7) * 4,

        dp(2) + bmax(3, 7) * 5,

        dp(1) + bmax(2, 7) * 6

        dp(0) + bmax(1, 7) * 7

    )

     

    dp(8) = min (

        dp(7) + bmax(8, 8) * 1

        dp(6) + bmax(7, 8) * 2,

        dp(5) + bmax(6, 8) * 3,

        dp(4) + bmax(5, 8) * 4,

        dp(3) + bmax(4, 8) * 5,

        dp(2) + bmax(3, 8) * 6,

        dp(1) + bmax(2, 8) * 7

        dp(0) + bmax(1, 8) * 8

    )

    通过上述的推导,不难发现规律,求dp[i]时,总是从dp[i-1]开始,一直到dp[0]

    而bmax则容易发现,永远都是 bmax(j, i) 【j属于[1,i]】, 而右边的 * 次数,其数字结果总是 i - j;

    dp(i) = min (

        dp(i-1) + bmax(i, i) * (  i-(i-1) ),

        dp(i-2) + bmax(i-1, i) * (  i-(i-2) ),

        ……

        dp(i-(i-1)) + bmax(i-(i-2), i) * (  i- (i-(i-1))  ),

        dp(i-i) + bmax(i-(i-1), i) * ( i - (i-i) )

    )

     

    但是,很容易发现,bmax(i,j)该如何实现呢?或者说,我们需要做出一个数组或者用函数封装起来调用吗?

    事实上,通过观察数字之间的关系,很容易发现一个规律:直接拿到第i个数据后,直接和前边的比较,以此类推,不就能完美解决这个方法了吗?

     

    因此,经过上述推导后,很容易能理解下述代码。

    *

    */

     

     

    // 此函数重载了Compress(int* p, int length)

    int Compress(int* p, int length, int* L, int* B) {

        int* dp = new int[length]();//下标从1开始计数

        // 定义dp[i] 是灰度序列从【第1个】到【第i个】之间的最优压缩值

        int Bmax = getBLength(p[1]); // getBLength把该灰度值作为参数传入,返回这个灰度值所需的存储位数, 先把第一个灰度值所需的存储位数传给Bmax

        for (int i = 1; i < length; i++) {

             int Min = INT_MAX;    // <algorithm>下定义的一个常量,即:int所能存取的最大值

             for (int j = i - 1; j >= 0; j--) {

                 int tmp = getBLength(p[j + 1]);

                 if (tmp > Bmax)       Bmax = tmp;   // 如果发现 新的灰度值的存储位数 > 原先的灰度值的存储位数,则替换

                 if (i - j > LMAX) continue;       // 如果这段长度是> 规定长度(256),则跳出

                 if ((dp[j] + Bmax * (i - j)) < Min) { // dp[j] + Bmax * (i - j):即前j个最小压缩值 + (i-j)个所需的最大存储位数

                     Min = dp[j] + Bmax * (i - j);    // Min 和 dp[j] + Bmax * (i - j)进行比较,返回最小值。

                     L[i] = i - j;    // 存储 序列长度进入L数组

                     B[i] = Bmax;  // 存储 (i-j) 到 i 之间的最大存储位数

                 }

             }

             dp[i] = Min + HEADER// bit位(3)和length(8)位加上头部

             Bmax = 0;  // 清零  如若不置换,且Bmax在dp(i)情况下已经置为8,则影响不到后面Bmax的变化!Bmax将锁死在8

        }

        return dp[length - 1];   // 因为0不在考虑范围,需要减1;

        // 举例: 灰度值序列length = 3 分别是0 15 5, 则因为第0位不用补0,所以只需要返回dp[2]; 即  dp[length - 1]

    }

     

    int Compress(int* p, int length) {     // 这是没有存储L和B的,只能返回最小压缩长度

        int* dp = new int[length](); //下标从1开始计数

        // 定义dp[i] 是灰度序列从1到i的最优压缩值

        int Bmax = getBLength(p[1]);   // getBLength把该灰度值作为参数传入,返回这个灰度值所需的存储位数, 先把第一个灰度值所需的存储位数传给Bmax

        for (int i = 1; i < length; i++) {

             int Min = INT_MAX;   // <algorithm>下定义的一个常量,即:int所能存取的最大值

             for (int j = i - 1; j >= 0; j--) {

                 int tmp = getBLength(p[j+1]);

                 if (tmp > Bmax) Bmax = tmp;  // 如果发现 新的灰度值的存储位数 > 原先的灰度值的存储位数,则替换

                 if (i - j > LMAX) continue;   // 如果这段长度是> 规定长度(256),则跳出

                 Min = min(dp[j] + Bmax * (i-j), Min); // <algorithm>下定义的一个函数,两个参数进行比较,返回最小值。

             }

             dp[i] = Min + HEADER; // 11:压缩后的序列,前11位是告知接下来读取几位,并以什么样的方式去读写的。

                              //如:B=6 L=4 则读取 4个长度,以一个长度占6位来读写 (B缩写:Bits per pixel, L缩写: lengths of segment i )

             Bmax = 0;  // 一个循环之后,再跳入下一个循环之前,即此时dp(i)求出,将要进入求dp(i-1)的循环

                     // 需要将Bmax置为0,如若不置换,且Bmax在dp(i)情况下已经置为8,则影响不到后面Bmax的变化!Bmax将锁死在8

        } 

        return dp[length - 1];  // 因为0不在考虑范围,需要减1; 举例: 灰度值序列length = 3

    }

     

    void output(int* Llength, int* BLength, int length) {

        // 1. 首先需要算出到底分了几段,我这里设分了m段

        int m = 0;

        int t = length - 1;   // t是辅助变量,无实际意义

        while (t > 0) { 

             m++; 

             t = t - Llength[t];  // 这里已经分完一段,这段长度是 Llength[t]; 分完之后,把t往前移动,因为已经划分出了Llength[t]个长度了,所以需要减掉这个长度

        } // 举例:length = 17, t = 16, Llength[16] = 3; 把 长度为3,下标从14 - 16的划分出去,则原序列剩下 1 - 13,以此类推

        int* L = new int[m + 1]();  //申请数组存放每段的长度,下标从1开始计数

        int* B = new int[m + 1]();  //申请数组存放每段的最大存储位数,下标从1开始计数

     

        t = length - 1;  // t 重新赋值

        for (int i = m; i >= 1; i--) {  // 从后往前推出L和B的值

             L[i] = Llength[t];  

             B[i] = BLength[t];  

             t = t - Llength[t];   // 这段的B和L求出来之后,需要减掉这个已经求出值来的长度

        }

        for (int i = 1; i <= m; i++) {

             cout << "第" << i << "段长度:" << L[i] << ",所需存储位数:" << B[i] << endl;

        }

     

    }

    // 打印数组

    void printArray(int* array, int length) {

        cout << "【 ";

        for (int i = 1; i < length; i++) {

             cout << array[i] << " ";

        }

        cout << "】 " << endl;

    }

     

    控制台输出:

    【 10 9 12 40 50 35 15 12 8 10 9 15 11 130 160 240 】

    该灰度值序列最小可压缩为: 121

    第1段长度:6,所需存储位数:6

    第2段长度:7,所需存储位数:4

    第3段长度:3,所需存储位数:8

    请按任意键继续. . .

    展开全文
  • 跟贾冉一同合作的成果。她花了很多心思做的ppt。上传以做纪念。...该资源是算法设计与分析课程中对于图像压缩动态规划算法的课件。属于原创型。现上传与大家一同分享。也算是对jr与gavin的劳动成果的一种肯定
  • php 动态读取图片 动态裁剪 压缩 返回流或生成图片
  • 近期看了一篇高动态范围红外图像压缩的文章,《New technique for the visualization of high dynamic range infrared images》.这篇文章主要利用双边滤波器把宽动态红外图像切割为基本图像和细节图像,再分别对基本...

    BF&DRC

    近期看了一篇高动态范围红外图像压缩的文章,《New technique for the visualization of high dynamic range infrared images》.这篇文章主要利用双边滤波器把宽动态红外图像切割为基本图像和细节图像,再分别对基本图像和细节图像进行处理。对处理后的图像进行融合处理。
    传统的宽动态图像压缩到256可视图像,一般採用线性的方法,该方法得到的图像细节不好,因此眼下有非常多复杂的方法来对宽动态范围图像进行操作处理。而处理的准则一般例如以下:

    1. 压缩大梯度;
    2. 增强具有小对照度的纹理;
    3. 可视化效果好,避免人工噪声;
      BF&DRP的结构图例如以下:
      这里写图片描写叙述
      BF:双边滤波器对高动态红外图像进行滤波,双边滤波器例如以下:
      这里写图片描写叙述
      s(x,y)——低通滤波器;
      这里写图片描写叙述——输入图像;
      这里写图片描写叙述——滤波器输出图像;
      这里写图片描写叙述——权重函数;
      这里写图片描写叙述——归一化;
      双线性滤波器一般选用这里写图片描写叙述的滑动窗,权重函数这里写图片描写叙述选用高斯函数,标准差为这里写图片描写叙述依据例如以下公式进行计算:
      这里写图片描写叙述
      这里写图片描写叙述
      双边滤波器得到基本图像这里写图片描写叙述,细节图像这里写图片描写叙述这里写图片描写叙述
      分别对基本图像和细节图像进行gamma矫正。矫正參数分别为这里写图片描写叙述,矫正參数必须依据不同标准进行选择,细节须要加强,所以这里写图片描写叙述一般在1和2之间,基本图像须要压缩所以这里写图片描写叙述
      同意一定比例像素饱和參数分别为这里写图片描写叙述,參数一般默觉得0.01,也就是低和高密度的像素饱和度为1%。饱和过程可以减少神秘值对图像产生的影响,避免了图像产生较大的视觉改变。
      对基本图像和细节图像分别处理之后。对两幅图像进行融合。融合採用DRC的方法。假设输出的是Mbits(一般M=8),细节是这里写图片描写叙述级,基本图像部分是这里写图片描写叙述级。当中这里写图片描写叙述
      文中的參数:
      这里写图片描写叙述这里写图片描写叙述

    GIF&DDE

    近期開始研究高动态范围的图像压缩。看了几篇文章。怕看完了就不记得了,所以在这把文章的核心思想和主要操作过程进行整理。方便以后查阅。GIF&DDE是我给作者起的,參阅的文章是《Detail enhancement for high-dynamic-range infrared images based on guided imagee filter》.
    作者以BF&DDE结构为基准。採用GIF滤波器对原图分成base layer和details layer,在分别对这两部分进行处理。最后对处理后的图像进行融合,作者的算法结构图例如以下:
    这里写图片描写叙述
    Raw Image:输入图像
    Guided Image Filter:滤波器,该滤波器处理速度快,而且是非预计的线性规则,计算复杂度与滤波器核尺寸不相关。

    这里写图片描写叙述
    这里写图片描写叙述是以(x,y)为中心的滤波窗内的像素点。
    这里写图片描写叙述,权重核,权重系数来强化细节。
    这里写图片描写叙述
    这里写图片描写叙述是窗这里写图片描写叙述内像素的个数
    这里写图片描写叙述方窗的半径;
    这里写图片描写叙述是输入图像在这里写图片描写叙述内的均值和方差
    这里写图片描写叙述描写叙述滤波器平滑程度的參数;
    线性滤波器输出可以表示为例如以下:
    这里写图片描写叙述
    这里写图片描写叙述
    这里写图片描写叙述和窗体尺寸决定细节获取的程度,窗体尺寸越大。图像越模糊,窗体尺寸和这里写图片描写叙述值都大,则背景会忽略了一些结构信息,更关注强边缘信息,为了我们的应用处理。一般採用小窗体大这里写图片描写叙述


    Histogram Projection
    为了保证输出图像会有一个均匀分布,对基础图像部分採用直方图操作。二值化的直方图操作例如以下:
    这里写图片描写叙述
    这里写图片描写叙述是灰度值x像素的个数
    这里写图片描写叙述提高图像整个对照度,一般选择为所有像素个数的0.1%,输出的直方图效果较好。累积分布函数定义例如以下:
    这里写图片描写叙述
    输出图像为这里写图片描写叙述
    这里写图片描写叙述表示固定灰度级像素的总量
    这里写图片描写叙述表示输出的bit数
    假设背景单一,比如单一的墙或天空。固定的灰度值可能会非常小,获取会小于10。在这样的情况下,输出的8bit的可视图像可能会充满噪声。则输出图像函数公式更改为[12],例如以下:
    这里写图片描写叙述
    这里写图片描写叙述调节输出亮度的控制參数。
    这里写图片描写叙述输出范围R将会被压缩。
    这里写图片描写叙述适当的添加,输出图像会更适合显示;
    Mask Gain Enhancement
    细节图像通过原图与滤波后的基础图像相减得到
    这里写图片描写叙述
    通过核函数
    这里写图片描写叙述
    来获得图像哪部分须要增强
    这里写图片描写叙述决定图像哪些区域被增强,哪些区域被忽略。该值小,则增强的区域大。噪声有可能被增强了。该值大,缩小了增强的区域,噪声得不到增强的同一时候有可能细节也会被忽略了,一般选用500.
    这里写图片描写叙述选用这里写图片描写叙述
    一般平坦区域W(i,j)的值趋近于0,当W(i,j)大于1.2时。该值为1.2,绝大多数时候该值小于1.输出的细节部分计算例如以下
    这里写图片描写叙述
    当中文章中这里写图片描写叙述
    图像融合
    这里写图片描写叙述

    转载于:https://www.cnblogs.com/cxchanpin/p/7212613.html

    展开全文
  • 动态规划——图像压缩

    千次阅读 2016-05-03 20:35:11
    下面以图像压缩问题为例浅析动态规划算法在图像压缩中的应用,其关键在于如何通过对灰度序列的分段寻找最优存储结构。 问题:在计算机中常用像素点灰度值序列{P1,P2, … ,Pn}表示图像。其中整数Pi,1,表示像素点i的...
  • 这里写自定义目录标题动态规划之图像压缩问题问题描述最优子结构最优子结构的性质插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表...
  • ngx-fastdfs:nginx lua fastdfs 实现分布式图片实时动态压缩
  • 计算压缩图像的嵌入容量,在嵌入容量限制下,根据目标图像动态地计算最优的维纳滤波器对称性、精度等参数并将参数嵌入JPEG压缩图像中,并对解码图像使用提取的维纳滤波器进行滤波增强,获得与原图像接近的解压缩图像...
  • 动态规划——图像压缩问题 问题: 图象压缩问题要求确定象素序列{p1 ,p2 ,…,pn}的最优分段,使得依此分段所需的存储空间最少。每个分段的长度不超过256位。 问题描述比较复杂,复习时间比较紧张,此处不贴了。 分析...
  • 为了进一步增强观察人员对气体泄漏红外图像的细节感知, 等效提高系统探测极限, 提出一种基于双边滤波的气体泄漏红外图像动态压缩及增强方法, 以气体泄漏红外图像特点为依据, 对双边滤波和压缩合并过程进行控制, 实现...
  • 图像压缩算法欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右...
  • 动态规划--图像压缩

    2020-01-26 17:59:25
    1)问题描述 2)基本思路 3)代码实现 import java.util.Scanner; public class example { ... * @param n 图像灰度数组的大小 ... * @param s s[i]表示从0到i压缩为一共占多少存储空间 * @param l l代表l...
  • 图像压缩---动态规划

    千次阅读 2019-06-26 20:26:05
    转载自:动态规划之–图像压缩 1.1问题描述 图像压缩的问题我们是这样理解的:大家都知道计算机的图像是用灰度值序列来表示的{P1,P2…Pn},其中Pi表示像素点i的灰度值。而通常灰度值的范围是0~255,因此需要8位二...
  • 图像压缩1 问题描述2 问题分析5 递归子结构4 例题5 递归计算最优值6 核心代码 1 问题描述 2 问题分析 没有分段之前,固定的 每8位二进制 截取为一个像素点; 现在分段之后,看到一串二进制,我首先要知道多少位...
  • 一、螺杆式压缩机工作原理二、离心式压缩机离心式压缩机又称透平式压缩机,主要用来压缩气体,主要由转子和定子两部分组成:转子包括叶轮和轴,叶轮上有叶片、平衡盘和一部分轴封;定子的主体是气缸,还有扩压器、...
  • /** * @author: * @description: 图像压缩动态规划算法 * @date: Created in 2020/4/16 0:05 * @ersion: 1.0 */ public class Work8 { public Work8(){ int[] img = { 1, 10, 12, 255, 255, 1, 2, 1, 1, 2, 2, 1,...
  • 图形的压缩简介 详细说明 最优子结构性质 举例 代码块 测试结果 图形的压缩简介在计算机中常用像素点灰度值序列{p1,p2,….,pn}表示图像。其中,整数pi(1)表示像素点i的灰度值。 灰度值的范围是0~255。因此需要用8位...
  • 动态规划-图像压缩问题

    千次阅读 2017-11-26 20:54:22
    压缩的原理就是把序列{p1,p1,……pn}进行设断点,将其分割成一段一段的。分段的过程就是要找出断点,让一段里面的像素的最大灰度值比较小,那么这一段像素(本来需要8位)就可以用较少的位(比如7位)来表示

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,803
精华内容 1,121
关键字:

压缩动态图