基于Matlab的图像方块编码(BTC)
DIP实验6:方块编码(BTC)
实验目的
掌握方块编码的基本方法及压缩性能。
实验内容
1)编程实现子块为n×n的方块编码算法;
2)分别取n=4和8的方块尺寸进行实验,计算重建图像的PSNR和压缩比。
输出图像排列格式如下:
原图像 | 4×4BTC重建图像 | 8×8BTC重建图像 |
---|
参考代码
figure('NumberTitle', 'off', 'Name', '实验6:方块编码(BTC)');
OI = imread('lena.bmp'); % 原始图像读取
[len, wid] = size(OI);
rebuildImg1 = BTC2(OI, 4);
rebuildImg2 = BTC2(OI, 8);
subplot(1,3,1); imshow(OI); title('原图像');
subplot(1,3,2); imshow(rebuildImg1); title('4×4BTC重建图像');
subplot(1,3,3); imshow(rebuildImg2); title('8×8BTC重建图像');
[PSNR1, cr1] = Para(OI, rebuildImg1, 4)
[PSNR2, cr2] = Para(OI, rebuildImg2, 8)
function rebuildImg = BTC1(OI, N)
% rebuildImg 重建图像
% OI 原始图像
% N 子块大小为 m = N * N
m = N * N;
OI = double(OI);
[len, wid] = size(OI);
% 判断len, wid是否能都被N整除
if (len/N ~= round(len/N)) || (wid/N ~= round(wid/N))
OI = Pad(OI, N);
[len, wid] = size(OI);
end
rebuildImg = zeros(len, wid);
for x = 1 : len/N
for y = 1 : wid/N
block = OI((x-1)*N+1 : (x*N), (y-1)*N+1 : (y*N));
Xt = mean(mean(block)); % 计算均值
q = 0; % 计算q值: 比均值大的方块的个数
for i = 1 : N
for j = 1 : N
if block(i, j) >= Xt
q = q + 1;
end
end
end
% 计算子块的标准差sigma
sigma = sqrt(mean(mean(block .* block)) - Xt^2);
if m == q
a1 = Xt;
a0 = Xt;
else
a0 = round(Xt - sigma * sqrt(q/(m-q)));
a1 = round(Xt + sigma * sqrt((m-q)/q));
end
for i = 1 : N
for j = 1 : N
if block(i, j) > Xt
block(i, j) = a1;
else
block(i, j) = a0;
end
end
end
rebuildImg((x-1)*N+1 : (x*N), (y-1)*N+1 : (y*N)) = block(1:N, 1:N);
end
end
rebuildImg = uint8(rebuildImg);
end
function rebuildImg = BTC2(OI, N)
% rebuildImg 重建图像
% OI 原始图像
% N 子块大小为 m = N * N
m = N * N;
OI = double(OI);
[len, wid] = size(OI);
rebuildImg = zeros(len, wid);
for x = 1 : len/N
for y = 1 : wid/N
block = OI((x-1)*N+1 : (x*N), (y-1)*N+1 : (y*N));
Xt = mean(mean(block)); % 计算均值
q = 0; % 计算q值: 比均值大的方块的个数
u_xi = 0;
d_xi = 0;
for i = 1 : N
for j = 1 : N
if block(i, j) > Xt
q = q + 1;
u_xi = u_xi + block(i, j);
else
d_xi = d_xi + block(i, j);
end
end
end
a0 = round(d_xi/(m-q));
a1 = round(u_xi/(q));
for i = 1 : N
for j = 1 : N
if block(i, j) > Xt
block(i, j) = a1;
else
block(i, j) = a0;
end
end
end
rebuildImg((x-1)*N+1 : (x*N), (y-1)*N+1 : (y*N)) = block(1:N, 1:N);
end
end
rebuildImg = uint8(rebuildImg);
end
function [PSNR, cr]= Para(I1, I2, N)
% 计算重建图像的PSNR和压缩比
P = 8; %编码一个像素用多少二进制位
max = 2^P - 1; %图像有多少灰度级
I1 = double(I1);
I2 = double(I2);
[len, wid] = size(I1);
m = N * N;
% 峰值信噪比
MSE = sum(sum((I1-I2).^2)) / (len * wid);
PSNR = 20 * log10(max/sqrt(MSE));
% 压缩比
cr = P / (1 + 2 * P / m);
end
% 若无法恰好分割,填充边缘
function newImg = Pad(OI, N)
[len, wid] = size(OI);
newImg(1:len,1:wid) = OI(1:len,1:wid);
if mod(len, N) ~= 0
padRow = N - mod(len, N);
newImg(len+1:len+padRow) = OI(len-padRow:len);
end
if mod(wid, N) ~= 0
padCol = N - mod(wid, N);
newImg(wid+1:wid+1+padCol) = OI(wid-padCol:wid);
end
end