www.pudn.com > jpegtool_matlab.rar > deblockc
# deblockc - calculate AC coefficients in a smoothing scheme
#
# SYNOPSIS
# deblockc()
# deblockc(k)
# deblockc(k, N)
#
# DESCRIPTION
# deblockc is a Maple procedure to find the AC coefficients (in terms
# of the DC coefficients) which could be used as part of a smoothing
# procedure to reduce blocking artifacts (the telltale discontinuities
# between blocks which often follow aggressive quantizing) in JPEG.
#
# The polynomial
# p = a_1 x^2 y^2 + a_2 x^2 y + a_3 x y^2 + a_4 x^2 + a_5 x y
# + a_6 y^2 + a_7 x +a_8 y + a_9
# is fitted using the DC coefficients from nearest neighbors:
#
# ------------------- x
# | DC1 | DC2 | DC3 |
# |-----------------|
# | DC4 | DC5 | DC6 |
# |-----------------|
# | DC7 | DC8 | DC9 |
# |-----------------
# y
#
# The coefficients are chosen so that the average over the NxN
# DC_i subblock is DC_i. (There is a scaling factor--see below.)
# N defaults to 8; k specifies the number of coefficients to
# find (defaults to 5).
#
# The idea is that low-frequency zero AC coefficients in the center
# block will be will be replaced by values from the (transformed)
# polynomial. The procedure is described in Pennebaker and Mitchell,
# "JPEG Still Image Data Compression Standard", Van Nostrand Reinhold.
#
# EXAMPLE
# The two statements
# AC := deblockc():
# AC := deblockc(5,8):
# produce the same results. The zigzag sequence AC[0,0], AC[0,1],
# AC[1,0], ..., AC[0,3] is displayed (first symbolically, then
# numerically), and the results are stored in AC.
#
# BUGS
# This is a hack.
# Copyright (C) 1995-1997 Darrel Hankerson and Greg A. Harris
#
# This file is part of the JPEGtool collection of scripts for Octave
# and Matlab; see http://www.dms.auburn.edu/compression
#
# The JPEGtool collection is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2, or
# (at your option) any later version.
#
# The collection is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this package; see the file COPYING. If not, write to the
# Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
deblockc := proc()
local N, terms, i, X, AC, row, col, v,u, y, x, n, z,
p, dct, zigzag;
if nargs < 2 then N := 8; else N := args[2] fi;
if nargs < 1 then terms := 5; else terms := args[1] fi;
for i from 1 to 9 do;
a.i := evaln(a.i);
od;
p := proc(y,x)
a1*x^2*y^2 + a2*x^2*y + a3*x*y^2 + a4*x^2 + a5*x*y + a6*y^2
+ a7*x +a8*y + a9
end:
# In the "standard" transform, the DC coefficient is N^2/(2*sqrt (2N))
# times the block averages. Adjustment made below.
for i from 1 to 9 do;
row := floor((i-1)/3) * N; col := ((i-1) mod 3) * N;
eq.i := sum(sum(p(y,x),y=row..row+N-1),
x=col..col+N-1) - DC.i:
od:
assign( solve({seq(eq.i, i=1..9)}, {seq(a.i, i=1..9)}) );
X := array(0..N-1, 0..N-1);
for y from 0 to N-1 do;
for x from 0 to N-1 do;
X[y,x] := p(y+N, x+N)
od
od;
dct := proc(X, v, u)
local x, y, w, N, C;
N := op(2,eval(X))[1]; N := op(2,N) - op(1,N) + 1;
C := proc(w)
if not type(w, 'numeric') then
RETURN( 'procname(args)' )
fi;
if w = 0 then 1/sqrt(2) else 1 fi
end:
w := Pi/(2*N);
C(v)*C(u)/sqrt(2*N) *
sum(cos((2*y+1)*v*w) * sum(X[y,x]*cos((2*x+1)*u*w), x=0..N-1),
y=0..N-1)
end:
zigzag := proc(N)
local u, v, inc, n, z;
z := array(0..N*N-1, 0..1);
u := -1; v := 1; inc := 1;
for n from 0 to N*N-1 do;
v := v - inc; u := u + inc;
if (u >= N) then
v := v + 2; u := N-1; inc := -1;
elif (v = -1) then
v := 0; inc := -1;
elif (v >= N) then
u := u + 2; v := N-1; inc := 1;
elif (u = -1) then
u := 0; inc := 1;
fi;
z[n, 0] := v; z[n,1] := u;
od;
z
end:
z := zigzag(N); AC := array(0..N, 0..N);
for n from 0 to terms do;
v := z[n,0]; u := z[n,1];
AC[v,u] := collect( dct(X,v,u), {seq(DC.i, i=1..9)} ) * 2*sqrt(2*N);
print(evaln(AC[v,u]) = AC[v,u]);
od:
for n from 0 to terms do;
v := z[n,0]; u := z[n,1];
print(evaln(AC[v,u]) = evalf(AC[v,u]));
od:
AC
end:
`help/text/deblockc` := TEXT(
`FUNCTION: deblockc - find coefficients in deblocking scheme`,
` `,
`CALLING SEQUENCE:`,
` deblock(k, N)`,
` `,
`PARAMETERS:`,
` k - (optional, default 5) number of terms to find`,
` N - (optional, default 8) size of block in the transform`,
` `,
`SYNOPSIS:`,
`- The function deblockc finds coefficients of a polynomial to be used`,
` by a smoothing procedure in an effort to reduce blocking artifacts `,
` (the telltale discontinuities between blocks which often follow`,
` aggressive quantizing). For a given block, a polynomial is fitted using`,
` the DC coefficients from nearest neighbors.`,
` `,
`- The matrix of coefficients is returned.`,
` `,
`- See Pennebaker and Mitchell, "JPEG Still Image Data Compression Standard"`,
` Van Nostrand Reinhold, 1993.`
):
#save `deblockc.m`;
#quit