Problema Matlab[URGENTE]
Sto facendo un progetto in Matlab, il testo è questo:
http://www.dmi.unict.it/~fstanco/lezioni_IEM_2007_2008/progetto_170211.pdf
Ho creato una funzione Bitplane:
E poi il programma vero e proprio, trascurate quello scritto tra %
Ho un problema perchè così facendo l' immagine Z non risulta corretta, cioè se ad esempio non elimino piani di bit dovrei ottenere la stessa immagine, invece non coincide con quella di partenza, secondo voi c' è qualche errore?
E' molto importante, grazie.
http://www.dmi.unict.it/~fstanco/lezioni_IEM_2007_2008/progetto_170211.pdf
Ho creato una funzione Bitplane:
function[B]=bitplane(I)
%A=rgb2gray(I);
A=I;
[m,n]=size(A);
B=zeros(m,n,8);
%figure,imshow(A);
D=[1 2 4 8 16 32 64 128];
for i=1:m
for j=1:n
for h=1:8
s=rem(round (A(i,j)/D(h)),2);%calcolo la divisione intera del colore diviso 2^n e del risultato ne calcolo il modulo diviso 2
if(s==0)
B(i,j,h)=1;
end
end
end
endE poi il programma vero e proprio, trascurate quello scritto tra %
clear all;
close all;
%inserimento numeri
nr=input('Digita un numero compreso tra 0 e 8: ');
ng=input('Digita un numero compreso tra 0 e 8: ');
nb=input('Digita un numero compreso tra 0 e 8: ');
%lettura immagine
I=imread('lena.jpg');
[m,n,t]=size(I);
R=I(:,:,1); %memorizzo 3 canali
G=I(:,:,2);
B=I(:,:,3);
Rbit=bitplane(R); %bitplane per ogni canale
Gbit=bitplane(G);
Bbit=bitplane(B);
Rnuova=zeros(m,n,8); %creo delle matrici oer memorizzare i piani che mi servono
Gnuova=zeros(m,n,8);
Bnuova=zeros(m,n,8);
for i=nr+1:8 %dal piano che mi interessa fino all' ottavo
Rnuova(:,:,i)=Rbit(:,:,i); %memorizza
end
for i=nr+1:8
Gnuova(:,:,i)=Gbit(:,:,i);
end
for i=nr+1:8
Bnuova(:,:,i)=Bbit(:,:,i);
end
%Rnuova=Rbit;
%Gnuova=Gbit;
%Bnuova=Bbit;
%figure,imshow(Rnuova(:,:,1));
%figure,imshow(Gnuova(:,:,1));
%figure,imshow(Bnuova(:,:,1));
%CALCOLO IL RISPARMIO IN MEMORIA
pixel=m*n; %primo costo
costo1=24*pixel;
bitr=8-nr;
bitg=8-ng;
bitb=8-nb;
costo2=pixel*bitr+pixel*bitg+pixel*bitb; %secondo costo
risparmio_bit=costo1-costo2;
II=zeros(m,n);
III=zeros(m,n);
IIII=zeros(m,n);
%for i=1:m
% for j=1:n
% A(i,j)=bi2de([Rnuova(i,j,1) Rnuova(i,j,2) Rnuova(i,j,3) Rnuova(i,j,4) Rnuova(i,j,5) Rnuova(i,j,6) Rnuova(i,j,7) Rnuova(i,j,8)]);
% B(i,j)=bi2de([Gnuova(i,j,1) Gnuova(i,j,2) Gnuova(i,j,3) Gnuova(i,j,4) Gnuova(i,j,5) Gnuova(i,j,6) Gnuova(i,j,7) Gnuova(i,j,8)]);
% C(i,j)=bi2de([Bnuova(i,j,1) Bnuova(i,j,2) Bnuova(i,j,3) Bnuova(i,j,4) Bnuova(i,j,5) Bnuova(i,j,6) Bnuova(i,j,7) Bnuova(i,j,8)]);
%end
%end
for i=1:m %qui prendo i valori di ogni riga in binario e li metto
for j=1: n %in un vettore dopo li converto in decimali e li inserisco in un pixel
vett=zeros(8);
for k=1:8
vett1(k)=Rnuova(i,j,k);
vett2(k)=Gnuova(i,j,k);
vett3(k)=Bnuova(i,j,k);
end
bi2de(vett1);
II(i,j)=bi2de(vett1);
III(i,j)=bi2de(vett2);
IIII(i,j)=bi2de(vett3);
end
end
%II=Rnuova(:,:,1)+Rnuova(:,:,2)+Rnuova(:,:,3)+Rnuova(:,:,4)+Rnuova(:,:,5)+Rnuova(:,:,6)+Rnuova(:,:,7)+Rnuova(:,:,8);
%III=Gnuova(:,:,1)+Gnuova(:,:,2)+Gnuova(:,:,3)+Gnuova(:,:,4)+Gnuova(:,:,5)+Gnuova(:,:,6)+Gnuova(:,:,7)+Gnuova(:,:,8);
%IIII=Bnuova(:,:,1)+Bnuova(:,:,2)+Bnuova(:,:,3)+Bnuova(:,:,4)+Bnuova(:,:,5)+Bnuova(:,:,6)+Bnuova(:,:,7)+Bnuova(:,:,8);
Z(:,:,1)=II;
Z(:,:,2)=III;
Z(:,:,3)=IIII;
%figure,
%subplot(1,4,1),imshow(uint8(II), []);
%subplot(1,4,2),imshow(uint8(III), []);
%subplot(1,4,3),imshow(uint8(IIII), []);
%subplot(1,4,4),imshow(uint8(Z), []);
imwrite(Z,'Compressa.jpg','jpg');
PSNR=psnr(double(I),Z);
figure,imshow(uint8(Z),[]);Ho un problema perchè così facendo l' immagine Z non risulta corretta, cioè se ad esempio non elimino piani di bit dovrei ottenere la stessa immagine, invece non coincide con quella di partenza, secondo voi c' è qualche errore?
E' molto importante, grazie.
Risposte
for i=nr+1:8 %dal piano che mi interessa fino all' ottavo
Rnuova(:,:,i)=Rbit(:,:,i); %memorizza
end
for i=nr+1:8
Gnuova(:,:,i)=Gbit(:,:,i);
end
for i=nr+1:8
Bnuova(:,:,i)=Bbit(:,:,i);
end
Qui usi 3 volte nr, suppongo che sia un errore.
PSNR=psnr(double(I),Z);
Come mai hai passato I come matrice di double? Di che tipo erano prima di essere passati a psnr?
s = rem(round(A(i,j)/D(h)), 2);%calcolo la divisione intera del colore diviso 2^n e del risultato ne calcolo il modulo diviso 2
if(s==0)
B(i,j,h)=1;
end
Perché usi round? È il troncamento il metodo corretto per ottenere le cifre decimali di un numero. E in ogni caso è a mio parere migliore lavorare direttamente sui bit usando bitget o sporcandosi un po' più le mani con bitand e bitshift. Cioè
function [B] = bitplane(I)
[m, n] = size(I);
B = zeros(m, n, 8);
D = [1 2 4 8 16 32 64 128];
for i = 1:m
for j = 1:n
for h=1:8
B(i, j, h) = bitshift(bitand(I(i, j), D(h)), 1 - h);
end
end
end
Direi che non può dirti niente per l'uso di questo genere di funzioni. Non implementano alcuna logica particolare. Il modo più semplice sarebbe
function [B] = bitplane(I)
[m, n] = size(I);
B = zeros(m, n, 8);
for i = 1:m
for j = 1:n
B(i, j, :) = bitget(I(i, j), 1:8);
end
end
Questo potrebbe servirti come funzione di controllo (verificare se gli altri codici funzionano correttamente) Si potrebbe anche scrivere tutto senza cicli (immagino).
Allora ricopio i codici, psnr, bitplane e main vero e proprio, tutte le funzione prendono le immagini in input normalmente senza effettuare conversioni, nell' usare il psnr, non so perchè ma devo convertire a double:
Ho corretto quelle sviste che mi avevi fatto notare, però continuo a non capire perchè l' immagine che qui chiamo RICOMPOSTA si vede male.
PSNR (abbiamo detto va bene)
BITPLANE:
Ho corretto quelle sviste che mi avevi fatto notare, però continuo a non capire perchè l' immagine che qui chiamo RICOMPOSTA si vede male.
PSNR (abbiamo detto va bene)
function [PSNR,MSE] =psnr(A,Interpolata)
[m,n]=size(A);
MSE=0;
for x=1: m
for y=1: n
MSE=MSE+(A(x,y)-Interpolata(x,y)).^2;
end
end
MSE=MSE/(m*n);
PSNR=10*log10((255^2)/MSE);
end
BITPLANE:
function[B]=bitplane(I)
A=I;
[m,n]=size(A);
B=zeros(m,n,8);
for i=1:m
for j=1:n
for h=1:8
numero=A(i,j); %memorizzo il valore
cont=0;
while(cont<h) %continuo a dividere finchè non ottengo il bit corrispondente al piano h
resto=mod(numero,2); %il resto conterrà il valore binario
cont=cont+1;
numero=numero/2; %memorizzo il successivo numero da dividere
end
if resto==1
B(i,j,h)=1;
end
end
end
end
end
clear all;
close all;
%inserimento numeri da tastiera
nr=input('Inserisci un numero tra 0 e 8: ');
ng=input('Inserisci un numero tra 0 e 8: ');
nb=input('Inserisci un numero tra 0 e 8: ');
%lettura immagine
I=imread('lena.jpg');
[m,n,t]=size(I);
R=I(:,:,1); %memorizzo i 3 canali separatamente
G=I(:,:,2);
B=I(:,:,3);
Rbit=bitplane(R); %bitplane per ogni canale
Gbit=bitplane(G);
Bbit=bitplane(B);
Rnuova=zeros(m,n,8); %creo delle matrici per memorizzare i piani che mi servono per ogni canale
Gnuova=zeros(m,n,8);
Bnuova=zeros(m,n,8);
for i=nr+1:8 %da nr+1(piano che mi interessa)fino all' ottavo
Rnuova(:,:,i)=Rbit(:,:,i); %memorizza i piani nelle nuove matrici
end
for i=ng+1:8
Gnuova(:,:,i)=Gbit(:,:,i);
end
for i=nb+1:8
Bnuova(:,:,i)=Bbit(:,:,i);
end
%CALCOLO IL RISPARMIO IN MEMORIA
pixel=m*n; %primo costo
costo1=24*pixel; %avremo 3 canali cioè 8 bit ciascuno, quindi 24 moltiplicati per il numero di pixel
bitr=8-nr; %Ho tolto dei piani, quindi ho dei bit in meno per ogni canale
bitg=8-ng;
bitb=8-nb;
costo2=pixel*bitr+pixel*bitg+pixel*bitb; %secondo costo
risparmio_bit=costo1-costo2; %ecco il risparmio
%RICOSTRUZIONE IMMAGINE
II=zeros(m,n);
III=zeros(m,n);
IV=zeros(m,n);
for i=1:m %qui prendo i valori di ogni riga in binario e li metto
for j=1: n %in un vettore, dopo li converto in decimali e li inserisco nel corrispondente pixel
for k=1:8
vett1(k)=Rnuova(i,j,k); %conterrà tutto il codice binario
vett2(k)=Gnuova(i,j,k);
vett3(k)=Bnuova(i,j,k);
end
II(i,j)=bi2de(vett1); %converto ed assegno il valore decimale
III(i,j)=bi2de(vett2);
IV(i,j)=bi2de(vett3);
end
end
RICOMPOSTA(:,:,1)=II;
RICOMPOSTA(:,:,2)=III;
RICOMPOSTA(:,:,3)=IV;
%STAMPE
risparmio_bit
%SALVATAGGIO IN MEMORIA DELL' IMMAGINE COMPRESSA
imwrite(RICOMPOSTA,'Compressa.jpg','jpg');
%STAMPA
figure,imshow(RICOMPOSTA,[]),title('COMPRESSA');
%Stampa
PSNR=psnr(double(I),double(RICOMPOSTA))
Hai provato ad utilizzare le operazioni bitwise come ti ho consigliato? Come appare l'immagine? Hai provato a visualizzarla per cui dovresti essere in grado di dire che cosa non c'è che non va.
Ho già dovuto inviare il progetto......ti ringrazio comunque...