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 end
E 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...
