2019-12-23 19:04:57 weixin_44244154 阅读数 30

实验内容

计算以上边界的阶数为20的形状数及其相应的近似多边形。
在这里插入图片描述

实验原理

形状数是一种基于链码的,反映边界形状的描述子。形状数定义为具有最小值的一阶差分码,其值限定了可能的不同形状数目。
对链码来说,有两种基本的链码表示方法:

在这里插入图片描述可以按照各个方向的数字来确定相应的图像边界的方向,从而构成图像,对于每相邻的两个方向之间的差则构成了一阶差分码,一阶差分码的最小值即形状数。

过程分析

首先先对图像进行二值化处理,得到只有0和1的图像矩阵,然后还需对图像进行相应的小处理,使图像只有轮廓是白色,其余背景部分均为黑色。得到图像如图所示:
在这里插入图片描述
然后对图像的每一行进行扫描,找出图像中每一行白色区域的临界端点,然后将两个端点之间的中间区域填充为白色,得到图像如下图所示:
在这里插入图片描述
接着调用bwperim函数对得到的二值图像进行轮廓提取:
在这里插入图片描述
然后对得到的轮廓图像进行重采样操作,即完整的图像轮廓分散到距离相同的点位处,采样间隔为20个像素点,得到重采样后的图像如下:
在这里插入图片描述
最后找出一个起始点进行链码搜索操作,从0方向开始搜索重采样后的图像,并将搜索到的点置0,这样可以防止搜索死循环,且做差后即可得到链码搜索后的图像。最终将各个点存入到矩阵当中并进行连线,得到的近似多边形如下图所示:
在这里插入图片描述
求得的链码为:在这里插入图片描述
对其做差即可求得一阶差分,求具有最小值的一阶差分链码即为形状数。

实验代码如下:

clear all
clc
t1=imread('9.png');
t1=im2bw(t1);%图像二值化
t=t1;
%图像边缘有白边,将其过滤掉
t(:,1)=0;
t(144:145,:)=0;
figure;
imshow(t),title('原图');
[m,n]=size(t);%获取图像大小
%%
%按每一行来进行扫描,找出图像每一行白色区域的临界端点,并将中间区域填充为白色
for i=1:m
    lie=t(i,:);
    x1=0;x2=n;
    zong=sum(lie);
    if zong~=0
        for j=1:n
            if lie(j)==1
                x1=j;
                break
            end
        end
        lie=flip(lie);
        for j=1:n
            if lie(j)==1
                x2=n-j+1;
                break
            end
        end
   
    for k=x1+1:x2-1
        t(i,k)=1;      %将中间区域填充为白色
    end
    end
end
figure;
imshow(t),title('填充区域');
t=bwperim(t,8);%对二值图像进行轮廓提取
figure;
imshow(t),title('轮廓提取');
%%
%重采样
t1=t;
t2=zeros(m,n);
for i=1:m
    for j=1:n
        if t(i,j)==1
            if round(j/20)==0
                t2(20*round(i/20),20*(round(j/20)+1))=1;
            else
                t2(20*round(i/20),20*round(j/20))=1;
            end
        end
    end
end
figure,imshow(t2),title('重取样后');
%%
qidian=[0 0];%保存起点
lianma=[];%保存链码
duandian=zeros(20,2);%保存端点
k=0;
t=t2;

%找出一个起点进行链码搜索
for i=1:m
    for j=1:n
        if t(i,j)==1
            qidian=[i j];
            qidian
            break;
        end
    end
end

x=qidian(1);
y=qidian(2)+1;

while (x~=qidian(1)||y~=qidian(2)) && k<21
k=k+1;
if k==1
    y=y-1;
end

if y+20<=n
    if t(x,y+20)==1
        lianma(k)=0;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        y=y+20;
        continue;
    end
end

if x-20>0&&y+20<=n
    if t(x-20,y+20)==1
        lianma(k)=1;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        x=x-20;
        y=y+20;
        continue;
    end
end

if x-20>0
    if t(x-20,y)==1
        lianma(k)=2;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        x=x-20;
        continue;
    end
end

if x-20>0&&y-20>0
    if t(x-20,y-20)==1
        lianma(k)=3;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        x=x-20;
        y=y-20;
        continue;
    end
end

if y-20>0
    if t(x,y-20)==1
        lianma(k)=4;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        y=y-20;
        continue;
    end
end

if y-20>0
    if t(x+20,y-20)==1
        lianma(k)=5;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        x=x+20;
        y=y-20;
        continue;
    end
end

if t(x+20,y)==1
    lianma(k)=6;
    duandian(k,1)=x;
    duandian(k,2)=y;
    t(x,y)=0;
    x=x+20;
    continue;
end

if y+20<=141
    if t(x+20,y+20)==1
        lianma(k)=7;
        duandian(k,1)=x;
        duandian(k,2)=y;
        t(x,y)=0;
        x=x+20;
        y=y+20;
        continue;
    end
end
end
lianma
xt=t2-t;
figure,imshow(xt),title('相似多边形'),hold on;
for i=1:19
    if i==19
        plot([duandian(19,2);duandian(1,2)],[duandian(19,1);duandian(1,1)]);
    else
        plot(duandian(i:i+1,2),duandian(i:i+1,1));
    end
end

2019-02-18 21:29:30 dzm123lalala 阅读数 105

形态学基本概念

基本思想:用一定形态的结构元素去度量和提取图像中的对应形状,达到分析和识别的目的。
可用于图像处理的各个方面,包括图像分割,特征抽取,边界检测等等。
对图像处理的理论和技术产生了重大影响,已经构成一种新的图像处理方法和理论,成为一个重要的研究领域。

在图像处理中的应用主要是:

  1. 对图像进行观察和处理,从而达到改善图像质量的目的
  2. 米哦啊书和定义图像的各种几何参数和特征,如面积,周长,联通度,颗粒度,骨架和方向性等。

几个概念

补集:不包含AA的所有元素组成的集合
AC={wwA} A^C=\{w|w \notin A\}
集合的差:
AB={wwA,wB}=ABC A-B=\{w|w\in A,w \notin B \}=A \cap B^C
集合的差
反射:B^={ww=b,bB}\hat{B}=\{w|w=-b,b\in B\}关于原点取对称。如果集合BB本身关于原点对称,那么B=B^B=\hat{B}
反射

平移:
(A)z={cc=a+z,aA} (A)_z=\{c|c=a+z,a \in A\}

腐蚀与膨胀

腐蚀和膨胀是形态学处理的基础,许多形态学算法都是以这两种运算为基础的。

膨胀

集合AA被集合BB膨胀,定义为:
AB={z(B^)zAΦ} A\oplus B=\{z|(\hat{B})_z \cap A \neq \Phi\}
B称为结构元素。结构元素先进行反射,之后进行z平移,之后和A进行交运算,若击中,记录下平移量z。
若B对称,则把B平移a后得到BaB_a。若BaB_a击中A,记下a点,所有满足上述条件的a点组成的集合称为A对B的膨胀。
DB(A)=AB={aBaA} D_B(A)= A\oplus B=\{a|B_a\uparrow A\}

二值图像膨胀运算过程

如果用d4\frac{d}{4}大小的结构元素取膨胀d大小的结构元素,会得到边缘加厚d8\frac{d}{8}的结果。

在这里插入图片描述

膨胀最简单的应用是 将裂缝桥接起来
膨胀最简单的应用之二是填充目标中的空洞。

腐蚀

使用集合B对集合A进行腐蚀,定义为:
AB={z(B)zA} A\circleddash B=\{z|(B)_z \subseteq A\}
把结构元素B平移a后得到BaB_a,若BaB_a包含于X,则记下这个a点,所有满足上述条件的a点组成的集合称作X被B腐蚀的结果。
EB(A)=AB={aBaA} E_B(A)=A\circleddash B=\{a|B_a \subset A\}
腐蚀的结果
在这里插入图片描述
形态学腐蚀选择目标

膨胀和腐蚀的性质

  • 膨胀和腐蚀运算的对偶性
    (XB)C=XCB^(XB)C=XCB^ (X\circleddash B)^C=X^C \oplus \hat{B} \quad \quad (X\oplus B)^C=X^C \circleddash \hat{B}
    X对B的腐蚀运算的补集等于X的补集对B的反射的膨胀运算;
    X对B的反射运算的补集等于X的补集对B的腐蚀的膨胀运算。
    河岸的补集为河面,对河岸的腐蚀等价于对河面进行膨胀。

  • 膨胀运算具有互换性,腐蚀运算不具有互换性。
    (XB)A=(XA)B (X\oplus B)\oplus A=(X\oplus A)\oplus B
    (XB)A(XA)B (X\circleddash B)\circleddash A \neq (X\circleddash A)\circleddash B

  • 腐蚀和膨胀具有组合性。
    在这里插入图片描述

开运算与闭运算

膨胀和腐蚀运算,对目标的后处理有着非常好的作用,缺点是,改变了原目标物的大小。
为了解决这一问题,考虑到腐蚀与膨胀时一对对偶运算,将膨胀和腐蚀运算同时进行,便构成了开运算和闭运算。

开运算

使用结构元素B对集合A进行开操作,定义为:
AB=(AB)B A \circ B=(A\circleddash B)\oplus B
开运算

  • 消除细小对象
  • 在细小粘连处分离对象
  • 在不改变形状的前提下,平滑对象的边缘。

3×33\times 35×55\times 5的矩形结构元素分别进行开运算:
开运算结果
去除了细小孔洞,平滑了边缘。
如果B是非对称的,进行开运算时要用B的对称集BB^\vee膨胀,否则,进行开运算时结果会和原来比发生平移,当结构元素为非对称时,腐蚀的结果会发生平移,然后再进行膨胀时,会向另外一侧平移。
在这里插入图片描述

闭运算

使用结构元素B对集合A进行闭操作,定义为:
在这里插入图片描述
闭运算作用:

  • 填充对象内细小空洞
  • 链接接近的对象
  • 再不明显改变面积的前提下,平滑对象的边缘
    在这里插入图片描述

在这里插入图片描述

开运算和闭运算的性质

开运算和闭运算也是对偶运算
X开运算的补集等于X补集的闭运算,或者X闭运算的补集等于X补集的开运算。
如何理解:两个小岛之间有小桥,岛和桥看作是处理对象X,则X的补集为大海。对岛桥进行开处理等于对大海进行闭处理
在这里插入图片描述
开闭·运算的一些性质
开操作一般是使得对象的轮廓变得平滑,断开狭窄的间断和消除细小的突出物。
闭操作同样是使得轮廓更为光滑,通常是消除狭窄的尖端和长细的鸿沟,消除小的空洞,填补轮廓线中的断裂。

二值数学形态学基本算法

形态滤波

用不同的方向结构元素提取方向向量
在这里插入图片描述

在这里插入图片描述

图像的边缘提取

图像的边缘线或者棱线时图像中信息量最为丰富的区域。提取边界或者边缘也是图像分割的重要组成部分。

先腐蚀图像,然后用原图像减去腐蚀后的图像,相减即得到边缘。
提取物体的轮廓边缘的形态学变换为:
Y=X(XB) Y=X-(X\circleddash B)

在这里插入图片描述

区域填充

区域时边界所包围的部分,边界是区域的轮廓线,区域和边界可以互求。
填充过程实际上就是从边界上某一点p开始做以下迭代运算,用结构元素对其进行膨胀,求补和求交集的过程。
Xk=(Xk1B)Ac X_k=(X_{k-1} \oplus B)\cap A^c
B是结构元素,X0X_0是边界种子点,A是边界图像。
在进行形态学填充之前必须了解一点:当我们的边界是4连通边界时,我们使用的结构元素为8连通;当我们的连通边界为8连通时,我们需要用4连通的结构元素。

具体为什么可以这样做,拿那个结构元素在边缘上试一下就知道了。

击中击不中变换

在这里插入图片描述

2019-07-18 14:25:35 YueYingGuang 阅读数 3307

MATLAB图像处理(一)——计算机图形学之图像形状识别

由于遇到了很多次这个课题,这次做完之后结合手上的资料总结一下。

基本步骤:

1、读取彩色图像转化为二值图像;

2、确定图像中的形状边界;

3、确定所需形状的目标;

本文主要通过识别圆形目标来进行说明,原图如下所示,本例需要识别出下图中的圆形物体:
在这里插入图片描述

1、读取彩色图像转化为二值图像

针对图像中可能有不同形状的目标物体,为了进行目标筛选,可以先通过形状判断,过滤掉我们不需要的物体,极大地提高图像识别的效率。

1) 读取彩色图像

% 1、读取图像并转化为二值图像
RGB = imread('ImageSeg.png');
figure;imshow(RGB);title('原图像');

2)将彩色图像转化为二值图像

% 转化为灰度图像
I = rgb2gray(RGB);
% 设置阈值
threshold = graythresh(I);
% 转化为二值图像
bw = im2bw(I,threshold);

注意:如果使用阈值公式进行转化,转化出的效果如果不符合预期的话需要手动调整阈值,上面代码的效果如下:
在这里插入图片描述
所以我们根据图像像素的特性人为调整阈值。

bw = im2bw(I,0.69);

在这里插入图片描述
调整后的二值图像如上图所示,可以看到物体形状非常清晰,但是明显看到背景有许多噪点,所以在这里为了去除这些噪点我们进行了人工去噪,去噪的代码如下,即简单的领域判断。

% 通过领域判断手动去噪
[m,n] = size(bw);
for i = 2:m-1
   for j = 2:n-1
       %同上下元素判断       
       if(bw(i,j)~=bw(i+1,j) && bw(i,j)~=bw(i-1,j))
           bw(i,j) = 1;
       %同左右元素判断
       elseif(bw(i,j)~=bw(i,j+1) && bw(i,j)~=bw(i,j-1))
           bw(i,j) = 1;
       %同斜边元素判断
       elseif(bw(i,j)~=bw(i+1,j+1) && bw(i,j)~=bw(i-1,j-1))
           bw(i,j) = 1;
       %同斜边元素判断
       elseif(bw(i,j)~=bw(i-1,j+1) && bw(i,j)~=bw(i+1,j-1))
           bw(i,j) = 1;
       end
   end
end

去噪之后的二值图像为:
在这里插入图片描述
然后对以上图像进行取反,以备下面使用。

for i = 1:m
    for j = 1:n
        bw(i,j) = ~bw(i,j);
    end
end

结果为
在这里插入图片描述

2、确定图像中的形状边界

首先去除小目标,由于本例图像中不存在小目标,所以可省略该步骤,其次进行孔洞填充并进行白色描边,最后通过bwboundaries函数确定图像边界。

% 去除小目标,因为本图没有小目标,所以可以不需要本条语句
bw = bwareaopen(bw,30);
% 图形学结构元素构建,圆形
se = strel('disk',8);
% 关操作
bw = imclose(bw,se);
% 填充孔洞
bw = imfill(bw,'holes');
% 二值化图像显示
figure(1);imshow(bw);title('二值图像');
[B,L] = bwboundaries(bw,'noholes');
figure(2);imshow(label2rgb(L,@jet,[.5 .5 .5]));
hold on;
for k = 1:length(B)
boundary = B{k};
% 显示白色边界
plot(boundary(:,2),boundary(:,1),'w','LineWidth',2)
end

在这里插入图片描述

3、确定所需形状的目标

确定圆形目标,求取图形周长,圆心,面积,人为设置阈值进行过滤,在这里我设置阈值为0.85,即形状比对大于这个阈值的就是我们所需要的目标物体。

hold on;
% 确定圆形目标
stats = regionprops(L,'Area','Centroid');
% 设置求面积
threshold = 0.85;
for k = 1:length(B)
    boundary = B{k};
    delta_sq = diff(boundary).^2;
    % 求周长     
    perimeter = sum(sqrt(sum(delta_sq,2)));
    % 求面积     
    area = stats(k).Area;
    metric = 4*pi*area/perimeter^2;
    metric_string = sprintf('%2.2f',metric);
    % 根据阈值匹配
    if metric > threshold  
       centroid = stats(k).Centroid;
       plot(centroid(1),centroid(2),'ko');
       text(centroid(1)-2,centroid(2)-2, '这是圆形','Color',...
        'k','FontSize',14,'FontWeight','bold');
    end
       text(boundary(1,2)-10,boundary(1,1)-12, metric_string,'Color',...
        'k','FontSize',14,'FontWeight','bold');
end
title('图像形状识别')

最后识别的效果图为:
在这里插入图片描述
源代码及所使用的文件链接:https://download.csdn.net/download/yueyingguang/11381702

2019-06-08 09:20:06 lin1094201572 阅读数 76

《图像处理》复习内容

1、图像及类型

数字图像处理:指通过计算机对图像去除噪声,增强,变换,复原,分割,特征提取,识别等 运算与处理。

图像类型:1.可见图像(视觉可见),2.物理图像(反应物理),3.数学图像(函数图像)

2、数字图像概念

图像是其所表示物理信息的直接描述和概括,数字图像则是用数学方法描述图像,图像为不同空间坐标上的光亮度集合。

数字图像的类型:1.矢量图(几何形状)2.位图(二值图像(0黑,1白),灰度图像(255级灰度值),索引图像(映射对应有一颜色矩阵),RGB彩色图像(3维矩阵MxNx3))

3、数字图像获取办法

1.图像传感器

2.数字化扫描

3.光电转换设备

3.合成图像

4、数字图像矩阵表示

数字图像在计算机中通常已二维矩阵表示和存储。每一格对应指定像素点存储图像在该点的灰度值。灰度值由顺序扫描采样获取,并量化得到。

图像的像素的多少决定矩阵的大小。

5、图像的采样和量化

1.采样:将图像在空间(x,y)上离散化称为采样

先沿垂直再沿水平方向顺序线性扫描等间距采样。

2.量化:将采样后的图像离散为像素

线性量化为等间距划分灰度区间量化

非线性量化将灰度级范围分为不等间距量化

6、灰度直方图

直方图:基于图像灰度值和像素统计分布的形象表示,概括地表示了一幅图像的灰度级信息。

直方图的作用:1)数字化参数 2)选择边界阀值 3)计算综合光密度

7、傅里叶变换

前提满足迪利克雷条件:1有限个间断点 2.有限个极值点 3.绝对可积

一维连续傅里叶变换
F(u)=+f(x)ej2πuxdx F(u) = \int_{- \infty}^{+\infty}f(x)e^{-j 2 \pi u x}dx
傅里叶逆变换
f(x)=+F(u)ej2πuxdu f(x) = \int_{-\infty}^{+\infty}F(u)e^{j2\pi ux}du

二维连续傅里叶变换
F(u)=++f(x)ej2π(ux+uy)dx F(u) = \int_{- \infty}^{+\infty}\int_{- \infty}^{+\infty}f(x)e^{-j 2 \pi (ux+uy)}dx
逆变换
f(x)=++F(u)ej2π(ux+uy)du f(x) = \int_{- \infty}^{+\infty}\int_{- \infty}^{+\infty}F(u)e^{-j 2 \pi (ux+uy)}du
离散傅里叶变换

一维正变换
F(u)=x=0N1f(x)ej2πuxN F(u)=\sum_{x=0}^{N-1}f(x)e^{-j\frac{2\pi ux}{N}}
一维逆变换
f(x)=1Nu=0N1F(u)ej2πuxN f(x)=\frac{1}{N}\sum_{u=0}^{N-1}F(u)e^{-j\frac{2\pi ux}{N}}

二维离散傅里叶(DFT)变换的性质

1.线性特性 2.比例特性 3.平移性质 4.可分离性 5.周期性 6.共轭对称性 7.旋转不变性 8.微分性 9平均值性质 10.卷积定理 11.相关定理 12.帕沙瓦(Parseval)定理(能量不变)

二维正变换
F(u,v)=x=0M1y=1N1f(x,y)ej2π(uxM+vyN) F(u,v)=\sum_{x=0}^{M-1}\sum_{y=1}^{N-1}f(x,y)e^{-j2\pi(\frac{ux}{M}+\frac{vy}{N})}
二维逆变换
f(x,y)=1MNu=0M1v=1N1F(u,v)ej2π(uxM+vyN) f(x,y)=\frac{1}{MN}\sum_{u=0}^{M-1}\sum_{v=1}^{N-1}F(u,v)e^{-j2\pi(\frac{ux}{M}+\frac{vy}{N})}

8、离散余弦变换

DFT(离散傅里叶变换)是频谱分析的有力工具,但DFT是基于复数域的运算,因而给实数运算带来不变。

故而存在再实数域的运算DCT(离散余弦变换).

DCT变换具有正交变换的性质

在这里插入图片描述
在这里插入图片描述

9、图像噪声

噪声的来源:1)图像获取过程中 2)图像信号传输过程中

噪声的分类:1)外部噪声 2)内部噪声

噪声的特点:1)随机性 2)叠加性

噪声对图像的影响:

10、图像增强处理

分类:可分为基于空间域和基于频率域的两大类增强方法。

1)空域增强

1.1.灰度变换

1.1.1直接灰度变换

1.1.2直方图灰度变换

1.1.3图像代数运算

1.2.空域滤波

1.2.1平滑滤波

方法:1)邻域平均法 2)中值滤波

1.2.2锐化滤波

方法:1)梯度法 2)拉普拉斯算子法3)定向滤波

2)频域增强

2.1 低频滤波

2.2 高通滤波

2.3 带通滤波

2.4 带阻滤波

11、直方图的图像增强

基于直方图的图像增强是以概率统计理论为基础的,将图像的明暗情况和对比度等特征信息都可以通过直方图反映处理啊

原理:

通过变换函数来控制图像灰度级的概率密度,从而改善图像的灰度分布情况。

1.首先对原始图像进行直方图均衡化处理

2.依据原始图像均衡化后的图像的灰度值得到目标图像的灰度级z

12、空域滤波

对图像的空间纹理信息的增强。

分为平滑和瑞华两类空域滤波方法。

平滑滤波:消除想中的随机燥音,起到图像平滑的作用

线性平滑方法:1)领域平均法 2)加权平均法 3)高斯滤波

非线性平滑滤波方法:1)中值滤波 2)最大值滤波 3)最小值滤波

锐化滤波:处理图像的边缘纹理信息

方法:1)梯度法 2)拉普拉斯算子 3)定向滤波

13、低通滤波

对图像的低频信息的增强

1559740626496

14、高通滤波

对图像的高频信息的增强。

1559740659112

15、全彩色图像处理

分为合成处理法和直接处理法

合成处理法:将RGB图像分解为RGB三个波段的图像分量,分别对三个分量处理,处理后合成为彩色图像。

直接处理法:将每个彩色像素用三维分量表示直接处理。

16、无约束复原技术

无约束复原法:在求解的过程中不受其他条件的约束

最小二乘是一种常用的无约束的图像恢复法。

17、逆滤波器

预测或知道怎么产生的噪声之后,利用产生噪声的方法反向计算,试图得到其原来的真实声音。

18、几何畸变校正

以一幅图像为基准,然后去校验另一幅图像的几何形状。

1.图像空间坐标的变换 2.确定校正空念各像素点的取值。

19、盲目图像复原

指在没有图像退化先验知识,对退化系统了解不足的条件下

通过观察退化图像的多个图像并以某种方式抽除退化信息,进行图像复原的方法。

1)直接测量法 2)间接估计法

20、图像编码的基本原理

按照一定的格式存储图像数据的过程,而编码技术则是研究如何满足图像保真条件下,压缩原始图像的编码方法。

21、图像统计编码

统计编码建立在统计特征基础上的数据压缩方法

原理: 找到去除相关性和改变概率分布不均的方法,从而找到信源数据的统计编码方法。

方法:1)变长最佳编码 2)霍夫曼编码 3)行程长度编码 4)香农凡诺编码 5)算术编码

22、预测编码

以某一模型,对新样本进行预测,然后将样本的实际值与预测值相减到一个误差值,对误差值进行编码。

几种编码方式:1)线性脉冲编码 2)非线性预测

23、图像分割的基本概念

目的:将图像划分为若干有意义或有一定目的的子区域

原理:根据图像组成结构和应用需求将图像划分为若干个互不相交的区域,这些区域是某种意义下具有共同属性的像素的联通集合。

方法:基于 阀值,区域,边缘的分割

24、阀值分割

特点:1)实现简单 2)计算量小 3)性能稳定

25、区域分割

两种方法:1)区域生长法(合并周围像素) 2)区域分裂与合并(逐渐分裂与合并)

26、边缘检测

检测灰度级或者一幅图像中结构具有突变的地方。

边缘的描述:1)边缘法线方向 2)边缘方向 3)边缘强度

边缘点:1)空间曲面上的不连续点 2)物体与背景的分界线 3)不同材料组成的边缘线 4)阴影引起的边缘

27、几何特征

几何特征指:图像中物理的位置,方向,周长,面积和距离等方面的特征。

面积算法:1)像素计算法 2)边界行程码计算法 3)边界坐标计算法。

28、颜色特征

定义:是一种全局特征,描述了图像内区域所对应的景物的表面性质。

特点:优:不受图像旋转和平移变换影响,基于归一化的直方图还可不受图像尺度变换的影响。缺:没有表达出颜色分布的信息。

常用特征提取与匹配方法:1)颜色直方图,2)颜色集 3)颜色矩 4)颜色聚合向量 5)颜色相关图

29、纹理特征

定义:纹理由许多互相接近的互相交织的元素构成,具有周期性。纹理在一定程度上反应了一个区域中像素灰度级的空间分布属性。**

分类:1)人工纹理(由某种符号有序排列组成) 2)自然纹理(排列的自然现象)

对纹理的认识:1)凭直观印象 2)凭图像本身结构

30、骨架的概念

骨架主要针对二值图而言。从某种意义上,所谓估计,可以理解为图像的中轴。

2016-01-04 14:52:41 lx407655880 阅读数 140




1.通过坐标变换矩阵 去改变图像的形状大小位置等 (9位 float)




    A  B C

    D E F

    G H I                          --> AE控制缩放,CF控制平移, BD控制错切




2.  android API操作


matrix.setRote(); -- 旋转

matrix.setTranslate() -- 平移

matrix.setScale() -- 缩放

matrix.setSkew() -- 错切

post -- 矩阵组合



3.     通过画笔风格实现不同图形特效   -Xfermode

PorterDuff.Mode为枚举类,一共有16个枚举值:

1.PorterDuff.Mode.CLEAR  

  所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC

   显示上层绘制图片
3.PorterDuff.Mode.DST

  显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER

  正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER

  上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN

   取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN

  取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT

 取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT

 取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP

 取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP

 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR

  异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN

  取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN

  取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY

  取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN

  取两图层全部区域,交集部分变为透明色





事例 做一个四周有圆角的图形:

public class RoundRectXfermodeView extends View {


    private Bitmap mBitmap;
    private Bitmap mOut;
    private Paint mPaint;


    public RoundRectXfermodeView(Context context) {
        super(context);
        initView();
    }


    public RoundRectXfermodeView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }


    public RoundRectXfermodeView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }


    private void initView() {
        setLayerType(LAYER_TYPE_SOFTWARE, null);    //    要禁用 硬件加速 
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1);
        mOut = Bitmap.createBitmap(mBitmap.getWidth(),
                mBitmap.getHeight(),
                Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mOut);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        // Dst  遮罩层
        canvas.drawRoundRect(0, 0, mBitmap.getWidth(), mBitmap.getHeight(),
                50, 50, mPaint);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));  // 设置画笔的 xfermode属性为  src_in
        // Src
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        mPaint.setXfermode(null);
    }


    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mOut, 0, 0, null);
    }
}






4.   画笔风格-  shader  着色器/渲染器  

      图像渐变:   BitmapShader


public   BitmapShader(Bitmap bitmap,Shader.TileMode tileX,Shader.TileMode tileY)

调用这个方法来产生一个画有一个位图的渲染器(Shader)。

bitmap   在渲染器内使用的位图

tileX      The tiling mode for x to draw the bitmap in.   在位图上X方向渲染器平铺模式

tileY     The tiling mode for y to draw the bitmap in.    在位图上Y方向渲染器平铺模式

TileMode:

CLAMP  :如果渲染器超出原始边界范围,会复制范围内边缘染色。

REPEAT :横向和纵向的重复渲染器图片,平铺。

MIRROR :横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺。


示例:


package com.tony.shader;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.util.AttributeSet;
import android.view.View;


public class BitmapShaderView extends View {


private BitmapShader bitmapShader = null;
private Bitmap bitmap = null;
private Paint paint = null;
private ShapeDrawable shapeDrawable = null;
private int BitmapWidth = 0;
private int BitmapHeight = 0;


public BitmapShaderView(Context context) {
super(context);


// 得到图像
bitmap = ((BitmapDrawable) getResources().getDrawable(R.drawable.cat))
.getBitmap();
BitmapWidth = bitmap.getWidth();
BitmapHeight = bitmap.getHeight();
// 构造渲染器BitmapShader
bitmapShader = new BitmapShader(bitmap, Shader.TileMode.MIRROR,Shader.TileMode.REPEAT);
}

public BitmapShaderView(Context context,AttributeSet set) {
super(context, set);
}


@Override
protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
super.onDraw(canvas);
//将图片裁剪为椭圆形    
        //构建ShapeDrawable对象并定义形状为椭圆    
        shapeDrawable = new ShapeDrawable(new OvalShape());  
        //得到画笔并设置渲染器  
        shapeDrawable.getPaint().setShader(bitmapShader);  
        //设置显示区域  
        shapeDrawable.setBounds(20, 20,BitmapWidth-140,BitmapHeight);  
        //绘制shapeDrawable  
        shapeDrawable.draw(canvas);  
}


}






5. 像素块   drawBitmapMesh


public class MeshView extends View {


    private int WIDTH = 200;
    private int HEIGHT = 200;
    private int COUNT = (WIDTH + 1) * (HEIGHT + 1);
    private float[] verts = new float[COUNT * 2];
    private float[] orig = new float[COUNT * 2];
    private Bitmap mBitmap;
    private float K = 1;


    public MeshView(Context context) {
        super(context);
        initView();
    }


    public MeshView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }


    public MeshView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }


    private void initView() {
        int index = 0;
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test);
        float bmWidth = mBitmap.getWidth();
        float bmHeight = mBitmap.getHeight();


        for (int i = 0; i < HEIGHT + 1; i++) {
            float fy = bmHeight * i / HEIGHT;
            for (int j = 0; j < WIDTH + 1; j++) {
                float fx = bmWidth * j / WIDTH;
                orig[index * 2 + 0] = verts[index * 2 + 0] = fx;
                orig[index * 2 + 1] = verts[index * 2 + 1] = fy + 200;
                index += 1;
            }
        }
    }


    @Override
    protected void onDraw(Canvas canvas) {
        for (int i = 0; i < HEIGHT + 1; i++) {
            for (int j = 0; j < WIDTH + 1; j++) {
                verts[(i * (WIDTH + 1) + j) * 2 + 0] += 0;
                float offsetY = (float) Math.sin((float) j / WIDTH * 2 * Math.PI + K * 2 * Math.PI);
                verts[(i * (WIDTH + 1) + j) * 2 + 1] =
                        orig[(i * (WIDTH + 1) + j) * 2 + 1] + offsetY * 50;
            }
        }
        K += 0.1F;
        canvas.drawBitmapMesh(mBitmap, WIDTH, HEIGHT,
                verts, 0, null, 0, null);
        invalidate();
    }
}


   



      




没有更多推荐了,返回首页