Image Compression MATLAB Code outputs pixellated image? - image

I would really appreciate it if anyone could point out the mistakes in my code. I am trying to encode and decode an image by reading it in, performing DCT, Quantization then dequantizing it and performing inverse DCT. After running this code, the output Image, I2 is kind of pixellated. I have no idea how to fix it. The output should be somewhat similar to the original image but slightly blurred as it has undergone compression. Please help! My code is as follows :-
I = imread('cameraman.tif');
I = im2double(I);
T = dctmtx(8); % dct matrix
%Performing DCT on blocks of 8 by 8
dct = #(block_struct) T * block_struct.data * T';
B = blockproc(I,[8 8],dct);
B = ceil(B);
% A Standard Quantization Matrix
q_mtx = [16 11 10 16 24 40 51 61;
12 12 14 19 26 58 60 55;
14 13 16 24 40 57 69 56;
14 17 22 29 51 87 80 62;
18 22 37 56 68 109 103 77;
24 35 55 64 81 104 113 92;
49 64 78 87 103 121 120 101;
72 92 95 98 112 100 103 99];
%PErforming Quantization by Dividing with q_mtx on blocks of 8 by 8
c = #(block_struct) (block_struct.data) ./ q_mtx;
B2 = blockproc(B,[8 8],c);
% B2 = ceil(B2)
%Performing Inverse Quantization By Multiplying with q_mtx on Blocks of 8
%by 8
B3 = blockproc(B2,[8 8],#(block_struct) q_mtx .* block_struct.data);
%Performing Inverse DCT on Blocks of 8 by 8
invdct = #(block_struct) T' * block_struct.data * T;
% B3 = ceil(B3);
I2 = blockproc(B3,[8 8],invdct);
imshow(I), figure, imshow(I2)

Related

Nested for/while loop python triangle

Code
num = int(input(“Enter the number of lines: “))
for i in range(10):
for j in range(1,i):
print(num, the end='')
num = num+1
print()
I am writing a program which is should be like this.
Enter the number of lines: 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37
38 39 40 41 42 43 44
45 46 47 48 49 50
51 52 53 54 55
56 57 58 59
60 61 62
63 64
65
I don’t have any example from the lecturer, i just following the step from website, but the output of my code is like this: i am confused where i made the mistake, don’t get any clue to wear for or while. Please help me, thank you.
10
11 12
13 14 15
16 17 18 19
20 21 22 23 24
25 26 27 28 29 30
31 32 33 34 35 36 37
38 39 40 41 42 43 44 45
Try this:
input_data = input('Enter number of lines: ')
num = int(input_data)
# how many items to print in the first line?
items_to_print = num
# what's the starting number?
print_number = 11
for i in range(0, num):
# don't decrease num
# decrease items_to_print
# each line will reduce 1 item to print
for j in range(0, items_to_print):
print(print_number, end = ' ')
print_number += 1
print()
items_to_print -= 1
Result:
Enter number of lines: 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37
38 39 40 41 42 43 44
45 46 47 48 49 50
51 52 53 54 55
56 57 58 59
60 61 62
63 64
65
Explanation
Start small and make your way up.
First just do this:
input_data = input('Enter number of lines: ')
num = int(input_data)
print(num)
That'll print 10 if you entered 10. Great.
Second, add the first for loop and test whether it will print 10 rows.
input_data = input('Enter number of lines: ')
num = int(input_data)
for i in range(0, num):
print(f'Printing line {i}')
Third, try to print a block of 10 x 10. So, you add another variable called items_to_print. Set it to num. If you enter 10 as input, you will get 10 rows and 10 columns.
input_data = input('Enter number of lines: ')
num = int(input_data)
print_number = 0
items_to_print = num
for i in range(0, num):
print(f'Printing line {i}')
for j in range(0, items_to_print):
print(print_number, end = ' ')
Fourth step is to reduce the number of zeros printed before restarting the i loop. So, you decrement items_to_print.
input_data = input('Enter number of lines: ')
num = int(input_data)
print_number = 0
items_to_print = num
for i in range(0, num):
print(f'Printing line {i}')
for j in range(0, items_to_print):
print(print_number, end = ' ')
items_to_print -= 1
Now that your printing is working great, let's set print_number to start with 11 and each time a print happens in j loop, increment print_number. Then you will have same code I published at the top of this answer.
Well you have three little problems so let's address them one at a time.
First: default range function starts at 0 so when your j starts at one you are missing one iteration of the cicle. That explains missing one column and row but not two so let's keep going.
Second: the range function is non inclusive meaning you're I goes from 0 to 9 then in the inner loop you go from 1 to a maximum of 8. There's your missing second iteration.
Third: you are looping from 1 to an encreasing value what you want is the opposite so you need a decreasing range.
This is how you're code should look like.
num = 11
for i in range(10, 0, - 1):
for j in range(i):
print(num, end = " ")
num += 1
print()
Good luck and happy coding

Algorithm for visiting all grid cells in pseudo-random order that has a guaranteed uniformity at any stage

Context:
I have a hydraulic erosion algorithm that needs to receive an array of droplet starting positions. I also already have a pattern replicating algorithm, so I only need a good pattern to replicate.
The Requirements:
I need an algorism that produces a set of n^2 entries in a set of format (x,y) or [index] that describe cells in an nxn grid (where n = 2^i where i is any positive integer).
(as a set it means that every cell is mentioned in exactly one entry)
The pattern [created by the algorism ] should contain zero to none clustering of "visited" cells at any stage.
The cell (0,0) is as close to (n-1,n-1) as to (1,1), this relates to the definition of clustering
Note
I was/am trying to find solutions through fractal-like patterns built through recursion, but at the time of writing this, my solution is a lookup table of a checkerboard pattern(list of black cells + list of white cells) (which is bad, but yields fewer artifacts than an ordered list)
C, C++, C#, Java implementations (if any) are preferred
You can use a linear congruential generator to create an even distribution across your n×n space. For example, if you have a 64×64 grid, using a stride of 47 will create the pattern on the left below. (Run on jsbin) The cells are visited from light to dark.
That pattern does not cluster, but it is rather uniform. It uses a simple row-wide transformation where
k = (k + 47) mod (n * n)
x = k mod n
y = k div n
You can add a bit of randomness by making k the index of a space-filling curve such as the Hilbert curve. This will yield the pattern on the right. (Run on jsbin)
     
     
You can see the code in the jsbin links.
I have solved the problem myself and just sharing my solution:
here are my outputs for the i between 0 and 3:
power: 0
ordering:
0
matrix visit order:
0
power: 1
ordering:
0 3 2 1
matrix visit order:
0 3
2 1
power: 2
ordering:
0 10 8 2 5 15 13 7 4 14 12 6 1 11 9 3
matrix visit order:
0 12 3 15
8 4 11 7
2 14 1 13
10 6 9 5
power: 3
ordering:
0 36 32 4 18 54 50 22 16 52 48 20 2 38 34 6
9 45 41 13 27 63 59 31 25 61 57 29 11 47 43 15
8 44 40 12 26 62 58 30 24 60 56 28 10 46 42 14
1 37 33 5 19 55 51 23 17 53 49 21 3 39 35 7
matrix visit order:
0 48 12 60 3 51 15 63
32 16 44 28 35 19 47 31
8 56 4 52 11 59 7 55
40 24 36 20 43 27 39 23
2 50 14 62 1 49 13 61
34 18 46 30 33 17 45 29
10 58 6 54 9 57 5 53
42 26 38 22 41 25 37 21
the code:
public static int[] GetPattern(int power, int maxReturnSize = int.MaxValue)
{
int sideLength = 1 << power;
int cellsNumber = sideLength * sideLength;
int[] ret = new int[cellsNumber];
for ( int i = 0 ; i < cellsNumber && i < maxReturnSize ; i++ ) {
// this loop's body can be used for per-request computation
int x = 0;
int y = 0;
for ( int p = power - 1 ; p >= 0 ; p-- ) {
int temp = (i >> (p * 2)) % 4; //2 bits of the index starting from the begining
int a = temp % 2; // the first bit
int b = temp >> 1; // the second bit
x += a << power - 1 - p;
y += (a ^ b) << power - 1 - p;// ^ is XOR
// 00=>(0,0), 01 =>(1,1) 10 =>(0,1) 11 =>(1,0) scaled to 2^p where 0<=p
}
//to index
int index = y * sideLength + x;
ret[i] = index;
}
return ret;
}
I do admit that somewhere along the way the values got transposed, but it does not matter because of how it works.
After doing some optimization I came up with this loop body:
int x = 0;
int y = 0;
for ( int p = 0 ; p < power ; p++ ) {
int temp = ( i >> ( p * 2 ) ) & 3;
int a = temp & 1;
int b = temp >> 1;
x = ( x << 1 ) | a;
y = ( y << 1 ) | ( a ^ b );
}
int index = y * sideLength + x;
(the code assumes that c# optimizer, IL2CPP, and CPP compiler will optimize variables temp, a, b out)

How to rotate a centered hexagonal bitboard?

Consider the following centered hexagonal bitboard representation (padding is in boldface):
56
55 49
54 48 42
53 47 41 35
52 46 40 34 28
45 39 33 27
44 38 32 26 20
37 31 25 19
36 30 24 18 12
29 23 17 11
28 22 16 10 04
21 15 09 03
20 14 08 02 60
13 07 01 59
06 00 58
63 57
56
This representation fits in a 64-bit integer and allows for easy movement in the 6 hexagonal directions by rotating bits 1, 7 or 8 spaces to the right or to the left respectively. If it helps with visualization, you can deform this hexagon into a square:
42 43 44 45 46 47 48
35 36 37 38 39 40 41
28 29 30 31 32 33 34
21 22 23 24 25 26 27
14 15 16 17 18 19 20
07 08 09 10 11 12 13
00 01 02 03 04 05 06
Now, what I want to do is rotate this bitboard 60° clockwise, such that the [45,46,47,38,39,31] triangle becomes the [48,41,34,40,33,32] triangle, etc. How do I do this?
This permutation is kind of a mess, with every relevant bit having a distinct move-distance. The permutation diagram looks like this (top row is output):
That does suggest some approaches though. If we look near the top, every "group" is formed by gathering some bits from the input in ascending order, so it can be done with 7 compress_right operations aka PEXT which is efficient on Intel (not so efficient on AMD so far). What that really comes down to is sampling the vertical columns, so extracting bits with a stride of 8.
So if PEXT is acceptable, it could be done like this (not tested):
uint64_t g0 = _pext_u64(in, 0x8080808);
uint64_t g1 = _pext_u64(in, 0x404040404);
uint64_t g2 = _pext_u64(in, 0x20202020202);
uint64_t g3 = _pext_u64(in, 0x1010101010101);
uint64_t g4 = _pext_u64(in, 0x808080808080);
uint64_t g5 = _pext_u64(in, 0x404040404000);
uint64_t g6 = _pext_u64(in, 0x202020200000);
uint64_t out = g0 | (g1 << 7) | (g2 << 14) | (g3 << 21) |
(g4 << 28) | (g5 << 35) | (g6 << 42);
This permutation is not routable by a butterfly network, but Beneš networks are universal so that will work.
So it can be done with 11 of these permute steps, also known as delta swaps:
word bit_permute_step(word source, word mask, int shift) {
word t;
t = ((source >> shift) ^ source) & mask;
return (source ^ t) ^ (t << shift);
}
There is some choice in how to create the exact masks, but this works:
x = bit_permute_step(x, 0x1001400550054005, 1);
x = bit_permute_step(x, 0x2213223111023221, 2);
x = bit_permute_step(x, 0x01010B020104090E, 4);
x = bit_permute_step(x, 0x002900C400A7007B, 8);
x = bit_permute_step(x, 0x00000A0400002691, 16);
x = bit_permute_step(x, 0x0000000040203CAD, 32);
x = bit_permute_step(x, 0x0000530800001CE0, 16);
x = bit_permute_step(x, 0x000C001400250009, 8);
x = bit_permute_step(x, 0x0C00010403080104, 4);
x = bit_permute_step(x, 0x2012000011100100, 2);
x = bit_permute_step(x, 0x0141040000000010, 1);

The Traveling Salesman algorithm bug

I have tried to make an algorithm solving the traveling salesman problem as follows:
%main function:
[siz, ~] = size(table);
done(1:siz) = false;
done(1) = true;
[dist, path] = bruteForce(table, done, 1);
function bruteForce:
function [distance, path] = bruteForce(table, done, index)
size = length(done);
dmin = inf;
distance = 0;
path = [];
%finding minimum distance
for i = 1:size
if ~done(i)
done(i) = true;
%iterating through all nodes using recursion
[d, p] = bruteForce(table, done, i);
if (d < dmin)
dmin = d;
path = [i p];
distance = dmin + table(i, index);
end
%freing the node again
done(i) = false;
end
end
if distance == 0
distance = table(1, index);
path = 1;
end
Unfortunately, for the following matrix:
B = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
Instead of getting the expected result:
1-8-5-4-10-6-3-7-2-11-9-1 = 253km
I get:
1-8-11-3-4-6-10-5-9-2-7-1 = 271km
Could you help me find the bug?
If brute force is a must and speed is no issue, then just use the perms function for the number of cities. This allows for an easy implementation:
table = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
[siz, ~] = size(table);
[bp, b] = bruteForce(table, siz)
function [bestpath, best] = bruteForce(table, siz)
p = perms(1:siz);
[r, c] = size(p);
best = inf;
for i = 1:r
path = p(i, :);
dist = distCalculatorReturn(table, path);
if dist < best
best = dist;
bestpath = path;
end
end
bestpath = [bestpath, bestpath(1)];
end
function [totaldist] = distCalculatorReturn(distMatrix, proposedPath)
dist = 0;
i = 1;
while i ~= length(proposedPath)
dist = dist + distMatrix(proposedPath(i),proposedPath(i+1));
i = i+1;
end
dist = dist + distMatrix(proposedPath(1), proposedPath(end));
totaldist = dist;
end
This yields the answer you are looking for. However, if you are only solving problems of that size, why not apply a standard simulated annealing. This gives much faster solution times and should solve the problem size consistently:
table = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
[path, dist] = tsp(table, length(table))
function [path, dist] = tsp(D, n)
L = 40*n;
epsi = 1e-9;
x = randperm(n);
fx = distCalculatorReturn(D, x);
T = 1000000;
while T > epsi
for i=1:L
num1 = 1 + floor(rand*n);
num2 = 1 + floor(rand*n);
while num1 == num2
num1 = 1 + floor(rand*n);
end
y = x;
swap1 = y(num1);
y(num1) = y(num2);
y(num2) = swap1;
fy = distCalculatorReturn(D,y);
if fy < fx
x = y;
fx = fy;
elseif rand < exp(-(fy - fx)/T)
x = y;
fx = fy;
end
end
T = 0.9*T;
end
path = [x, x(1)];
dist = fx;
end
Your code does not compute the distance for each possible path (as bruteForce suggests). Instead it always starts at node 1 and from there goes always to the node that is closest to the current node. As your example shows, that does not necessarily lead to the overall shortest path. You will need to go through all possible paths to be sure you find the optimum.
Here is my go at your problem:
% distance matrix
B = [0 29 20 21 16 31 100 12 4 31 18;
29 0 15 29 28 40 72 21 29 41 12;
20 15 0 15 14 25 81 9 23 27 13;
21 29 15 0 4 12 92 12 25 13 25;
16 28 14 4 0 16 94 9 20 16 22;
31 40 25 12 16 0 95 24 36 3 37;
100 72 81 92 94 95 0 90 101 99 84;
12 21 9 12 9 24 90 0 15 25 13;
4 29 23 25 20 36 101 15 0 35 18;
31 41 27 13 16 3 99 25 35 0 38;
18 12 13 25 22 37 84 13 18 38 0];
% compute all possible paths assuming we always start at node 1
nNodes = size(B,1);
paths = perms(2:nNodes);
nPaths = size(paths,1);
paths = [ones(nPaths,1) paths ones(nPaths,1)]; % start and finish tour at node 1
% with a random start point:
% paths = perms(1:nNodes);
% paths = [perms(1:nNodes) paths(:,1)];
% compute overall distance for each path
distance = inf;
for idx=1:nPaths
from = paths(idx,1:end-1);
to = paths(idx,2:end);
d = sum(diag(B(from,to)));
if d<distance
distance = d;
optPath = paths(idx,:);
end
end
This leads to the following result:
optPath = [1 9 11 2 7 3 6 10 4 5 8 1]
distance = 253

Valid values of a matrix/image under a mask [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Suppose I want to extract values in an image or matrix in Matlab under a given mask (e.g., a 5x5 mask), but I want to extract only existing values because in the borders (or close to them) the mask will not find all values. I want to extract only the valid values of the image given this mask, no matter which pixel i am iterating. How to do that in Matlab?
You just have to compute the x and y indices applying max and min so as not to exceed the image boundaries:
img = magic(7); %// define example image
Nx = 5; %// block size in x
Ny = 5; %// block size in y
x = 2; %// pixel x
y = 6; %// pixel y
nx = (Nx-1)/2;
ny = (Ny-1)/2;
xx = max(x-nx,1):min(x+nx,size(img,1));
yy = max(y-ny,1):min(y+ny,size(img,2));
block = img(xx, yy);
Example result:
>> img
img =
30 39 48 1 10 19 28
38 47 7 9 18 27 29
46 6 8 17 26 35 37
5 14 16 25 34 36 45
13 15 24 33 42 44 4
21 23 32 41 43 3 12
22 31 40 49 2 11 20
>> block
block =
1 10 19 28
9 18 27 29
17 26 35 37
25 34 36 45
If you have the image processing toolbox, you can use the function blockproc to define your own neighborhood-based operation.
M=5; N=5;
fun = #(block_struct) block_struct.data;
B = blockproc(I,[M N],fun, 'TrimBorder', 1);
where I is your image (matrix). Then change fun to whatever you need. The TrimBorder parameter should cope with your border issue.
Hope it helps

Resources