【图像压缩】基于主成分分析PCA算法实现图像压缩matlab源码

基于几何特征的模板匹配通过计算模板图像与目标图像特征信息,来判断目标图像中是否有与模板图像相近或相同的图像。
模板匹配的大致流程:
首先,需要制作一个模板,并以模板图像以一定角度旋转,制作0°–360°各个方向的模板。模板图像 T 从目标图像的原点处开始每次移动一个像素,直到匹配分数达到要求找到目标物体。
在这里插入图片描述

基于边缘模板的创建:

我们首先从模板图像的边缘创建一个数据集或模板模型,该数据集或模板模型将用于目标图像中去搜索与模板图像相近或相同的图像。边缘检测的方法与canny边缘检测的方法类似。

1利用sobel算子寻找图像的梯度和方向

Sobel算子卷积因子如图所示
在这里插入图片描述
sobel算子在横向和纵向两个方向可以与图像作平面卷积。对于模板图像某点(x,y)可以得出两个方向的梯度向量Gx,Gy;

我们计算该像素点幅值梯度:
在这里插入图片描述

计算梯度方向:
在这里插入图片描述

2非最大值抑制原理提取边缘信息

sobel算子检测出来的边缘太粗了,我们需要抑制那些梯度不够大的像素点,只保留最大的梯度,从而达到瘦边的目的。这些梯度不够大的像素点很可能是某一条边缘的过渡点。按照高数的极大值的定义,即对点(x0,y0)的某个邻域内所有(x,y)都有f(x,y)≤(f(x0,y0),则称f在(x0,y0)具有一个极大值,极大值为f(x0,y0)。简单方案是判断一个像素点的8邻域与中心像素谁更大,但这很容易筛选出噪声,因此我们需要用梯度和梯度方向来辅助确定。
如下图所示,中心像素C的梯度方向是蓝色直线dTmp1,dTmp2是梯度直线上与邻域交点的值,那么只需比较中心点C与dTmp1和dTmp2的大小即可。由于这两个点的像素不知道,假设像素变化是连续的,就可以用g1、g2和g3、g4进行线性插值估计。设g1的幅值M(g1),g2的幅值M(g2),则M(dtmp1)=w*M(g2)+(1-w)*M(g1) ,其w=distance(dtmp1,g2)/distance(g1,g2) 。也就是利用g1和g2到dTmp1的距离作为权重,来估计dTmp1的值。经过非最大值抑制可以滤除大部分非边缘点。
在这里插入图片描述

3用双阈值算法检测和连接边缘

经过非极大值抑制之后的边缘点中,梯度值超过T1的称为强边缘,梯度值小于T1大于T2的称为弱边缘,梯度小于T2的不是边缘。可以肯定的是,强边缘必然是边缘点,因此必须将T1设置的足够高,以要求像素点的梯度值足够大(变化足够剧烈),而弱边缘可能是边缘,也可能是噪声,如何判断呢?当弱边缘的周围8邻域有强边缘点存在时,就将该弱边缘点变成强边缘点,以此来实现对强边缘的补充。
在这里插入图片描述
由此我们找到了模板图像边缘点的梯度信息Gx,Gy,θ,和位置信息(x,y)在与原图像匹配之前我们的模板数据集用如下方法表示:
其中pi为相对于模板重心的相对坐标。pi=(Xi,Yi)T,i=1,2,3,4…n构成,对应于每个点有一个梯度方向向量di=(ti,ui)T

模板匹配:

1计算被搜索图像

计算被搜索图像(目标图像)边缘点梯度信息,边缘点梯度信息与位置信息的计算同模板制作的过程。

2金字塔下采样

金字塔下采样后,需得到多级金字塔图像的边缘点梯度信息,边缘点梯度信息与位置信息的计算同模板制作的过程。其中金字塔用来对算法进行加速。

3匹配过程:

先在顶层金字塔进行快速搜索匹配得到一个匹配位置,然后在下一层金字塔进行匹配时候就能在该区域的ROI内进行搜索,以此类推,直到最底层。通过金字塔可以大大加快匹配速度。
搜索目标图像之前,我们设被搜索图像(目标图像)点集(xi,yi)T, i=1,2,3,4…n,对应的每个点的方向向量为e(x,y)=(vx,y,wx,y)T
由图像金字塔算法得到被搜索图像底层的ROI区域后,模板图像以重心点为原点在ROI区域进行遍历搜索。
搜索过程按如下公式进行:
在这里插入图片描述
(上式di’相当于上文提到的di=模板的方向向量,pi’相当于上文提到的pi’=模板的边缘点)
计算的是模板与子图像对应边缘点的梯度向量点积平均值。当一对对应边缘点梯度方向相同是,点积取得最大值,梯度方向正交时,点积为零,梯度方向相反时,点积取得负的最大值。计算得到的相似度量值不方便用于判断子图像是否为符合要求的结果,即很难确定一个阈值来筛选所需要的结果。因而对上式进行归一化处理:
在这里插入图片描述
(上式di’相当于上文提到的di=模板的方向向量,pi’相当于上文提到的pi’=模板的边缘点)
上式描述的是,转换后的模板与被搜索图像点(x, y)处子图像所有对应点的方向向量点积和的归一化。由于对方向向量进行了归一化处理,相似度量对任意光照变化具有不变性,不管是模板、还是搜索图像中有噪声,由于噪声导致的方向向量是随机的,平均起来对以上求和公式没有贡献值,因而具有很好的抗干扰性。上式的取值范围为[−1, 1],返回值为1时,表示模板和搜索子图像与完全匹配。

function varargout = daunxujian1(varargin)
% DAUNXUJIAN1 MATLAB code for daunxujian1.fig
%      DAUNXUJIAN1, by itself, creates a new DAUNXUJIAN1 or raises the existing
%      singleton*.
%
%      H = DAUNXUJIAN1 returns the handle to a new DAUNXUJIAN1 or the handle to
%      the existing singleton*.
%
%      DAUNXUJIAN1('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in DAUNXUJIAN1.M with the given input arguments.
%
%      DAUNXUJIAN1('Property','Value',...) creates a new DAUNXUJIAN1 or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before daunxujian1_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to daunxujian1_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 daunxujian1
 
% Last Modified by GUIDE v2.5 23-Oct-2020 21:52:34
 
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @daunxujian1_OpeningFcn, ...
                   'gui_OutputFcn',  @daunxujian1_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 daunxujian1 is made visible.
function daunxujian1_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 daunxujian1 (see VARARGIN)
% Choose default command line output for daunxujian1
handles.output = hObject;
handles.Result = [];
handles.File = [];
% Update handles structure
guidata(hObject, handles);
clc; warning off all;
InitAxes(handles);
% UIWAIT makes daunxujian1 wait for user response (see UIRESUME)
% uiwait(handles.figure1);
 
 
% --- Outputs from this function are returned to the command line.
function varargout = daunxujian1_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;
 
 
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname] = uigetfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
    '*.*','All Files' },'载入图像',...
    fullfile(pwd, 'images'));
I = imread(fullfile(pathname, filename));
Result = Process_Main(I);
handles.File = fullfile(pathname, filename);
handles.Result = Result;
guidata(hObject, handles);
InitAxes(handles)
axes(handles.axes1); imshow(handles.Result.Image); title('原图像');
 
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if ~isempty(handles.Result)
    axes(handles.axes1); imshow(handles.Result.Image); title('原图像');
    axes(handles.axes2); imshow(handles.Result.Medfilt); title('中值滤波图像');
end
 
% --- Executes on button press in pushbutton3.
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if ~isempty(handles.Result)
    axes(handles.axes1); imshow(handles.Result.Image); title('原图像');
    axes(handles.axes2); imshow(handles.Result.Medfilt); title('中值滤波图像');
    axes(handles.axes3); imshow(handles.Result.Normalize); title('归一化图像');
end
 
% --- Executes on button press in pushbutton4.
function pushbutton4_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if ~isempty(handles.Result)
    axes(handles.axes1); imshow(handles.Result.Image); title('原图像');
    axes(handles.axes2); imshow(handles.Result.Medfilt); title('中值滤波图像');
    axes(handles.axes3); imshow(handles.Result.Normalize); title('归一化图像');
    axes(handles.axes4); imshow(handles.Result.Bww); title('二值化图像');
end
 
% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if ~isempty(handles.Result)
    axes(handles.axes1); imshow(handles.Result.Image); title('原图像');
    axes(handles.axes2); imshow(handles.Result.Medfilt); title('中值滤波图像');
    axes(handles.axes3); imshow(handles.Result.Normalize); title('归一化图像');
    axes(handles.axes4); imshow(handles.Result.Bww); title('二值化图像');
    axes(handles.axes6); imshow(handles.Result.Thin); title('细化处理');
    axes(handles.axes5); imshow(handles.Result.Bw); title('特征提取');
    hold on;
    h = [];
    for i = 1 : length(handles.Result.hs) %绘制水平线
        h = [h plot([1 handles.Result.sz(2)], [handles.Result.hs(i) handles.Result.hs(i)], 'r-')];
    end
    for i = 1 : length(handles.Result.vs)%绘制竖直线
        h = [h plot([handles.Result.vs(i) handles.Result.vs(i)], [1 handles.Result.sz(1)], 'g-')];
    end
    h = [h plot(handles.Result.x1, handles.Result.y1, 'y-')];%绘制左对角线
    h = [h plot(handles.Result.x2, handles.Result.y2, 'm-')];%绘制右对角线
end
 
% --- Executes on button press in pushbutton7.
function pushbutton7_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton7 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[filename, pathname] = uiputfile({'*.jpg;*.tif;*.png;*.gif','All Image Files';...
    '*.*','All Files' },'Save Image',...
    fullfile(pwd, 'Result/result.png'));
if ~isequal(filename, 0)
    imwrite(handles.Result.label, fullfile(pathname, filename));
    msgbox('保存图像成功!', '信息提示框');
end
 
 
% --- Executes on button press in pushbutton9.
function pushbutton9_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton9 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
choice = questdlg('确定退出?', ...
    '退出', ...
    '是','否','否');
switch choice
    case '是'
        close;
    otherwise
        return;
end
 
 
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
 
 
% --- Executes on button press in pushbutton8.
function pushbutton8_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton8 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
set(handles.edit1,'string',handles.Result.label);
 
 
% --- Executes on button press in pushbutton10.
function pushbutton10_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton10 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
if ~isempty(handles.Result)
    axes(handles.axes1); imshow(handles.Result.Image); title('原图像');
    axes(handles.axes2); imshow(handles.Result.Medfilt); title('中值滤波图像');
    axes(handles.axes3); imshow(handles.Result.Normalize); title('归一化图像');
    axes(handles.axes4); imshow(handles.Result.Bww); title('二值化图像');
    axes(handles.axes6); imshow(handles.Result.Thin); title('细化处理');
end

【图像压缩】基于主成分分析PCA算法实现图像压缩matlab源码_第1张图片

完整代码或者代写添加QQ1575304183

一、PCA简介

主成分分析(Principal Component Analysis,PCA), 是一种统计方法。通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。

二、PCA提出的背景

在许多领域的研究与应用中,往往需要对反映事物的多个变量进行大量的观测,收集大量数据以便进行分析寻找规律。多变量大样本无疑会为研究和应用提供了丰富的信息,但也在一定程度上增加了数据采集的工作量,更重要的是在多数情况下,许多变量之间可能存在相关性,从而增加了问题分析的复杂性,同时对分析带来不便。如果分别对每个指标进行分析,分析往往是孤立的,而不是综合的。盲目减少指标会损失很多信息,容易产生错误的结论。

因此需要找到一个合理的方法,在减少需要分析的指标同时,尽量减少原指标包含信息的损失,以达到对所收集数据进行全面分析的目的。由于各变量间存在一定的相关关系,因此有可能用较少的综合指标分别综合存在于各变量中的各类信息。主成分分析与因子分析就属于这类降维的方法。

三、PCA的推导

主成分的意思就是数据的主要成分,对于给定的一些数据,我们一般来说关心的是数据中变化的部分,变化的越多,我们得到的信息也就越多,而数据中不变的地方,我们能收集到的信息非常有限,所以,数据中变化较多的部分就构成了数据的主成分。

为了说明什么是数据的主成分,先从数据降维说起。数据降维是怎么回事儿?假设三维空间中有一系列点,这些点分布在一个过原点的斜面上,如果你用自然坐标系x,y,z这三个轴来表示这组数据的话,需要使用三个维度,而事实上,这些点的分布仅仅是在一个二维的平面上,那么,问题出在哪里?如果你再仔细想想,能不能把x,y,z坐标系旋转一下,使数据所在平面与x,y平面重合?这就对了!如果把旋转后的坐标系记为x’,y’,z’,那么这组数据的表示只用x’和y’两个维度表示即可!当然了,如果想恢复原来的表示方式,那就得把这两个坐标之间的变换矩阵存下来。这样就能把数据维度降下来了!但是,我们要看到这个过程的本质,如果把这些数据按行或者按列排成一个矩阵,那么这个矩阵的秩就是2!这些数据之间是有相关性的,这些数据构成的过原点的向量的最大线性无关组包含2个向量,这就是为什么一开始就假设平面过原点的原因!那么如果平面不过原点呢?这就是数据中心化的缘故!将坐标原点平移到数据中心,这样原本不相关的数据在这个新坐标系中就有相关性了!有趣的是,三点一定共面,也就是说三维空间中任意三点中心化后都是线性相关的,一般来讲n维空间中的n个点一定能在一个n-1维子空间中分析!

上一段文字中,认为把数据降维后并没有丢弃任何东西,因为这些数据在平面以外的第三个维度的分量都为0。现在,假设这些数据在z’轴有一个很小的抖动,那么我们仍然用上述的二维表示这些数据,理由是我们可以认为这两个轴的信息是数据的主成分,而这些信息对于我们的分析已经足够了,z’轴上的抖动很有可能是噪声,也就是说本来这组数据是有相关性的,噪声的引入,导致了数据不完全相关,但是,这些数据在z’轴上的分布与原点构成的夹角非常小,也就是说在z’轴上有很大的相关性,综合这些考虑,就可以认为数据在x’,y’ 轴上的投影构成了数据的主成分。

PCA的思想是将n维特征映射到k维上(k是重新构造出来的k维特征,而不是简单地从n维特征中去除其余n-k维特征。

总结一下,做PCA的主要步骤如下:

设有m条n维数据。

1)将原始数据按照m行n列排列的,如matlab和Python中都是这样(每一列代表一个特征)

2)将X的每一列(代表一个属性字段)进行零均值化,即减去这一列的均值

3)求出协方差矩阵

4)求出协方差矩阵的特征值及对应的特征向量

5)将上一步得到的特征向量组成矩阵V

6)求Y=XV,再取Y的前k列得到Y'即为要求的矩阵

这里注释一下以上矩阵的维数便于理解,在编程时防止矩阵相乘时的维数错误:

矩阵X:m x n (n维m个数据)

矩阵V:n x n

矩阵Y:m x n(n维m个数据)

矩阵Y':m x k(k维m个数据)

clc; clear all; close all;
I=imread('liftingbody.png');
k=1;
figure('Units', 'Normalized', 'Position', [0 0 1 1]);
for p=1:5:20
    [Ipca,ratio,contribution]=pcaimage(I,p,[24 24]);
    subplot(2,2,k);    
    imshow(Ipca)
    title(['主成分个数=',num2str(p),...
        ',压缩比=',num2str(ratio),...
        ',贡献率=',num2str(contribution)],'fontsize',14);
    k=k+1;
end

【图像压缩】基于主成分分析PCA算法实现图像压缩matlab源码_第2张图片

你可能感兴趣的:(图像处理,matlab,算法,机器学习)