-
Notifications
You must be signed in to change notification settings - Fork 1
/
halftone.m
181 lines (158 loc) · 7.99 KB
/
halftone.m
1
2
3
4
5
6
7
8
9
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
function Im_out = halftone(Img_in, error_diffusion_type, bin_coef)
%HALFTONE Computes halftone of an image using error diffusion methods
% H = HALFTONE(Im_in, error_diffusion_type) creates a halftoned image
% of an image using error difusion and binar function.
% Valid values for error_diffusion_type are:
%
% 'Floyd_Steinberg' only diffuses the error to neighboring pixels.
% This results in very fine-grained dithering.
%
% 'Brukes' is a simplified form of Stucki dithering that is faster,
% but is less clean than Stucki dithering.
%
% 'Stucki' is based on the above, but is slightly faster. Its output
% tends to be clean and sharp.
%
% 'Minimized average error' by Jarvis, Judice, and Ninke diffuses the
% error also to pixels one step further away. The dithering
% is coarser, but has fewer visual artifacts. However, it is
% slower than Floyd–Steinberg dithering, because it
% distributes errors among 12 nearby pixels instead of 4
% nearby pixels for Floyd–Steinberg.
%
% 'Atkinson' was developed by Apple programmer Bill Atkinson, and
% resembles Jarvis dithering and Sierra dithering, but it's
% faster. Another difference is that it doesn't diffuse the
% entire quantization error, but only three quarters. It tends to
% preserve detail well, but very light and dark areas may appear
% blown out.
%
%
if nargin == 2
bin_coef = 0.5;
end
Im_in = im2double(Img_in);
[rows,cols,channels] = size(Im_in);
if(channels ~= 1)
error('Funkcija prima samo sive slike');
end
switch error_diffusion_type
case 'Floyd_Steinberg'
Im_out = padarray(Im_in,[1,1]);
div = 7;
case 'Brukes'
Im_out = padarray(Im_in,[1,2]);
div = 32;
case 'Stucki'
Im_out = padarray(Im_in,[2,2]);
div = 42;
case 'Minimized average error'
Im_out = padarray(Im_in,[2,2]);
div = 46;
case 'Atkinson'
Im_out = padarray(Im_in,[2,2]);
div = 8;
otherwise
error('Unknown function type.');
end
for i= 1:rows
for j= 1:cols
row = i;
col = j;
switch error_diffusion_type
case 'Floyd_Steinberg'
trow = row + 1;
tcol = col + 1;
case 'Brukes'
trow = row + 1;
tcol = col + 2;
case 'Stucki'
trow = row + 2;
tcol = col + 2;
case 'Minimized average error'
trow = row + 2;
tcol = col + 2;
case 'Atkinson'
trow = row + 2;
tcol = col + 2;
otherwise
error('Unknown function type.');
end
dif_error = Im_out(trow,tcol) - bin_coef;
if(Im_out(trow,tcol) > bin_coef)
Im_out(trow,tcol) = 1;
else
Im_out(trow,tcol) = 0;
end
switch error_diffusion_type
case 'Floyd_Steinberg'
Im_out(trow,tcol+1) = Im_out(trow,tcol+1) + dif_error * 7./div;
Im_out(trow+1,tcol-1) = Im_out(trow+1,tcol-1) + dif_error * 3./div;
Im_out(trow+1,tcol) = Im_out(trow+1,tcol) + dif_error * 5./div;
Im_out(trow+1,tcol+1) = Im_out(trow+1,tcol+1) + dif_error * 1./div;
case 'Brukes'
Im_out(trow,tcol+1) = Im_out(trow,tcol+1) + dif_error * 8./div;
Im_out(trow,tcol+2) = Im_out(trow,tcol+2) + dif_error * 4./div;
Im_out(trow+1,tcol-2) = Im_out(trow+1,tcol-2) + dif_error * 2./div;
Im_out(trow+1,tcol-1) = Im_out(trow+1,tcol-1) + dif_error * 4./div;
Im_out(trow+1,tcol) = Im_out(trow+1,tcol) + dif_error * 8./div;
Im_out(trow+1,tcol+1) = Im_out(trow+1,tcol+1) + dif_error * 4./div;
Im_out(trow+1,tcol+2) = Im_out(trow+1,tcol+2) + dif_error * 2./div;
case 'Stucki'
Im_out(trow,tcol+1) = Im_out(trow,tcol+1) + dif_error * 8./div;
Im_out(trow,tcol+2) = Im_out(trow,tcol+2) + dif_error * 4./div;
Im_out(trow+1,tcol-2) = Im_out(trow+1,tcol-2) + dif_error * 2./div;
Im_out(trow+1,tcol-1) = Im_out(trow+1,tcol-1) + dif_error * 4./div;
Im_out(trow+1,tcol) = Im_out(trow+1,tcol) + dif_error * 8./div;
Im_out(trow+1,tcol+1) = Im_out(trow+1,tcol+1) + dif_error * 4./div;
Im_out(trow+1,tcol+2) = Im_out(trow+1,tcol+2) + dif_error * 2./div;
Im_out(trow+2,tcol-2) = Im_out(trow+2,tcol-2) + dif_error * 1./div;
Im_out(trow+2,tcol-1) = Im_out(trow+2,tcol-1) + dif_error * 2./div;
Im_out(trow+2,tcol) = Im_out(trow+2,tcol) + dif_error * 4./div;
Im_out(trow+2,tcol+1) = Im_out(trow+2,tcol+1) + dif_error * 2./div;
Im_out(trow+2,tcol+2) = Im_out(trow+2,tcol+2) + dif_error * 1./div;
case 'Minimized average error'
Im_out(trow,tcol+1) = Im_out(trow,tcol+1) + dif_error * 7./div;
Im_out(trow,tcol+2) = Im_out(trow,tcol+2) + dif_error * 5./div;
Im_out(trow+1,tcol-2) = Im_out(trow+1,tcol-2) + dif_error * 3./div;
Im_out(trow+1,tcol-1) = Im_out(trow+1,tcol-1) + dif_error * 5./div;
Im_out(trow+1,tcol) = Im_out(trow+1,tcol) + dif_error * 7./div;
Im_out(trow+1,tcol+1) = Im_out(trow+1,tcol+1) + dif_error * 5./div;
Im_out(trow+1,tcol+2) = Im_out(trow+1,tcol+2) + dif_error * 3./div;
%Im_out(trow+2,tcol-2) = Im_out(trow+2,tcol-2) + error * 0/div;
Im_out(trow+2,tcol-1) = Im_out(trow+2,tcol-1) + dif_error * 3./div;
Im_out(trow+2,tcol) = Im_out(trow+2,tcol) + dif_error * 5./div;
Im_out(trow+2,tcol+1) = Im_out(trow+2,tcol+1) + dif_error * 3./div;
%Im_out(trow+2,tcol+2) = Im_out(trow+2,tcol+2) + error * 0/div;
case 'Atkinson'
Im_out(trow,tcol+1) = Im_out(trow,tcol+1) + dif_error * 1./div;
Im_out(trow,tcol+2) = Im_out(trow,tcol+2) + dif_error * 1./div;
%Im_out(trow+1,tcol-2) = Im_out(trow+1,tcol-2) + error * 0/div;
Im_out(trow+1,tcol-1) = Im_out(trow+1,tcol-1) + dif_error * 1./div;
Im_out(trow+1,tcol) = Im_out(trow+1,tcol) + dif_error * 1./div;
Im_out(trow+1,tcol+1) = Im_out(trow+1,tcol+1) + dif_error * 1./div;
%Im_out(trow+1,tcol+2) = Im_out(trow+1,tcol+2) + error * 0/div;
%Im_out(trow+2,tcol-2) = Im_out(trow+2,tcol-2) + error * 0/div;
%Im_out(trow+2,tcol-1) = Im_out(trow+2,tcol-1) + error * 0/div;
Im_out(trow+2,tcol) = Im_out(trow+2,tcol) + dif_error * 1./div;
%Im_out(trow+2,tcol+1) = Im_out(trow+2,tcol+1) + error * 0/div;
%Im_out(trow+2,tcol+2) = Im_out(trow+2,tcol+2) + error * 0/div;
otherwise
error('Unknown function type.');
end
end
end
switch error_diffusion_type
case 'Floyd_Steinberg'
Im_out = Im_out(2:rows+1, 2:cols+1);
case 'Brukes'
Im_out = Im_out(2:rows+1, 3:cols+2);
case 'Stucki'
Im_out = Im_out(3:rows+2, 3:cols+2);
case 'Minimized average error'
Im_out = Im_out(3:rows+2, 3:cols+2);
case 'Atkinson'
Im_out = Im_out(3:rows+2, 3:cols+2);
otherwise
error('Unknown error diffusion type.');
end