学习了第10章的后半部分和第11章
plot
x=0:pi/100:2*pi;
y=2exp(-0.5x).sin(2pi*x);
plot(x,y)
程序执行后,打开一个图形窗口,在其中绘制出如下曲线
注意:指数函数和正弦函数之间要用点乘运算,因为二者是向量。
例52 绘制曲线
这是以参数形式给出的曲线方程,只要给定参数向量,再分别求出x,y向量即可输出曲线:
t=-pi:pi/100:pi;
x=t.cos(3t);
y=t.sin(t).sin(t);
plot(x,y)
程序执行后,打开一个图形窗口,在其中绘制出如下曲线
以上提到plot函数的自变量x,y为长度相同的向量,这是最常见、最基本的用法。实际应用中还有一些变化。分别说明:
①
2. 含多个输入参数的plot函数
plot函数可以包含若干组向量对,每一组可以绘制出一条曲线。含多个输入参数的plot函数调用格式为:plot(x1,y1,x2,y2,…,xn,yn)
如下列命令可以在同一坐标中画出3条曲线。
x=linspace(0,2*pi,100);
plot(x,sin(x),x,2sin(x),x,3sin(x))
当输入参数有矩阵形式时,配对的x,y按对应的列元素为横坐标和纵坐标绘制曲线,曲线条数等于矩阵的列数。
x=linspace(0,2*pi,100);
y1=sin(x);
y2=2*sin(x);
y3=3*sin(x);
x=[x;x;x]\';
y=[y1;y2;y3]\';
plot(x,y,x,cos(x))
x,y都是含有三列的矩阵,它们组成输入参数对,绘制三条曲线;x和cos(x)又组成一对,绘制一条余弦曲线。
利用plot函数可以直接将矩阵的数据绘制在图形窗体中,此时plot函数将矩阵的每一列数据作为一条曲线绘制在窗体中。如
A=pascal(5)
A =
1 1 1 1 1
1 2 3 4 5
1 3 6 10 15
1 4 10 20 35
1 5 15 35 70
plot(A)
3. 含选项的plot函数
Matlab提供了一些绘图选项,用于确定所绘曲线的线型、颜色和数据点标记符号。这些选项如表所示:
线型
颜色
标记符号
- 实线
b蓝色
. 点
- s 方块
- 虚线
g绿色
o 圆圈
d 菱形
-. 点划线
r红色
× 叉号
∨朝下三角符号
-- 双划线
c青色
- 加号
∧朝上三角符号
m品红
- 星号
<朝左三角符号
y黄色
朝右三角符号
k黑色
p 五角星
w白色
h 六角星
例 用不同的线型和颜色在同一坐标内绘制曲线 及其包络线。
x=(0:pi/100:2*pi)\';
y1=2exp(-0.5x)*[1,-1];
y2=2exp(-0.5x).sin(2pi*x);
x1=(0:12)/2;
y3=2exp(-0.5x1).sin(2pi*x1);
plot(x,y1,\'k:\',x,y2,\'b--\',x1,y3,\'rp\');
在该plot函数中包含了3组绘图参数,第一组用黑色虚线画出两条包络线,第二组用蓝色双划线画出曲线y,第三组用红色五角星离散标出数据点。
集合运算
f = imread(\'Fig0903(utk).tif\');
g = imread(\'Fig0903(gt).tif\');
subplot(2, 3, 1), imshow(f), title(\'UTK\');
subplot(2, 3, 2), imshow(g), title(\'GT\');
subplot(2, 3, 3), imshow(~f), title(\'UTK的补集\');
subplot(2, 3, 4), imshow(f | g), title(\'UTK和GT的合集\');
subplot(2, 3, 5), imshow(f & g), title(\'UTK和GT的交集\');
subplot(2, 3, 6), imshow(f & ~g), title(\'UTK和GT的差集\');
霍夫变换的线检测
S=sparse(r, c, s, m, n)将矩阵变为稀疏矩阵
full(S) 可以将稀疏矩阵还原
函数 intline(x1, x2, y1, y2) 将二个点连起来,并返回这条线的向量
[x, y] = intline(0, 100, 0, 100);
imshow(bound2im(cat(2, x, y)));
函数 [H,theta,rho] = hough(f)
f = zeros(101, 101);
f(1, 1) = 1;
f(101, 1) = 1;
f(1, 101) = 1;
f(101, 101) = 1;
f(51, 51) = 1;
[H,theta,rho] = hough(f);
subplot(1, 2, 1), imshow(f), title(\'原图\');
subplot(1, 2, 2), imshow(H,[],\'XData\',theta,\'YData\',rho,...
\'InitialMagnification\',\'fit\'), title(\'计算后\');
xlabel(\'\theta\'), ylabel(\'\rho\');
axis on, axis normal;
函数[r,c,hnew] = houghpeaks(h,numpeaks,threshold,nhood)
hough峰值检测
1.找到包含有最大值的hough变换单元并记下它的位置
2.把第一步中找到的最大值点的邻域中的hough变换单元设为零
3.重复该步骤,直到找到需要的峰值数时为止,或者达到一个指定的阈值时为止
函数[r,c] = houghpixels(f,theta,rho,rbin,cbin)
找到影响峰值相关位置
lines = houghlines(f,theta,rho,rr,cc,fillgap,minlength)
相关位置像素合成线段
hough变换的应用
直线检测
一条直线在图像中是一系列离散点的集合,通过一个直线的离散极坐标公式,
可以表达出直线的离散点几何等式如下:X *cos(theta) + y * sin(theta) = r 其中角度theta指r与X轴之间的夹角,r为到直线几何垂直距离。如果我们能绘制每个(r, theta)值根据像素点坐标P(x, y)值的话,那么就从图像笛卡尔坐标系统转换到极坐标霍夫空间系统,这种从点到曲线的变换称为直线的霍夫变换.
close all;
f = imread(\'Fig1006.tif\');
f = edge(f, \'canny\', [0.04, 0.10], 1.5 );
[H,theta,rho] = hough(f,\'ThetaRes\',0.2);
imshow(H,[], \'XData\', theta, \'YData\', rho, \'InitialMagnification\', \'fit\');
axis on,axis normal;
xlabel(\'\theta\'),ylabel(\'\rho\');
peaks=houghpeaks(H,5);
hold on;
plot(theta(peaks(:,2)), rho(peaks(:,1)),...
\'LineStyle\', \'none\', \'marker\', \'s\', \'color\', \'w\');
lines=houghlines(f,theta,rho,peaks);
figure;imshow(f), hold on;
for k = 1:length(lines)
xy = [lines(k).point1 ; lines(k).point2];
plot(xy(:, 1),xy(:,2),\'LineWidth\', 4, \'Color\', [.8 .8 .8]);
圆检测
(x-a)2+(y-b)2=r^2;
x=a+rcos(theta),y=b+rsin(theta)
(x和y为实际的图像空间某个边缘点的坐标,a和b为其对应的参数空间的坐标)
中心点处的坐标值必定最强.
function [hough_space,hough_circle,para] = hough_circle(BW,step_r,step_angle,r_min,r_max,thresh);
% hough_space:参数空间,h(a,b,r)表示圆心在(a,b)半径为r的圆上的点数
% hough_circle:二值图像,检测到的圆
% para:检测到的圆的圆心、半径
[m,n] = size(BW);
size_r = round((r_max-r_min)/step_r)+1;
size_angle = round(2*pi/step_angle);
hough_space = zeros(m,n,size_r); %对应于参数平面,将其所有数据置为0.
[rows,cols] = find(BW);
ecount = size(rows); %非零坐标的个数
% Hough变换
% 将图像空间(x,y)对应到参数空间(a,b,r)
% a = x-r*cos(angle)
% b = y-r*sin(angle)
%hough_space(a,b,r)确立了一个三维的立体坐标系,每个坐标点存放着一个数值,此数值代表着圆心为(a,b)半径为r的圆的可信度
for i=1:ecount
for r=1:size_r %单个点在所有半径空间内检测
for k=1:size_angle
a = round(rows(i)-(r_min+(r-1)*step_r)*cos(k*step_angle));
b = round(cols(i)-(r_min+(r-1)*step_r)*sin(k*step_angle));
if(a>0&&a<=m&b>0&b<=n)
hough_space(a,b,r) = hough_space(a,b,r)+1; %让圆对应的参数平面的点的值都加1。
end
end
end
end
% 搜索超过阈值的聚集点
max_para = max(max(max(hough_space))); %返回值就是这个矩阵的最大值
index = find(hough_space>=max_para*thresh );
%一个矩阵中,想找到其中大于max_para*tresh数的位置,找到可信度较高的圆
% index 是一个一维数组每个值代表着 hough_space(a,b,r) 一维化后的位置
length = size(index); %符合阈值的个数
hough_circle = false(m,n);
%通过位置求半径和圆心.根据数据 一维化后的位置 定位三维的坐标 index=m*n*(r-1)+(a-1)*m+b
for i=1:ecount
for k=1:length
par3 = floor(index(k)/(m*n))+1; %转化为圆的半径
par2 = floor((index(k)-(par3-1)*(m*n))/m)+1;%转换为圆心的a值
par1 = index(k)-(par3-1)*(m*n)-(par2-1)*m; %转换为圆心的b值
if((rows(i)-par1)^2+(cols(i)-par2)^2<(r_min+(par3-1)*step_r)^2+5&...
(rows(i)-par1)^2+(cols(i)-par2)^2>(r_min+(par3-1)*step_r)^2-5)
hough_circle(rows(i),cols(i)) = true;
%为了判断原图中的圆边界点 以便建立 hough_circle ,判断原理是基于欧式距离,允许的误差范围是sqrt(5)。
end
end
end
% 打印结果
for k=1:length
par3 = floor(index(k)/(m*n))+1;
par2 = floor((index(k)-(par3-1)*(m*n))/m)+1;
par1 = index(k)-(par3-1)*(m*n)-(par2-1)*m;
par3 = r_min+(par3-1)*step_r;
fprintf(1,\'Center %d %d radius %d\n\',par1,par2,par3);
para(:,k) = [par1,par2,par3];
end
阈值处理
f = imread(\'Fig17.tif\');
T = 0.5 * (double(min(f(:))) + double(max(f(:))));
done = false;
while ~done
g = f >= T;
Tnext = 0.5 * (mean(f(g)) + mean(f(~g)));
done = abs(T - Tnext) < 0.5;
T = Tnext;
end
subplot(1, 2, 1), imshow(f), title(\'原图\');
subplot(1, 2, 2), imshow(g), title(\'利用迭代策略\');
表示与描述
单元数组与结构
表示区域设计到两个基本选择
用外部特征(区域的边界)表示区域
用内部特征(组成区域的像素)表示区域
函数floor(x):取最小的整数
floor(2.8)=2,floor(3.8)=3
函数ceil(x):取最大的整数
ceil(3.2)=4,ceil(5.18)=6
函数g = imfill(fI, conn, \'holes\')
将填充输入灰度图像fI 的孔洞
gB = imfill(fB, locations, conn)
在输入二值图像fB的背景像素上从参数locations指定的点开始,执行填充操作。
gI = imfill(fI, conn, \'holes\')
函数 [L,num]=bwlabel(f,conn)
bwlabel计算二值图像中所有的连通分量(区域).[L,num]=bwlabel(f,conn),其中f是输入图像,conn指定了期望的连通性(4连接或8连接,默认为8连接)。num是找到的连通分量数,L是标记矩阵,L对每个连通分量分配唯一的1到num的整数
函数find 可以和 bwlabel一起使用,返回构成某个指定对象的像素的坐标向量。
[gB, num] = bwlabel(fB)
产生了多个连续区域(即num > 1)
则使用一下语法可以获得第二个区域的坐标:
[r, c] = find(g == 2)
函数 g=bwperim(f,conn)
g=bwperim(f,conn)这个函数返回二值图像g,其中仅包含f中所有区域的周界(边界)像素。这个函数中conn指定背景的连通性:4连接(默认)或8连接。这样,为了得到4连接的区域边界,可以把conn指定为8,8连接的边界可通过将conn指定为4得到
函数 z=sortrows(S)
对数组进行排序
z = sortrows(S)
S 必须是矩阵或列向量
函数 [z, m, n] = unique(S, \'rows\')
既对数组进行排序,又去除重复行
函数 z=circshift(S, [ud lr])
z = circshift(S, [ud lr])
对数组进行向上、向下或侧移指定位置数的移位操作
ud 是 S 向上或向下移位的元素数
若S 是一幅图像,则circshift 就是对图像进行的卷动操作或平移操作。
函数 B = bwboundaries(f, conn, options)
第一版书的语法是 B = boundaries(f, conn, dir)
第二版书已改成 B = bwboundaries(f, conn, options)
conn相对于边界本身,并且值为4或8(默认),参数options的值可以为‘holes’和‘noholes’.使用holes会提取区域和孔洞的边界,也可以提取嵌套在区域内的区域边界。使用noholes只能得到区域或其子区域的边界。首先在B中列出区域,紧跟着是孔洞。
输出的B是px1的单元数组,其中,P是物体数。单元数组中每个单位都包含一个npx2的矩阵,其中的行是边界像素的行列坐标,np是相应区域的边界像素数。每个边界坐标都是以顺时针方向安排的,并且边界的最后一点与第一个点相同,这样就提供了闭合的边界。
[B,L]=bwboundaries(...)L是标记矩阵(与f的尺寸一样),使用不同的整数来标记f的每个元素(无论是区域还是孔洞)。背景像素标记为0,。区域和孔洞数由max(L(