说明
资料来自《详解MATLAB图像函数及其应用》
作者:张倩,占君,陈珊
出版社:电子工业出版社
出版时间:2011-04
这是我对MTALAB图像处理整理出来的学习笔记,望与君共勉
采用部分只有代码,其他的我自己收集来的资料,萌新一枚,侵权即删
内容来自书的第十九章1375页
图像配准
- 主要目的:
去除或抑制待配准图像和参考图像之间在几何上的不一致,并融合这些数据从而得到被测对象更完整的信息 - 配准控制点:
输入图像与参考图像上映射配准的对应点,而进行图像配准的几何参数需根据图像的一些配准点来进行计算
配准点选取
配准点的选取遵循的原则:
- 两幅图像上的配准点的特征必须保持一致,一般是两幅图像中都共同拥有的标记,如道路的拐弯或道路两旁的标志性建筑物等
- 选择的配准点要相对分散,尽量不要集中在某个区域
- 配准点的数量要恰当,不能过多也不能过少。配准点太少会影响配准精度,如果太多则影响配准速度。
对四幅不同的图像进行图像配准
本例通过图像配准将四幅图像转换成同一角度拍摄的同一幅图像
- 将图像读入MATLAB的工作区,通过对话框选择图像文件,打开图像文件并判断图像文件有效性
- 采集图像中的控制点对,并保存控制点对
对每幅图像进行控制点的采集,要求控制点个数至少要2个,每幅图像的控制点必须相同
为了便于采集控制点,将图像放大至屏幕左上角显示 - 选取一个基准图像进行图像配准
以第k帧图像为基准图像进行图像配准,配准前确定变换类型,利用指定的变换类型进行图像配准 - 显示配准后的图像
步骤一
下面是第一段源码
[filename,pathname]=uigetfile({'*.bmp';'*.jpg';'*.gif';'*.tif';'*.*'},'打开原始图','MultiSelect','on');
if ~iscell(filename)
errordlg('打开文件失败!');
return;
end
imnum=length(filename);
imA=cell(imnum,1);
for i=1:imnum
fullname=fullfile(pathname,filename{i});
imA{i}=imread(fullname);
figure
imshow(imA{i});
end
uigetfile函数
[filename,pathname]=uigetfile(filterspec,dialogtitle,‘MultiSelect’,mode)
- filename:返回的文件名,属性为细胞矩阵,每个元素存放一个文件的文件名
- pathname:返回的文件的路径名,属性为字符串,存放文件的路径
- filterspec:文件类型设置,如png,jpg,tif,gif等
- dialogtitle:打开对话框的标题,显示在选取图像时的对话框左上角
并且本例指定用户可以选择多个文件,将模式设置为on,将允许进行多选图像文件
- 其他用法:
创建标准的对话框并通过交互式操作取得文件名
file=uigetfile
- 显示一个模态对话框,对话框列出了当前目录下的文件和目录,用于可以选择一个将要打开的文件名
- 如果文件名是有效的且该文件存在,则当用户点击Open时函数uigetfile返回该文件名
- 若不存在,uigetfile显示一个控制返回对话框值的错误提示信息,此时用户可以输入另外的文件名或点击cancel按钮
- 如果用户点击cancel按钮或关闭对话框,函数uigetfile将返回0
[filename,pathname,filterindex]=uigetfile(filterspec,dialogtitle,defualtname)
- filename:返回的文件名
- pathname:返回的文件的路径名
- filterindex:选择的文件类型
- filterspec:文件类型设置
- dialogtitle:打开对话框的标题
- defaultname:默认指向的文件名
创建并显示对话框,列出当前目录下的文件
- FilterSpec决定文件的初始显示,它可以为一个文件全名或者包含通配符*,如‘*.doc’表示列出所有的文档文件
- 如果FilterSpec是一个包含文件名的字符串,则该文件名所在的文件名域将被选中并显示出来,且该文件的扩展名将作为过滤作用
- 如果FilterSpec是一个包含文件路径的字符串,例如‘.’,’…’或’/’,例如‘…/*.m’表示列出当前目录上的所有M文件
- 如果FilterSpec是一个单元数组,则其第一列为扩展名列表,第二列为描述列表
- 如果FilterSpec没有指定路径对象,则uigetfile将使用默认路径下的所有文件类型
iscell函数
tf=iscell(A)
- 如果A为cell array,则返回1,否则返回0
errordlg函数
errordlg(error_string)
错误对话框
- 其他:
- 普通对话框——h=dialog(‘PropertyName’,‘PropertyValue’)
- 警告对话框——h=warndlg(warning_string,dlgname,createmode)
- 帮助对话框——help(‘help_string’,‘dlgname’)
- 信息对话框——msgbox(message,title,icon)
- icon有’error’,‘warn’,‘help’,‘custom’
- 提问对话框——button=questdlg(‘q_string’,‘titlt’,‘str1’,‘str2’,‘str3’,default)
length函数
y=length(x)
- 计算指定向量或矩阵的长度y,x为向量则返回长度,x为非空矩阵,则length(x)等价于max(size(x))
cell函数
a=cell(n,m)
- 把a初始化为一个n行m列的空元胞数组
赋值方式:a{1,1}=rand(5)
fullfile函数
f=fullfile(filepart1,…,filepartN)
- 从各部分构建完整的文件名
- 不同平台的文件分隔符不同,windows为反斜杠(\),最后一个part的末尾无分隔符
结果就创建了每幅图的路径
因为是循环出来的,所以就剩一个第四幅图的路径,结果会弹四个窗口出来的,很占底部状态栏,可以关了吧
imread函数
[X,map]=imread(filename)
- 从指定的图像文件中读取索引图像和颜色表
X为索引图像
map为颜色表,其值自动被调整到[0 1]的范围
A=imread(filename,fmt)
- 从指定的图像中读取灰度图像或真彩色图像
filename表示文件名
fmt表示文件类型
其他说明
- 读取图像,我把tif格式去掉之后便出现了下图
去掉后面的“.”好像没啥用啊,那个所有文件的按钮都在的 - 然后打开原始图显示在
这个位置 - 打开失败是这样的
就是读取进去然判断是否读入了元胞数组,这些元胞数组被读成的样子是
我读入了四个读片,分别叫imge1/2/3/4,格式为png(QQ截图)
至于那个return到底是怎么回事,我学matlab到现在也没明白,也许有一天能理解吧 - 然后是图像个数、创建4x1的元胞数组、显示读取的图像,注意uigetfile并没有读入图片,而是读入图片的路径信息,最终读入图片要靠循环和imread函数给imA数组,元胞数组用{}这个括号
步骤二
hfigid=figure;
scrsz=get(0,'ScreenSize');
for i=1:imnum
imagevalue=imA{i};
imshow(imagevalue);
set(hfigid,'Position',[0,scrsz(4)*0.3-80,scrsz(3)*0.7,scrsz(4)*0.7]);
if i==1
ka=sum(size(imagevalue));%length(imagevalue)
k=1;
xy=ginput;
xynum=size(xy,1);
if xynum<2
errordlg('控制点个数至少要两个');
close(hfigid);
return;
end
imxy=zeros(xynum,2,imnum);
questdlg({['控制点个数:',num2str(xynum)]});
hfig0=figure;
figure(hfig0);
imshow(imagevalue);
hold on;
plot(xy(:,1),xy(:,2),'*r');
hold off;
figure(hfigid);
else
ka1=sum(size(imagevalue));
if ka>ka1
k=i;
ka=ka1;
end
xy=ginput(xynum);
if size(xy,1)~=xynum
errordlg('控制点个数不一致');
close(hfigid);
close(hfig0);
return;
end
end
imxy(:,:,i)=xy;
end
close(hfigid);
close(hfig0);
get函数
v=get(h)
- 查询图形对象属性
本例是返回句柄0的对象的screensize值
set函数
set(H,name,value)
- 设置图形对象属性
为H标识的对象指定其name属性的值 - 使用时须用单引号将属性名引起来,如果H是对象的向量,则set会为所有对象设置属性
本例用于设置句柄参数的位置和大小
ginput函数
[x,y]=ginput
- 标识坐标区坐标
- 可用于无线多个点,要选择一个点,将光标移至所需位置,然后按下鼠标按键或键盘上的键,按return键可停止选择,返回所选点的坐标
- 如果没有当前坐标区,调用ginput会创建一个笛卡尔坐标区
对于[x,y,button]=ginput(N),其中N为次数,button为操作的ascii码,x,y为横纵坐标,敲击键盘或鼠标总计N次后返回相应值
本例在i=1也就是对第一幅图进行采样,xy内记录了鼠标点击的地方的坐标值,一般应该都是Nx2的double型吧,我还没采集过3维,毕竟这个例子就是采集二维然后分析特征的嘛
其他说明
- hfigid结果变成了figure类型,继续打开之后就是一列可以继续打开的数据,然而打开之后什么都没有,连数据都没有,如下图
采集图像中的控制点对,并保存控制点对
对每幅图像进行控制点的采集,要求控制点个数至少2个,每幅图像的控制点必须相同,反正你的点数相同才能继续下一幅图的采集和结束采集点操作
- 图像统一放大至屏幕左上角显示
-
通过鼠标采集控制点,并记录控制点个数
xynum里就记录了点的个数 -
最后的IF语句模块用于判断采集点数是否大于等于2
显示第一幅图像及其控制点,作为后面图像的控制,并选取尺寸最小的图像作为基准图像
本次我采用maya制作一个长方体,并用ps进行图像大小限制之后再进行的采样,故四幅图大小一致
判断控制点个数是否一致,并且关闭图像
- 然后是用zeros函数创建一个xynum2imnum大小的三维零矩阵,本次应是3x2x4,即三个采样点,x和y两个坐标值,4幅图
- 第一幅图采样完之后你可以敲击回车结束采集,会弹出一个询问框,如下图
比如我某一次采样点为4,然后执行hold on;plot第一列所有点+第二列所有点+红色星号
可以看到已经是第七张新图了,然后继续弹出第二幅图的采样,当你完成第二幅图的采样时,上面这幅图也不会消失,直到你把四幅图采样完成才会关闭 - 然后是hfig0的出现,它就是创建采样图的那个新图用的,正常情况下会出现读取的4幅图即figure1234,然后采样图占一幅5,出现这个hfig0就是第6个句柄,我出现7是还有一幅我上次采样三个点用的
- 然后下边是if语句的出现,这是用来查找最小的图像的
- 又继续用ginput函数采点,达到第一幅图的采集次数会自动进行下一幅(close函数),点数不够又敲击的话会弹出报错窗口,然后关闭第一幅图的采样位置图
- 或者采集完也会自动关闭的,一个在if语句内,一个在外
- 然后把采集的位置传给imxy,前两个全部传,第三维指向图的顺序
步骤三
imA1=imA{k};
[imAx,imAy]=size(imA1);
if xynum==2
formstr='linear conformal';
elseif xynum==3
formstr='affine';
else
strlx=questdlg('请选择变换类型:仿射变换(Affine)/透视变换(Projective)','','Affine','Projective','Cancel','Affine');
if strcmp(strlx,'Affine')
formstr='affine';
elseif strcmp(strlx,'Projective')
formstr='projective';
else
return;
end
end
imB=uint8(zeros(imAx,imAy,3,imnum));
for i=1:imnum
tform=cp2tform(imxy(:,:,i),imxy(:,:,k),formstr);
imB(:,:,:,i)=imtransform(imA{i},tform,'XData',[1 imAy],'YData',[1 imAx]);
end
uint8函数
Y=uint8(X)
- 8位无符号整数数组
- 将X中的值转换为uint8类型,超出范围[0 2^8-1]的值映射到最近的端点,对数对矩阵都是如此,此为标量操作
本次出现4-D uint8表示4维无符号整型,第四维表示帧数
zeros函数
X=zeros(sz1,…,szN)
- 返回由0组成的sz1x…xszN数组
cp2tform函数
TFORM = cp2tform(input_points, base_points, ‘affine’);
- 对图像进行变换(模型参数估计)
- 在图像配准中,分别由标准图像和待测图像得出关键点坐标后,需进行仿射变换参数估计
我也没看懂这个函数,它创造出来的参量是这样的
看了好久的帮助文档之后,我只能说这个函数可以用于图像的旋转(二、三维)、液化、分段线性拉伸、分段非线性拉伸,我也用其他简单的参数试了一下
没看懂,可能是里边还有嵌套的概念吧,容我研究个几年
imtransform函数
B=imtransform(A,tform)
- 参数tform来自cp2tform函数
- 将二维空间变换应用于图像
- 具体细节请移步帮助文档
- 按我第一次研究的理解的话,就是可以用一个三维实现灰度图像的变形,要保持1x0;x10;001这样的,其中x可以作为修改图片的参数,第一行作为左右边的图片的上下错位,第二行作为图片的上下边错位,书面表达叫水平(垂直)剪切
- 还有个用途叫做图像配准,就是你拍同一个东西,会产生手抖,就有核心内容还在,但是边缘出现内容的增加或减少,然后用这个函数进行亿些操作,就可以检测出一点点变化
- 本例中的XData、YData指XY输出空间中的空间范围,XData 的两个元素分别给出 B 的第一列和最后一列的 x 坐标(水平)。YData 的两个元素给出 B 的第一行和最后一行的 y 坐标(垂直)。
其他说明
- 当控制点为2时,默认使用线形变换矩阵
- 当控制点为3时,默认使用仿射变换矩阵
- 当控制点大于3时,由用户选择使用仿射变换矩阵或透视矩阵,由questdlg函数弹出选择框
- 然后定义一个四维零矩阵,存放配准后的图像集,原代码中第三维大小为1,于是matlab弹出error,在修改创建大小和存放大小之后,error消失
- k出现在判断最小的图那里,因为我的四幅图大小一样,所以k=1
步骤四
figure
montage(imB);
montage函数
montage(photoname1,photoname2,…)
montage(D,map)
- 显示多帧图像的所有帧
测试结果
第一幅图
当采样点数为3时
当采样点数为4且选择affine仿射变换
我们可以知道这个图像配准配了什么鬼我们并看不懂,如实我按照教材说的各种奇妙的三角形去试试
第一幅采样图
2个采样点
4个采样点,选择affine
终于到这里变得规则了一点,至于这些图给了什么信息,还请容我用时间来慢慢渗透理解
转载:https://blog.csdn.net/qq_43600632/article/details/105690198