【圖像去噪】基于 DCT變換實現(xiàn)圖像去噪matlab源碼含 GUI
一、簡介
1 DCT算法:
DCT變換的全稱是離散余弦變換(Discrete Cosine Transform),離散余弦變換相當于一個長度大概是它兩倍的離散傅里葉變換,這個離散傅里葉變換是對一個實偶函數(shù)進行的。通過數(shù)字信號處理的學習我們知道實函數(shù)的傅立葉變換獲得的頻譜大多是復數(shù),而偶函數(shù)的傅立葉變換結果是實函數(shù)。以此為基礎,使信號函數(shù)成為偶函數(shù),去掉頻譜函數(shù)的虛部,是余弦變換的特點之一。它可以將將一組光強數(shù)據(jù)轉換成頻率數(shù)據(jù),以便得知強度變化的情形。若對高頻的數(shù)據(jù)做些修飾,再轉回原來形式的數(shù)據(jù)時,顯然與原始數(shù)據(jù)有些差異,但是人類的眼睛卻是不容易辨認出來。壓縮時,將原始圖像數(shù)據(jù)分成8*8數(shù)據(jù)單元矩陣,例如亮度值的第一個矩陣內。


2 DCT產(chǎn)生的工程背景:
視頻信號的頻譜線在0-6MHz范圍內,而且1幅視頻圖像內包含的大多數(shù)為低頻頻譜線,只在占圖像區(qū)域比例很低的圖像邊緣的視頻信號中才含有高頻的譜線。因此,在視頻信號數(shù)字處理時,可根據(jù)頻譜因素分配比特數(shù):對包含信息量大的低頻譜區(qū)域分配較多的比特數(shù),對包含信息量低的高頻 譜區(qū)域分配較少的比特數(shù),而圖像質量并沒有可察覺的損傷,達到碼率壓縮的目的。然而,這一切要在低熵(Entropy)值的情況下,才能達到有效的編碼。能否對一串數(shù)據(jù)進行有效的編碼,取決于每個數(shù)據(jù)出現(xiàn)的概率。每個數(shù)據(jù)出現(xiàn)的概率差別大,就表明熵值低, 可以對該串數(shù)據(jù)進行高效編碼。反之,出現(xiàn)的概率差別小,熵值高,則不能進行高效編碼。視頻信號的數(shù)字化是在規(guī)定的取樣頻率下由A/D轉換器對視頻電平轉換而來的,每個像素的視頻信號幅度隨著每層的時間而周期性地變化。每個像素的平均信息量的總和為總平均信息量,即熵值。由于每個視頻電平發(fā)生幾乎具有相等的概率,所以視頻信號的熵值很高。 熵值是一個定義碼率壓縮率的參數(shù),視頻圖像的壓縮率依賴于視頻信號的熵值,在多數(shù)情況下視頻信號為高熵值,要進行高效編碼,就要將高熵值變?yōu)榈挽刂怠T鯓幼兂傻挽刂的??這就需要分析視頻頻譜的特點。大多數(shù)情況下,視頻頻譜的幅度隨著頻率的升高而降低。其中 低頻頻譜在幾乎相等的概率下獲得0到最高的電平。與此相對照,高頻頻譜通常得到的是低電平及稀少的高電平。顯然,低頻頻譜具有較高的熵值,高頻頻譜具有較低的熵值。據(jù)此,可對視頻的低頻分量和高頻分量分別處理,獲得高頻的壓縮值。
自從Ahmed和Rao于1974年給出了離散余弦變換(DCT)的定義以來,離散余弦變換(DCT)與改進型離散余弦變換(MDCT)就成為廣泛應用于信號處理和圖像處理特別是用于圖像壓縮和語音壓縮編解碼的重要工具和技術,一直是國際學術界和高科技產(chǎn)業(yè)界的研究熱點?,F(xiàn)在的很多圖像和視頻編碼標準(如MPEG-1 , MEPG-2 ,MEPG-4中的第二部分)都要求實現(xiàn)整數(shù)的8×8 的DCT和IDCT,而MDCT 和IMDCT 則主要被應用于音頻信號的編解碼中(如MPEG-1 ,MEPG-2 和AC-]等標準的音頻編碼部分)。正是由于這類變換被廣泛采用,對于這類變換的快速算法的研究才顯得尤為重要。特別是針對特定的應用條件下的快速算法的研究對于提高整個系統(tǒng)的性能表現(xiàn)有很大幫助。
由上面的引用可見,碼率壓縮基于變換編碼和熵值編碼兩種算法。前者用于降低熵值,后者將數(shù)據(jù)變?yōu)榭山档捅忍財?shù)的有效編碼方式。在MPEG標準中,變換編碼采用的是DCT,變換過程本身雖然并不產(chǎn)生碼率壓縮作用,但是變換后的頻率系數(shù)卻非常有利于碼率壓縮。 實際上壓縮數(shù)字視頻信號的整個過程分為塊取樣、DCT、量化、編碼4個主要過程進行-----首先在時間域將原始圖像分成N(水平)×N(垂直)取樣塊,根據(jù)需要可選擇4×4、4×8、8×8、8×16、16×16等塊,這些取樣的像素塊代表了原圖像幀各像素的灰度值,其范圍在139-163之間,并依序送入DCT編碼器,以便將取樣塊由時間域轉換為頻率域的DCT系數(shù)塊。DCT系統(tǒng)的轉換分別在每個取樣塊中進行,這些塊中每個取樣是數(shù)字化后的值,表示一場中對應像素的視頻信號幅度值
3 離散余弦變換的實現(xiàn):
實現(xiàn)DCT的方法很多,最直接的是根據(jù)DCT的定義來計算。以二維8xSDCT為例,需要作4096次乘法和3584次加法。這種算法的實現(xiàn)需要巨大的計算量,不具有實用價值。在應用中,需要尋找快速而又精確的算法。較為常用的方法是利用DCT的可拆分特性,同樣以二維8xSDCT為例,先進行8行一維DCT需要64xS次乘法和56xS次加法,再進行8列一維DCT要64xS次乘法和56xS次加法,共需要64x8xZ=1024次乘法和56x8xZ=896次加法,計算量大為減少。
除此之外,DCT還有很多公開的快速算法。快速算法主要是通過減少運算次數(shù)而減少運算時間,這對于設計快速的硬件系統(tǒng)非常有效。二維DCT的快速算法則一般采用行列分離DCT算法,即轉換為兩次一維變換,其間通過轉置矩陣連接。最為經(jīng)典和常用的快速算法是由Arai等人于1988年提出的AAN算法以及Loeffier等人于1989年提出的LLM算法。但是,由于行列分離DCT算法能夠重復使用一維變換結構,因此在實際實現(xiàn)上,尤其在硬件上比二維直接計算算法更有優(yōu)勢。
二、源代碼
function varargout = imDCT(varargin)
% IMDCT M-file for imDCT.fig
% ? ? ?IMDCT, by itself, creates a new IMDCT or raises the existing
% ? ? ?singleton*.
%
% ? ? ?H = IMDCT returns the handle to a new IMDCT or the handle to
% ? ? ?the existing singleton*.
%
% ? ? ?IMDCT('CALLBACK',hObject,eventData,handles,...) calls the local
% ? ? ?function named CALLBACK in IMDCT.M with the given input arguments.
%
% ? ? ?IMDCT('Property','Value',...) creates a new IMDCT or raises the
% ? ? ?existing singleton*. ?Starting from the left, property value pairs are
% ? ? ?applied to the GUI before imDCT_OpeningFcn gets called. ?An
% ? ? ?unrecognized property name or invalid value makes property application
% ? ? ?stop. ?All inputs are passed to imDCT_OpeningFcn via varargin.
%
% ? ? ?*See GUI Options on GUIDE's Tools menu. ?Choose "GUI allows only one
% ? ? ?instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help imDCT
% Last Modified by GUIDE v2.5 07-Dec-2009 19:54:09
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name', ? ? ? mfilename, ...
? ? ? ? ? ? ? ? ? 'gui_Singleton', ?gui_Singleton, ...
? ? ? ? ? ? ? ? ? 'gui_OpeningFcn', @imDCT_OpeningFcn, ...
? ? ? ? ? ? ? ? ? 'gui_OutputFcn', ?@imDCT_OutputFcn, ...
? ? ? ? ? ? ? ? ? 'gui_LayoutFcn', ?[] , ...
? ? ? ? ? ? ? ? ? 'gui_Callback', ? []);
if nargin && ischar(varargin{1})
? ?gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
? ?[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
? ?gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% --- Executes just before imDCT is made visible.
function imDCT_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject ? ?handle to figure
% eventdata ?reserved - to be defined in a future version of MATLAB
% handles ? ?structure with handles and user data (see GUIDATA)
% varargin ? command line arguments to imDCT (see VARARGIN)
% Choose default command line output for imDCT
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes imDCT wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% --- Outputs from this function are returned to the command line.
function varargout = imDCT_OutputFcn(hObject, eventdata, handles)
% varargout ?cell array for returning output args (see VARARGOUT);
% hObject ? ?handle to figure
% eventdata ?reserved - to be defined in a future version of MATLAB
% handles ? ?structure with handles and user data (see GUIDATA)
% Get default command line output from handles structure
varargout{1} = handles.output;
function edit1_Callback(hObject, eventdata, handles)
% hObject ? ?handle to edit1 (see GCBO)
% eventdata ?reserved - to be defined in a future version of MATLAB
% handles ? ?structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit1 as text
% ? ? ? ?str2double(get(hObject,'String')) returns contents of edit1 as a double
% --- Executes during object creation, after setting all properties.
function edit1_CreateFcn(hObject, eventdata, handles)
% hObject ? ?handle to edit1 (see GCBO)
% eventdata ?reserved - to be defined in a future version of MATLAB
% handles ? ?empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% ? ? ? See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
? ?set(hObject,'BackgroundColor','white');
end
function edit2_Callback(hObject, eventdata, handles)
% hObject ? ?handle to edit2 (see GCBO)
% eventdata ?reserved - to be defined in a future version of MATLAB
% handles ? ?structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'String') returns contents of edit2 as text
% ? ? ? ?str2double(get(hObject,'String')) returns contents of edit2 as a double
% --- Executes during object creation, after setting all properties.
function edit2_CreateFcn(hObject, eventdata, handles)
% hObject ? ?handle to edit2 (see GCBO)
% eventdata ?reserved - to be defined in a future version of MATLAB
% handles ? ?empty - handles not created until after all CreateFcns called
% Hint: edit controls usually have a white background on Windows.
% ? ? ? See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
? ?set(hObject,'BackgroundColor','white');
end
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
ImgPath=get(handles.edit1,'String');
CompressRate=uint8(fix(str2num(get(handles.edit2,'String'))));
if CompressRate>64
? ?CompressRate=64;
end
if CompressRate<1
? ?CompressRate=1;
end
set(handles.edit2,'String',num2str(CompressRate));
img=imread(ImgPath);
axes(handles.axes1);
imshow(img);
set(handles.text7,'Visible','off');
set(handles.text7,'String','處理狀態(tài):正在處理中...');
set(handles.text7,'Visible','on');
pause(0.1);
Block=ceil(size(img)/8);
ImgDCT=zeros(Block*8);
ImgRestoreTemp=zeros(Block*8);
ImgRestore=zeros(size(img));
ImgBlock=zeros(8);
DCTBlock=zeros(8);
vector=zeros(1,64);
for ii=1:Block(1)
? ?for jj=1:Block(2)
? ? ? ?ImgBlock(:,:)=zeros(8);
? ? ? ?if ii==Block(1)
? ? ? ? ? ?if jj==Block(2)
? ? ? ? ? ? ? ?ImgBlock(1:size(img,1)-(ii-1)*8,1:size(img,2)-(jj-1)*8)=img((ii-1)*8+1:size(img,1),(jj-1)*8+1:size(img,2));
? ? ? ? ? ?else
? ? ? ? ? ? ? ?ImgBlock(1:size(img,1)-(ii-1)*8,:)=img((ii-1)*8+1:size(img,1),(jj-1)*8+1:jj*8);
? ? ? ? ? ?end
? ? ? ?else
? ? ? ? ? ?if jj==Block(2)
? ? ? ? ? ? ? ?ImgBlock(:,1:size(img,2)-(jj-1)*8)=img((ii-1)*8+1:ii*8,(jj-1)*8+1:size(img,2));
? ? ? ? ? ?else
? ? ? ? ? ? ? ?ImgBlock(:,:)=img((ii-1)*8+1:ii*8,(jj-1)*8+1:jj*8);
? ? ? ? ? ?end
? ? ? ?end
? ? ? ?DCTBlock(:,:)=dct2(ImgBlock(:,:));
? ? ? ?if CompressRate~=64
? ? ? ? ? ?vector(1:64)=m2v(DCTBlock(:,:));
? ? ? ? ? ?vector(CompressRate+1:64)=0;
? ? ? ? ? ?DCTBlock(:,:)=v2m(vector(1:64));
? ? ? ?end
? ? ? ?ImgDCT((ii-1)*8+1:ii*8,(jj-1)*8+1:jj*8)=DCTBlock(:,:);
? ?end
end
?
三、運行結果


?