# Dynamic Planning - Example 7. Image Compression

#### 1. Title Description

A digitized image is an n*n array of pixels. Assuming that each pixel has a gray value of 0-255, it requires at most 8 bits to store a pixel.
To reduce storage space, a variable-length mode is used, that is, different pixels are stored in different bits, as follows:

• Image Linearization: Convert a nn-dimensional image to an N2 vector {p1,p2,...pn^2}
• Segmentation: divide the pixels into consecutive m-segments s1,s2,...sm so that the pixel storage bits in each segment are the same. Each segment is a collection of adjacent pixels and each segment contains a maximum of 256 pixels. If the pixels of the same bit exceed 256, it is represented by more than two segments.
• Create three tables
l: l[i] stores the length of section i, each item in the table is 8 bits long
B: b[i] stores the number of bits of pixels in the first segment, each of which is 3 bits long in the table.
P: {p1,...p n2} Binary string of pixels stored in variable length format.

If m segments are created, the space required to store the pixels in segment I is: **l[i] * b[i] + 11 **
(l[i] * b[i] denotes the information required by the segment itself, and 11 denotes the length of the segment, l[i], and how many bits each of the pixels represents b[i], that is, 3 + 8 = 11 bits)
The total storage space is 11m+l[i]*b[i];
The problem requires an optimal segment to be found. Minimize storage space.

Example:
Examine 4*4 images Let's optimize step by step:
1. No segmentation, no variable length compression.
Gray value sequence P:
00001010 00001001 00001100 00111000 00110010 00100011...
Total storage is:
16 * 8 = 128 bits

(2) Segments: [10, 9, 12], [40, 50, 35], [15, 12, 8, 10, 9, 15, 11], [130, 160, 240]
L={3，3， 7，3}；B={4，6，4，8}；
P contains 16 gray values, of which the first three are stored in 4 bits, the next three in 6 bits, the next seven in 4 bits, and the last three in 8 bits.
1010 1001 1100 111000 110010 100011 ...

The three tables require storage space:
L: 32 bits (4 * 8)
B: 12 bits (3 * 4)
P: 82 bits (4 * 3 + 6 * 3 + 4 * 7 + 8 * 3)
Total storage: 32 + 12 + 82 = 126 bits

(3) If we merge paragraphs 1 and 2, the corresponding three tables are updated to:
L={6, 7, 3}; B={6, 4, 8};
P: 001010 001001 001100 111000 110010 100011...
The rest remains unchanged.
The storage space of the three tables becomes:
L: 24 bits (3 * 8)
B: 9 bits (3 * 3)
P: 88 bits (6 * 6 + 4 * 7 + 8 * 3)
Total storage: 24 + 9 + 88 = 121 bits (reduced by 5 bits)

Therefore, the problem of image compression is to find an optimal segmentation scheme to minimize the total storage space.

#### 2. Solving problems

The idea of the algorithm is to turn it into a multi-step decision-making process, which first finds the optimal segment with one segment, then finds the optimal segment with two segments, and then finds the optimal segment with three segments.

##### 1. Optimal solution structure:

Set the best merge of N segments to C. If in merge C, the n-th segment is merged with n-1,n-2,...n-k+1 segments, then the merge of n-1,n-2,...n-k+1 segments is also optimal.
The space required for optimal merge C is:
Optimal merge space + Lsum(n-k+1,n) * Bmax(n-k+1,n)+11 for the first to n-k segments
Where Lsum(a, b)= , Bmax(a, b) = max{ B[a],..., B[b] }

##### 2. Recursive calculation of optimal values

If s[i] i s the best combined storage number for the first I segments, then:
s[i] = {s[i-k]+ lsum(i-k+1,i)*bmax(i-k+1,i) } +11

##### 3. Constructing the Optimal Solution

Construct the optimal solution: Note the value of K when k[i] i s the minimum value of s[i], and the corresponding optimal solution can be constructed from the value of K.
Compress uses l[i] and b[i] to record the information needed for the most segmentation. The length of the last segment of the most segmentation and the number of pixels are stored i n l[n], b[n], and the length and number of pixels of the previous segment are stored i n l[n-l[n], and b[n-l[n], respectively.
By analogy, l and b computed by the algorithm can construct corresponding optimal solutions in O(n) time.

The code is as follows:

```// image compression
#include<bits/stdc++.h>
using namespace std;
int length(int i)  //The number of storage bits required to calculate the pixel point p
{
int k = 1;
i = i/2;
while(i>0)
{
k++;
i = i/2;
}
return k;
}
void Compress(int n, int p[], int s[], int l[], int b[])  //Make s[i] the optimal combined number of storage bits for the first I segments
{
int Lmax = 256, header = 11;
s = 0;
for(int i=1; i<=n; i++)  //i denotes the first few paragraphs
{
b[i] = length(p[i]); //The number of storage bits required to calculate the pixel point p
int bmax = b[i];
cout<<i<<"bmax: "<<bmax<<endl;
s[i] = s[i-1] + bmax;  //So the following j starts from 2
l[i] = 1;
for(int j=2; j<=i && j<=Lmax; j++)   //Recursive relationships: s[i]= min (1<=j<=i) (lsum(i-j+1,i)<=256) {s[i-j]+ lsum(i-j+1,i)*bmax(i-j+1,i)} + 11
{
if(bmax < b[i-j+1])
bmax = b[i-j+1];
if(s[i] > s[i-j] + j*bmax)   //Since all sequences are not segmented at first, it can be seen that each segment is a number, so lsum(i-j+1, i) = j;
{
s[i] = s[i-j] + j*bmax;
l[i] = j;   //Optimal disconnect position, l[i] indicates that the optimal segment scheme for the first I segment should be disconnected at i-j such as l = 3, which means that the optimal segment for the first five segments should be disconnected at (5-3=2), s = s + 3*bmax
//That is, 12 | 345, and so on, l[n]; Then l[n] backtraces forward when constructing the optimal solution
}
}
}
}
void Traceback(int n, int &m, int s[], int l[])
{
if(n == 0) return;
Traceback(n-l[n], m, s, l);
s[m++] = n-l[n];  //Re-assign s[] array to store segment location
}
void Output(int s[], int l[], int b[], int n)
{
cout<<"The optimal value is "<<s[n]<<endl;
int m = 0;
Traceback(n, m, s, l);
s[m] = n;
cout<<"Decompose into "<<m<<" segments "<<endl;
for(int j=1; j<=m; j++)
{
l[j] = l[s[j]];
b[j] = b[s[j]];
}
for(int j=1; j<=m; j++)
cout<<"Segment Length:"<<l[j]<<" Required number of storage bits:"<<b[j]<<endl;
}
int main()
{
int n;
while(cin>>n && n)
{
int p[n+1];
int s[n+1], l[n+1], b[n+1];
for(int i=1; i<=n; i++)
cin>>p[i];
Compress(n, p, s, l, b);
int m=0;
Traceback(n, m, s, l);
Output(s, l, b, n);
memset(p, sizeof(p), 0);
}
system("pause");
return 0;
}
```

Run result: This article refers to my teacher Bi Fangming's Courseware Algorithmic Design and Analysis.
Welcome to my personal blog-- George's programming cabin And join me in offer ing for the big factory!

Tags: Dynamic Programming

Posted on Tue, 30 Nov 2021 16:32:25 -0500 by Mr_Mako