1. 程式人生 > 其它 >【影象壓縮】基於matlab GUI DCT影象壓縮(壓縮率可調)【含Matlab原始碼 1049期】

【影象壓縮】基於matlab GUI DCT影象壓縮(壓縮率可調)【含Matlab原始碼 1049期】

一、簡介

1 DCT演算法:
DCT變換的全稱是離散餘弦變換(Discrete Cosine Transform),離散餘弦變換相當於一個長度大概是它兩倍的離散傅立葉變換,這個離散傅立葉變換是對一個實偶函式進行的。通過數字訊號處理的學習我們知道實函式的傅立葉變換獲得的頻譜大多是複數,而偶函式的傅立葉變換結果是實函式。以此為基礎,使訊號函式成為偶函式,去掉頻譜函式的虛部,是餘弦變換的特點之一。它可以將將一組光強資料轉換成頻率資料,以便得知強度變化的情形。若對高頻的資料做些修飾,再轉回原來形式的資料時,顯然與原始資料有些差異,但是人類的眼睛卻是不容易辨認出來。壓縮時,將原始影象資料分成8*8資料單元矩陣,例如亮度值的第一個矩陣內。

2 DCT產生的工程背景:

視訊訊號的頻譜線在0-6MHz範圍內,而且1幅視訊影象內包含的大多數為低頻頻譜線,只在佔影象區域比例很低的影象邊緣的視訊訊號中才含有高頻的譜線。因此,在視訊訊號數字處理時,可根據頻譜因素分配位元數:對包含資訊量大的低頻譜區域分配較多的位元數,對包含資訊量低的高頻 譜區域分配較少的位元數,而影象質量並沒有可察覺的損傷,達到位元速率壓縮的目的。然而,這一切要在低熵(Entropy)值的情況下,才能達到有效的編碼。能否對一串資料進行有效的編碼,取決於每個資料出現的概率。每個資料出現的概率差別大,就表明熵值低, 可以對該串資料進行高效編碼。反之,出現的概率差別小,熵值高,則不能進行高效編碼。視訊訊號的數字化是在規定的取樣頻率下由A/D轉換器對視訊電平轉換而來的,每個畫素的視訊訊號幅度隨著每層的時間而週期性地變化。每個畫素的平均資訊量的總和為總平均資訊量,即熵值。由於每個視訊電平發生幾乎具有相等的概率,所以視訊訊號的熵值很高。 熵值是一個定義位元速率壓縮率的引數,視訊影象的壓縮率依賴於視訊訊號的熵值,在多數情況下視訊訊號為高熵值,要進行高效編碼,就要將高熵值變為低熵值。怎樣變成低熵值呢?這就需要分析視訊頻譜的特點。大多數情況下,視訊頻譜的幅度隨著頻率的升高而降低。其中 低頻頻譜在幾乎相等的概率下獲得0到最高的電平。與此相對照,高頻頻譜通常得到的是低電平及稀少的高電平。顯然,低頻頻譜具有較高的熵值,高頻頻譜具有較低的熵值。據此,可對視訊的低頻分量和高頻分量分別處理,獲得高頻的壓縮值。

自從Ahmed和Rao於1974年給出了離散餘弦變換(DCT)的定義以來,離散餘弦變換(DCT)與改進型離散餘弦變換(MDCT)就成為廣泛應用於訊號處理和影象處理特別是用於影象壓縮和語音壓縮編解碼的重要工具和技術,一直是國際學術界和高科技產業界的研究熱點。現在的很多影象和視訊編碼標準(如MPEG-1 , MEPG-2 ,MEPG-4中的第二部分)都要求實現整數的8×8 的DCT和IDCT,而MDCT 和IMDCT 則主要被應用於音訊訊號的編解碼中(如MPEG-1 ,MEPG-2 和AC-]等標準的音訊編碼部分)。正是由於這類變換被廣泛採用,對於這類變換的快速演算法的研究才顯得尤為重要。特別是針對特定的應用條件下的快速演算法的研究對於提高整個系統的效能表現有很大幫助。
由上面的引用可見,位元速率壓縮基於變換編碼和熵值編碼兩種演算法。前者用於降低熵值,後者將資料變為可降低位元數的有效編碼方式。在MPEG標準中,變換編碼採用的是DCT,變換過程本身雖然並不產生位元速率壓縮作用,但是變換後的頻率係數卻非常有利於位元速率壓縮。 實際上壓縮數字視訊訊號的整個過程分為塊取樣、DCT、量化、編碼4個主要過程進行-----首先在時間域將原始影象分成N(水平)×N(垂直)取樣塊,根據需要可選擇4×4、4×8、8×8、8×16、16×16等塊,這些取樣的畫素塊代表了原影象幀各畫素的灰度值,其範圍在139-163之間,並依序送入DCT編碼器,以便將取樣塊由時間域轉換為頻率域的DCT係數塊。DCT系統的轉換分別在每個取樣塊中進行,這些塊中每個取樣是數字化後的值,表示一場中對應畫素的視訊訊號幅度值

3 離散餘弦變換的實現:

實現DCT的方法很多,最直接的是根據DCT的定義來計算。以二維8xSDCT為例,需要作4096次乘法和3584次加法。這種演算法的實現需要巨大的計算量,不具有實用價值。在應用中,需要尋找快速而又精確的演算法。較為常用的方法是利用DCT的可拆分特性,同樣以二維8xSDCT為例,先進行8行一維DCT需要64xS次乘法和56xS次加法,再進行8列一維DCT要64xS次乘法和56xS次加法,共需要64x8xZ=1024次乘法和56x8xZ=896次加法,計算量大為減少。

除此之外,DCT還有很多公開的快速演算法。快速演算法主要是通過減少運算次數而減少運算時間,這對於設計快速的硬體系統非常有效。二維DCT的快速演算法則一般採用行列分離DCT演算法,即轉換為兩次一維變換,其間通過轉置矩陣連線。最為經典和常用的快速演算法是由Arai等人於1988年提出的AAN演算法以及Loeffier等人於1989年提出的LLM演算法。但是,由於行列分離DCT演算法能夠重複使用一維變換結構,因此在實際實現上,尤其在硬體上比二維直接計算演算法更有優勢。

二、原始碼

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-Jun-2021 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','處理狀態:正在處理中...');
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

三、執行結果

四、備註

版本:2014a
完整程式碼或代寫加1564658423