2019-01-21 18:47:12 sjhfkhsf 阅读数 105
  • 宏定义与预处理函数函数库-C语言专题第6部分

    本课程综合讲解了C语言的预处理和宏定义,详细讲述了宏定义的细节规则和头文件包含等常用预处理;然后讲述了函数的使用、函数库的使用,静态链接库和动态链接库等的制作和使用。本章的目标是提升大家对函数及函数库的认知,提升在实战中使用函数库解决问题的能力。

    8061 人正在学习 去看看 朱有鹏
               

       先看下面程序:

clearclccd('C:\Documents and Settings\Administrator\桌面');I = imread('pig.jpg');B = I(:, :, 3);a = 200b = 220c = B(100, 100)d1 = abs(a - c)d2 = abs(c - b)


      结果为:


a =

   200


b =

   220


c =

  208


d1 =

    0


d2 =

    0

 

       为什么d1, d2都为0呢? 因为c是uint8类型的,所以一定要注意这一点,在matlab中用whos命令查阅一下c, 便有:

  Name      Size            Bytes  Class    Attributes

  c         1x1                 1  uint8       

 

        所以,上面的程序应该改为:

clearclccd('C:\Documents and Settings\Administrator\桌面');I = imread('pig.jpg');B = I(:, :, 3);a = 200b = 220c = B(100, 100)d1 = abs(a - double(c))d2 = abs(double(c) - b)


     结果为:

a =

   200


b =

   220


c =

  208


d1 =

     8


d2 =

    12

 

           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

2019-04-10 15:17:47 Dujing2019 阅读数 720
  • 宏定义与预处理函数函数库-C语言专题第6部分

    本课程综合讲解了C语言的预处理和宏定义,详细讲述了宏定义的细节规则和头文件包含等常用预处理;然后讲述了函数的使用、函数库的使用,静态链接库和动态链接库等的制作和使用。本章的目标是提升大家对函数及函数库的认知,提升在实战中使用函数库解决问题的能力。

    8061 人正在学习 去看看 朱有鹏

数字图像处理—频域处理

(一)二维离散傅里叶变换

基本定义:

  1. 二维离散傅里叶变换:(Two-Dimensional Discrete Fourier Transform)是一种数字变换方法,一般应用于将图像从空间域转至频域,在图像增强、图像去噪、图像边缘检测、图像特征提取、图像压缩等等应用中都起着极其重要的作用。
  2. 频谱:对一个时域信号进行傅里叶变换,就可以得到的信号的频谱,信号的频谱由两部分构成:幅度谱相位谱,相位谱描述各个分量的相位随角频率的变化。幅度谱描述各个分量的幅度随着频率的变化。
  3. 功率谱:为信号频谱的平方。可观察图像的能量分布,如果频谱图中暗的点数更多,那么实际图像是比较柔和的(因为各点与邻域差异都不大,梯度相对较小),反之,如果频谱图中亮的点数多,那么实际图像一定是尖锐的,边界分明且边界两边像素差异较大的。
  4. 相位:表示相对于原始波形,这个波形的偏移量(左或右)。
  5. 频域:频域就是频率域,平常我们用的是时域,是和时间有关的,这里只和频率有关,是时间域的倒数。时域中,X轴是时间,频域中是频率。频域分析就是分析它的频率特性。

进一步直观的理解这几个定义,编写代码如下:

h = imread('D:\数字图像处理\第三章学习\cat2.jpg');
f = im2double(rgb2gray(h));    %把图像变为灰度图像
F = fft2(f);                   %对图像进行傅里叶变换
FF = fftshift(F);              %对图像频谱进行移动,使0频率点在中心
s=log(abs(FF));                %获得傅里叶变换的幅度谱
p=log(angle(FF)*180/pi);       %获得傅里叶变换的相位谱
figure;
subplot(1, 3, 1), imshow(h), title('原图像');
subplot(1, 3, 2), imshow(s), title('图像的傅里叶变换幅度谱');
subplot(1, 3, 3), imshow(p), title('图像的傅里叶变换相位谱');

代码运行效果如下:

傅立叶频谱图上我们看到的明暗不一的亮点,实际是图像上某一点与邻域点差异的强弱,即梯度的大小,也即该点的频率的大小,图像中的低频部分(能量大,呈现白色)指低梯度的点,高频部分(能量小,呈现黑灰色)反之。

理论推导:

令f(x,y)代表一幅大小为 MxN的 数字图像,其中x=0,1,2,…,M-1, y=0,1,2,…,N-1, 由 F(u,v)表 示 的f(x,y)的二维离散傅立变换(DFT)可以由下式给出:
在这里插入图片描述
其中u=0,1,2,…,M-1,v=0,1,2,…,N-1。我们可以借助决定频率的变量 u、v(x和 y求和) 将指数形式展开为正弦和余弦的形式。频域系统是以 u,v(频率)为变量来表示 F(u, v)的坐标系。 离散傅立叶反变换(IDFT)的形式为:
在这里插入图片描述
其中x=0,1,2,…,M-1,y=0,1,2,…,N-1。。因此,给定 F(u, v), 我们可以借助 IDFT(傅立叶反变换)来得到f(x,y)。

注意:由于 MATLAB中的 数组索引以1 开头,而不是以0 开头,MATLAB中的F(1,1)和f(1,1)对应数学公式中正变换和反变换的F(0,0)和f(0,0)。 一般而言,F(i,j)= F(i-1,j-1),且f(i,j)= f(i-1,j-1) i=1 2,…,M且j=1,2,…,N。

傅立叶谱可以定义如下:
在这里插入图片描述
变换的相角定义如下:
在这里插入图片描述
这两个函数可在极坐标形式下用于表示复函数F(u,v):
在这里插入图片描述
功率谱可以定义为幅度的平方:
在这里插入图片描述
如果f(x,y)是实函数,它的傅立叶变换就是关于原点共轭对称的:
在这里插入图片描述
这意味着傅立叶谱也是关于原点对称的:
在这里插入图片描述
可以将它直接代入到公式 F(u,v)中:

F(u,v)= F(u+k1,M,v)=F(u,v+k2k_2N)= F(u+k1Mk_1M,v+k2Nk_2N)

其中,k1k_1k2k_2是整数。DFT 在u, v 方向上是无穷周期的,周期由 M和N决定。周期性也是 DFT 逆变换的重要特性:

f(x,y)=f(x+k1Mk_1M,y)=f(x,y+k2Mk_2M)=f(x+k1Mk_1M,y+k2Nk_2N)

也就是说,通过傅立叶反变换得到的图像也是无穷周期的。并且,在计算离散傅立叶变换时只计算它的一个周期,即仅处理尺寸为MXN的数组。

(二)在 MATLAB 中计算及观察二维 DFT

在实践中,DFT 及其反变换可以用快速傅立叶变换(FFT)算法实现。一幅图像数组 f 的 FFT 可以在 MATLAB中用函数 fft2 得到,语法如下:

F = fft2(f)

代码编写:

f = imread('D:\数字图像处理\第三章学习\light.png');
F = fft2(f);
subplot(1, 2, 1), imshow(f), title('原图像');
subplot(1, 2, 2), imshow(uint8(real(F))), title('图像数组f的FFT');

代码运行状态如下:

这个函数返回的傅立叶变换,大小仍为 MxN,目前是看不出来什么。

继续操作,使用傅立叶变换滤波时,需要对输入数据进行 0 填充。在这种情况下,语法变为:

F = fft2 (f,P,Q)             %快速傅里叶变换

代码编写如下:

f = imread('D:\数字图像处理\第三章学习\light.png');
F = fft2(f,200,300);
subplot(1, 2, 1), imshow(f), title('原图像');
subplot(1, 2, 2), imshow(uint8(real(F))), title('图像数组f的FFT');       %real获得F的傅里叶变换的实部:

代码运行状态如下:

fft2 对输入图像填充所需数目的 0, 结果大小变为 200x300。

傅立叶谱可以通过使用函数 abs 函数获得:

S = abs(F)

代码编写:

g = imread('D:\数字图像处理\第三章学习\light.png');
f = rgb2gray(g);    %把图像变为灰度图像
F = fft2(f);
S = abs(F);
subplot(1, 2, 1), imshow(g), title('原图像');
subplot(1, 2, 2), imshow(S,[]), title('傅里叶谱');

代码运行状态如下:

图中 4个角上的亮点是周期特性的结果。可以使用函数 fftshift 将变换的原点移动到频域矩形的中心,语法为:

Fc = fftshift(F)      

代码编写:

g = imread('D:\数字图像处理\第三章学习\light.png');
f = rgb2gray(g);    %把图像变为灰度图像
F = fft2(f);
Fc = fftshift(F);      %将变换的原点移动到频域矩形的中心
subplot(1, 2, 1), imshow(g), title('原图像');
subplot(1, 2, 2), imshow(abs(Fc),[ ]), title('fftshift居中变换');

代码运行状态如下:

居中后的结果是很明显的。该谱值的范围很大(0 到420 495),与用 8 位显示相比,中心处的亮度值占支配地位。可通过 log 变换处理这个难点。

代码编写如下:

g = imread('D:\数字图像处理\第三章学习\light.png');
f = rgb2gray(g);    %把图像变为灰度图像
F = fft2(f);
Fc = fftshift(F);         %将变换的原点移动到频域矩形的中心
S2 = log(1+ abs(Fc));      % 对数变换,增强显示视觉效果
subplot(1, 2, 1), imshow(g), title('原图像');
subplot(1, 2, 2), imshow(S2,[ ]), title('log变换处理增强细节');

代码运行状态如下:

可见细节的增加是很明显的。反居中变换函数 ifftshift 的语法形式是:

F = ifftshift(Fc)

代码编写:

g = imread('D:\数字图像处理\第三章学习\light.png');
f = rgb2gray(g);    %把图像变为灰度图像
F1 = fft2(f);
Fc = fftshift(F1);
F = ifftshift(Fc)
subplot(1, 2, 1), imshow(g), title('原图像');
subplot(1, 2, 2), imshow(uint8(real(F))), title('ifftshift反居中变换');

代码运行状态如下:

这个函数也可以用来将初始点在矩形中点的函数变换为中心点在矩形左上角的函数。

(三)频域滤波

3.1基础知识

空(间)域和频(率)域的线性滤波的基础都是卷积定理,可以被写作:
在这里插入图片描述
逆变换为:
在这里插入图片描述
在这里,符号"星号"表示两个函数的卷积,双箭头两边的表达式组成傅立叶变换对。例如, 第一个表达式表明两个空间函数(表达式左侧的项)的卷积可以通过计算两个傅立叶变换函数(表达式的右侧)的乘积的反变换得到。相反,两个空间函数的卷积的正傅立叶变换给出了两个函数傅立叶变换的乘积。

当工作在离散量时,我们知道F和H是周期性的,这意味着在离散频域执行卷积也是周期性的。由于这个原因,用DFT 执行的卷积叫做循环卷积。保证空间和循环卷积给出相同结果的唯一方法是使用适当的 0 填充。

执行未填充的滤波效果,代码编写:

function H = lpfilter(type, M, N, D0, n)
[U, V] = dftuv(M, N);
D = sqrt(U.^2 + V.^2);
switch type
case 'ideal'
   H = double(D <= D0);
case 'btw'
   if nargin == 4
      n = 1; 
   end
   H = 1./(1 + (D./D0).^(2*n));
case 'gaussian'
   H = exp(-(D.^2)./(2*(D0^2)));
otherwise
   error('Unknown filter type.')
end
           
h = imread('D:\数字图像处理\第三章学习\cat2.jpg');
f = im2double(rgb2gray(h));        %把图像变为灰度图像
[M,N]=size(f);
F = fft2(f);                      %计算傅里叶变换
sig=10;                           %指定高斯低通滤波器的标准偏差
H=lpfilter('gaussian',M,N,sig);   %高斯低通滤波器生成
G=H.*F;                           %将变换乘以滤波函数
g=real(ifft2(G));                 %获得G的傅里叶逆变换实部
figure;
subplot(1, 2, 1), imshow(h), title('原图像');
subplot(1, 2, 2), imshow(g), title('未填充的滤波效果');

代码运行效果如下:

正像我们预计的那样,图像变模糊了,但是注意垂直的边缘没有模糊。

执行已填充的滤波效果,代码编写:

function PQ = paddedsize(AB, CD, PARAM)
if nargin == 1
    PQ = 2*AB;
elseif nargin == 2 && -ischar(CD)
    PQ = AB + CD - 1;
    PQ = 2 * ceil(PQ / 2);
elseif nargin == 2
    m = max(AB);
    P = 2^nextpow2(2*m);
    PQ = [P, P];
elseif (nargin == 3) && strcmp(PARAM, 'pwr2')
    m = max([AB CD]);
    P = 2^nextpow2(2*m);
    PQ = [P, P];
else
    error('Wrong number of inputs.')
end  
h = imread('D:\数字图像处理\第三章学习\cat2.jpg');
f = im2double(rgb2gray(h));         %把图像变为灰度图像
PQ = paddedsize(size(f));           %用函数 paddedsize 获得填充参数
Fp = fft2(f,PQ(1),PQ(2));           %得到有填充的傅立叶变换
Hp = lpfilter('gaussian', PQ(1), PQ(2), 2*sig);     %现在滤波器的大小是没有进行填充时的两倍。 
Gp=Hp.*Fp;                          %用滤波器乘以FFT 变换
gp=ifft2(Gp);                       %获得 Gp 的逆 FFT 变换
gpc = gp(1:size(f,1), 1:size(f,2)); 
figure;
subplot(1, 2, 1), imshow(h), title('原图像');
subplot(1, 2, 2), imshow(gpc), title('已填充的滤波效果');

代码运行效果如下:

现在,这个图像有围绕在四周的均匀黑色边界。因此, 用这个无限序列与平滑滤波器卷积,将会在图像所有的亮边缘显示灰色的模糊效果。

3.2 DFT 滤波的基本步骤

前面的讨论可以概括为下面几个步骤,其中 f 是被滤波处理的图像,gpc为处理结果,同时假设滤波函数 H与填充后的图像大小相等。

  1. 把输入图像变成double类型图像:
f = im2double(rgb2gray(h));   
  1. 用函数 paddedsize 获得填充参数:
PQ = paddedsize(size(f)); 
  1. 得到有填充的傅立叶变换:
Fp = fft2(f,PQ(1),PQ(2)); 
  1. 用滤波器乘以FFT 变换:
Gp=Hp.*Fp;  
  1. 获得 Gp 的逆 FFT 变换:
gp=ifft2(Gp);  
  1. 修剪左上部矩形为原始大小:
gpc = gp(1:size(f,1), 1:size(f,2)); 

预处理阶段包括确定图像大小,获得填充参数和生成一个滤波函数等,后处理阶段包括计算结果的实部,修剪图像,以及将图像类型的转换。

3.3 频域滤波的M-函数

有一些可用 的 M-函数是很方便的,它们可以接收输入图像和滤波函数,处理所有滤波细节,并输出滤波后的结果以及修剪图像。下面的函数可实现这些工作,假定滤波函数已被适当地做了大小排列。在某些应用中,把滤波后的图像变换为与输入相同的类是很有用的;有些时候处理浮点数是必要的。这些函数可以做这些事。

function g = dftfilt(f, H, classout) 
[f, revertClass] = tofloat(f);               %用函数 tofloat 把输入图像变换为浮点图像:
F = fft2(f, size(H, 1), size(H, 2));         %得到有填充的傅立叶变换
g = ifft2(H.*F);                             %获得H.*F的逆FFT变换
g = g(1:size(ff 1), 1:size(f, 2));           %修剪左上部矩形为原始大小
if nargin == 2 || strcmp(classout,'priginal')         %输入参数个数为2
    g = revertClass(g);                      %把滤波过的图像变换为输入图像的类
 elseif strcmp(classout,'fltpoint')          %比较classout是否为fltpoint
   return 
 else
   error('Undefined class for the output image.’)
end
   
2017-09-10 10:34:01 Cristal_yin 阅读数 1398
  • 宏定义与预处理函数函数库-C语言专题第6部分

    本课程综合讲解了C语言的预处理和宏定义,详细讲述了宏定义的细节规则和头文件包含等常用预处理;然后讲述了函数的使用、函数库的使用,静态链接库和动态链接库等的制作和使用。本章的目标是提升大家对函数及函数库的认知,提升在实战中使用函数库解决问题的能力。

    8061 人正在学习 去看看 朱有鹏

图像分割

点、线和边缘检测

  • 点检测

    点检测在MATLAB中可以用函数imfilter来实现

    点检测方法

    >> g = abs(imfilter(double(f), w)) >= T

    其中f 是输入图像,w是一个合适的点检测掩模, g是结果图像

    • 计算已滤波的图像,即abs(imfilter(double(f),w));

    • 使用来自己滤波的图像的数据找到T的值

    • 将已滤波的图像与T做比较

    点检测举例

    >> w = [-1 -1 -1;-1 8 -1; -1 -1 -1];
    >> g = abs(imfilter(double(f), w));
    >> T = max(g(:));
    >> g = g>=T;

    方法二

    >>g = imsubstract(ordfilt2(f, m*n, ones(m, n)),ordfilt2(f, 1, ones(m, n)));
    >> g = g >= T;
  • 线检测

    线检测中对指定方向的线更感兴趣,这种情况下可以与该方向相关的掩模并对其输出做出阈值处理。

    检测指定方向的线

    >> w = [2 -1 -1 ; -1 2 -1; -1 -1 2];
    >> g = imfilter(double(f), w);
    >> gtop = g(1:120, 1:120);
    >> gtop = pixeldup(gtop, 4);
    >> subplot(1,2,1);
    >> gbot = g(end-119:end, end-119:end);
    >> gbot = pixeldup(gbot, 4);
    >> g = abs(g);
    >> T = max(g(:));
    >> g = g >= T;

    b 图是对a 进行 45. 检测器处理后的节刚过,下面两幅分别是它的左上角和右下角的放大图,e 是b 的绝对值 f 是满足条件 g>= T的所有点

    函数pixeldup

    ​ pixeldup(m,n)————%pixeldup函数是将图像扩大m*n倍,通过复制每个像素点m*n次。

    函数edge

    边缘检测的基本意图是使用如下两个基本准则之一在图像中找到亮度快速变化的地方:

    • 找到亮度的一阶导数在幅度上比指定的阈值大的地方
    • 找到亮度的二阶导数有零交叉的地方
    [g, t] = edge(f, 'method', parameters) 

    其中f 是输入图像 , method 是下表中的方法

    输出中 g是一个逻辑数组 ,其值如下决定:

    ​ 在f 中检测到边缘的位置为1, 在其他位置为 0

    t 参数是可选的,它给出edge使用的阈值,以确定那个梯度值足够大到可以称为边缘点。

    Sobel边缘检测器

    [g, t] = edge(f, 'soble', T, dir)
    • 其中f 是输入图像,T 是一个指定的阈值 ,dir指定检测边缘的首选方向:‘horizontal’、’vertical’、 或’both’
    • g 是在被检测到边缘的位置处为 1而在其他位置为0 的逻辑类图像
    • 输出参数t 是可选的,它是函数edge所用的阈值
    • 若指定了T的值,则t = T ; 否则,若T 未被赋值 ,则函数edge会令t 等于它自动确定的一个阈值,然后用于边缘检测。
    • 在输出参量中要包括t的主要原因之一是为了得到一个阈值的初始值
    • 若使用语法 g = edge(f) 或 [g, t] = edge(f) ,则函数edge会默认使用Sobel 检测器

    Prewitt边缘检测器

    [g, t] = edge(f, 'prewitt',T, dir)

    Prewitt 检测器比Sobel 检测器在计算上简单一点,但是比较容易产生一些噪声

    Roberts边缘检测器

    该检测器是最古老的边缘检测器之一,它也是最简单的一种边缘检测器;经常用于硬件的实现,因为既简单又快速。

    Laplacian of a Gaussian 检测器

    [g, t] = edge(f, 'log', T, sigma)

    其中sigma是标准偏差,默认值为2

    零交叉检测器

    该检测器基于与LOG方法相同的概念,但卷积是使用指定的滤波函数H执行的

    [g, t] = edge(f, 'zerocross',T, H)

    Canny边缘检测器

    该检测器是使用函数edge的最有效边缘检测器

    [g, t] = edge(f, 'canny', T, sigma) 
    • 其中T 是一个向量, T= [T1,T2]
    • sigma 是平滑滤波器的标准偏差
    • t 是一个二元向量,该向量包含该算法用到的两个阈值
    >> [gv, t] = edge(f,'sobel','vertical');
    >> gv = edge(f, 'sobel', 0.15, 'vertical');
    >> gboth = edge(f, 'sobel', 0.15);
    >> w45 = [-2 -1 0;-1 0 1; 0 1 2]
    >> g45 = imfilter(double(f), w45, 'replicate');
    >> T = 0.3 * max(abs(g45(:)));
    >> g45 = g45 >= T;
    >> f45= [0 1 2;-1 0 1;-2 -1 0]
    >> h45= imfilter(double(f), f45,'replicate');
    >> T = 0.3 * max(abs(h45(:)));
    >> h45 = h45 >= T;

    a . 原图像

    b .使用带有自动确定的阈值的一个垂直Sobel 掩模后, 函数edge导致的结果

    c .使用指定阈值后的结果

    d .使用指定阈值来决定垂直边缘和水平边缘的结果

    e .使用函数imfilter 计算 45° 边缘的结果

    f . 使用函数imfilter 计算 -45° 边缘的结果

    Sobel、LOG和Canny 边缘检测器的比较

    >> [g_sobel_default, ts] = edge(f, 'sobel');
    >> [g_log_default, tlog] = edge(f, 'log');
    >> [g_canny_default, tc] = edge(f, 'canny');
    >> g_sobel_best = edge(f, 'sobel', 0.05);
    >> g_log_best = edge(f, 'log', 0.003, 2.25);
    >> g_canny_best = edge(f, 'canny', [0.04 0.10], 1.5);

    ​ 左列: Sobel、LOG 和 Canny 边缘检测器使用默认选项产生的结果

    右列:交互地显示原图像的主要特征,减少了无关的细节

    综合所有,Canny 边缘检测器产生的最好结果

使用Hough变换的线检测

寻找并链接图像中线段的处理方式

  • 函数sparse

    给是一个矩阵,用函数sparse把他转换成稀疏矩阵

    S = sparse(A)

    更常用的方法:

 S = sparse(r, c, s, m, n)
  • r 和 c 分别是我们希望转换为稀疏矩阵的矩阵中非零元素的行和列索引向量

    • S 是一个向量,它包含有相应于索引对(r, c) 的值

    • m n 是结果矩阵的行维数和列维数

    • 函数full

    给出任意一个稀疏矩阵,用full 函数来获得完整的矩阵

A = full(S)
  • 使用hough变换做峰值检测

    • 找到包含有最大值的hough变换单元并记下它的位置
    • 把第一步中找到的最大值点的邻域中的hough变换单元设为零
    • 重复该步骤,直到找到需要的峰值数时为止,或者达到一个指定的阈值时为止
  • 函数houghpeaks

    解决上述所讲的问题

  • 使用hough变换做先检测和链接

    一旦hough变换中识别出了一组候选的峰被,则他们还要留待确定是否存在与这些峰值相关的线段以及它们的起始和结束为止。对每一个峰值来说,第一步是找到图像中影响到峰值的每一个非零值点的位置。因此,编写了函数houghpixels

    这里使用该函数来找到的位置相关的像素必须结合成线段,

  • 函数houghlines采用下面的策略

  • 使用hough变换做先检测和链接

    [H, theta, rho] = hough(f, 0.5);
    
    imshow(imadjust(mat2gray(H)),'XData',theta,'YData',rho,'InitialMagnification','fit'),axis on, axis normal
    
    xlabel('\theta'),ylabel('\rho')
    
    [r, c] = houghpeaks(H, 5);
    
    hold on
    
    plot(theta(c), rho(r), 'linestyle', 'none', 'marker', 's', 'color', 'w')
    
    lines = houghlines(f, theta,rho,r,c)
    
    figure, imshow(f),hold on
    
    In images.internal.initSize (line 71)
    
    In imshow (line 309) 
    
    for k = 1:length(lines)
    
    xy = [lines(k).point1 ; lines(k).point2];
    
    plot(xy(:, 2),xy(:,1),'LineWidth', 4, 'Color', [.6 .6 .6]);
    
    end

阈值处理

  • 全局阈值处理
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

T2 = graythresh(f);

T2 * 255

bw = im2bw(f, T2);

  • 局部阈值处理

    全局阈值处理方法在背景照明不均匀时有可能失效,在这种情况下

    • 针对照明问题做预处理以补偿图像,然后再对预处理后的图像采用全局阈值处理
2016-10-20 17:31:38 David_Han008 阅读数 2542
  • 宏定义与预处理函数函数库-C语言专题第6部分

    本课程综合讲解了C语言的预处理和宏定义,详细讲述了宏定义的细节规则和头文件包含等常用预处理;然后讲述了函数的使用、函数库的使用,静态链接库和动态链接库等的制作和使用。本章的目标是提升大家对函数及函数库的认知,提升在实战中使用函数库解决问题的能力。

    8061 人正在学习 去看看 朱有鹏

数字图像的分类

根据特性分为:
- 位图
通常用数字阵列来表示,常见的格式有BMP,JPG,GIF
- 矢量图
是由矢量数据库来表示,常见的格式有PNG图像
根据每个像素所代表的信息不同分为:
- 二值图像
0来表示黑色,1来表示白色—-越大越亮
- 灰度图像
所有的取值在0-255,然后值越大越白
- RGB图像
RGB颜色代码可以用16进制来书写
这里写图片描述

//两个16进制组成排列有256中可能
0XFF0000//表示红色R
0X00FF00//表示绿色G
0X0000FF//表示蓝色B
0X000000//表示黑色
0XFFFFFF//表示白色
0X808080//表示灰色
  • 索引图像
    他的诞生完全是为了省空间,但是怎么省去空间,我还是不知道(感觉相当于增量调制,用增加的量来表示代码)

像素

像素就是包含有图像的信息的一个最小的集合。

图像的空间分辨率

图像的空间分辨率(spatial Resolution)是指的图像中单位长度包含像素和点的数目,通常用像素/英寸(ppi)为单位来表示。例如72ppi就表示图像中每英寸包含72个像素或点

图像的灰度级/辐射计量分辨率

灰度级分辨率又叫做色阶,色阶是指的图像中可分辨的灰度级数目,色阶越少,可以颜色数目也越少。

邻域

这里写图片描述
数字图像中一些基本的性质:
- 邻接性
- 连通性
- 区域与边界

基本图像操作

  • 点运算和邻域运算
    点运算是对图像中每个像素点进行同样的灰度变换
    邻域运算(邻域变换)对图像中每个小范围(邻域内)像素进行灰度变换
  • 线性和非线性操作

细胞数组

在MATLAB中细胞数组就是可以在一个数组内部定义

>>cell={'a',12};
>>cell{1}='a'%用花括号进行索引

结构体

结构体就是一种聚合类型

struct.Name='David_Han';
struct.Age=23;
struct = 
    Name: 'David_Han'
     Age: 23

meshgrid()函数

meshgrid函数是拥有绘制三维曲面
绘制中心在原点的二维高斯函数的图像

u=[-10:0.1:10];
v=[-10:0.1:10];%取200个点
[U,V]=meshgrid(u,v);
H=exp(-(U.^2+V.^2)./2/3^2);
mesh(u,v,H)%用于出图

这里写图片描述

MATLAB中图像的读写

A=imread('C:\Users\Administrator\Desktop\1.jpg');
imshow(A)

这里写图片描述

imfinfo('C:\Users\Administrator\Desktop\1.jpg')
ans = 
           Filename: 'C:\Users\Administrator\Desktop\1.jpg'
        FileModDate: '23-十月-2016 15:11:09'
           FileSize: 92558
             Format: 'jpg'
      FormatVersion: ''
              Width: 811
             Height: 695
           BitDepth: 24
          ColorType: 'truecolor'
    FormatSignature: ''
    NumberOfSamples: 3
       CodingMethod: 'Huffman'
      CodingProcess: 'Progressive'
            Comment: {}

多帧图像的显示

>> load mri%载入matlab中自带图像
>> imshow(D(:,:,7),map)

这里写图片描述

load mri
imshow(D(:,:,7),map);
figure,montage(D,map);
figure
mov=immovie(D,map);
colormap(map);%设定颜色表
movie(mov);%播放电影

这里写图片描述

像素查看工具

输入impixellinfo命令后,对着光标的移动就会显示出指针位置的像素值
这里写图片描述
还可以通过输入imdistline命令后查看两点之间的距离
这里写图片描述

灰度直方图

灰度直方图用于图像分割和图像灰度变等过程
图像的直方图描述的是图像中各个灰度等级出现个概率,横坐标表示的是各个像素点的灰度级别,纵坐标是各个灰度级别的像素在图像中出现的次数或者概率。
在这个地方一直报错,目前知道的原因是因为图片的格式不是tif,我用示例照片是可以做的
这里写图片描述
注意:现在看来是因为不是灰度图像,所以要将彩色图像转化成灰度图像。

 I = imread('pout.tif');
 imhist(I)

这里写图片描述

灰度的线性变换

对灰度图像乘以线性变换用来改变图像的灰度值

灰度对数变换

灰度的对数变换可以增强一副图像中较暗部分的细节

clear all
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
figure;
imshow(A);
title('傅里叶变换前')
%显示出这幅图像的频谱
F=fft2(im2double(A));
F=fftshift(F);%也就是说用fft和fftshift两个函数,才完成了傅里叶变换
F=abs(F);%求出他的实部
figure
imshow(F,[]);
title('傅里叶变换后')

解释部分:

1、im2double(A)%这个函数将图像转化成double类型
%转化成double类型后再对这个图像进行二维的傅里叶变换,并且将这个值赋值给F

2、fftshift函数:
fftshift的作用正是让正半轴部分和负半轴部分的图像分别关于各自的中心对称。因为直接用fft得出的数据与频率不是对应的,fftshift可以纠正过来

这里写图片描述
哈哈,我把女神的照片便道频域上了
离散傅里叶的核心就是:反折,移位,相乘,相加

在频域上进行对数变换前后对比:
代码:

clear all
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
%figure;
%imshow(A);
%title('傅里叶变换前')
%显示出这幅图像的频谱
F=fft2(im2double(A));
F=fftshift(F);%也就是说用fft和fftshift两个函数,才完成了傅里叶变换
F=abs(F);%求出他的实部
figure
imshow(F,[]);
title('对数变换前')
%经过对数变换后
T=0.1*log(F+1.5);
figure
imshow(T);
title('频域经过对数变换后')

这里写图片描述
好漂亮啊!!
反正规律就是前面的系数越小就越黑,系数越大,就越白

伽玛变换

伽玛变换也叫做指数变换或者幂次变换
是一种常用的灰度非线性变换
MATLAB中实现伽玛变换的是imadjust函数

clear all
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
subplot(1,3,1);
imshow(A);
title('伽玛变换前')
%Gamma0.5
subplot(1,3,2)
imshow(imadjust(A,[],[],0.5));
title('Gamma取0.5')
%Gamma1.5
subplot(1,3,3)
imshow(imadjust(A,[],[],1.5));
title('Gamma取1.5')
J=imadjust(I,[low_in,high_in],[low_out,high_out],gamma);
%该函数将输入图像I中的low_in,high_in之间的值映射到输出图像J中,low_out 和 high_out之间的值,其他区域将会被裁减掉

Gamma>1,图像的高灰度区域对比度得到增强,也就是说区分度更大,图像变暗
Gamma=1,灰度变换是线性的
Gamma<1,图像的低灰度区域得到增强,图像变亮了,区分度更小

这里写图片描述

clear all
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
subplot(2,3,1);
imshow(A);
title('伽玛变换前')
%Gamma0.5
subplot(2,3,2)
imshow(imadjust(A,[],[],0.5));
title('Gamma取0.5')
%Gamma1.5
subplot(2,3,3)
imshow(imadjust(A,[],[],1.5));
title('Gamma取1.5')
subplot(2,3,4)
I=rgb2gray(A);%只有把原始的彩色图像转化成灰度图,才可以产生灰度的直方图
imhist(I);
subplot(2,3,5)
imhist(imadjust(I,[],[],0.5));
subplot(2,3,6)
imhist(imadjust(I,[],[],1.5));

这里写图片描述

%这个函数可以将彩色图像转换成灰度图像
I=rgb2gray(A);%只有把原始的彩色图像转化成灰度图,才可以产生灰度的直方图

灰度的阈值变换

灰度的阈值判断可以将一副灰度图像转变黑白的二值图像,用户给定一个分界线,高于这个分界线灰度值设成1,低于分界线的灰度值设成0。灰度的阈值变换经常用于图像分割
MATLAB中和图像的阈值变换相关的函数

Bw=im2bw(I,level)%I是输入图像,level是一个在0~1之间的双精度浮点数,例如166/255
thresh=graythresh(I) %graythesh函数自动为这个变换找到最优解
clear all
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
thresh=graythresh(A);
Bw1=im2bw(A,thresh);
subplot(1,3,1)
imshow(Bw1)
title('graythresh最优化的解')
Bw2=im2bw(A,50/255);
subplot(1,3,2)
imshow(Bw2)
title('阈值取50/255')
Bw3=im2bw(A,200/250);
subplot(1,3,3)
imshow(Bw3)阈值越小,白的部分越多,阈值越大,黑的部分越多
title('阈值取200/255')

这里写图片描述

分段线性变换

分段线性变换:对用户感兴趣的部分进行增强,对用户不感兴趣的部分进行减弱

直方图均衡化

直方图均衡化也叫灰度均衡化,是指的通过某种灰度映射使得,在整个直方图灰度的概率近似相等
matlab中提供的直方图均衡化的函数

[J,T]=histeq(I)%I是输入原始图像,J是经过直方图均值化输出的图像,T是变换矩阵
clear all
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
I=rgb2gray(A);%只有把原始的彩色图像转化成灰度图,才可以产生灰度的直方图
subplot(2,2,1)
imshow(I);
title('初始图像');
subplot(2,2,3)
imhist(I);
title('初始图像的直方图')
subplot(2,2,2)
imshow(histeq(I));
title('均值化');
subplot(2,2,4)
imhist(histeq(I));
title('均值化的直方图');

这里写图片描述
可以看出均衡化将直方图的灰度更加的平均

直方图规定化

直方图规定化是在直方图均衡化的基础上建立的,我们希望得到人们预期的直方图的形状,而直方图图均衡化做不到,所以就有了直方图规定化

[J,T]=histeq(I),hgram)%hgram叫做直方图的收集箱数目,
对于double类型的图像,hgram的范围是[0,1],
对于unit8类型的图像而言,是[0,255],
对于unit16型的图像取值范围[0,65535]
65535是计算机16位二进制最大数
clear all
%导入预期图像的灰度值
Idea=imread('D:\MATLAB\matlab编写的程序\原材料\2.png');
Idea=rgb2gray(Idea);%并且把他转化成灰度图像
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
I=rgb2gray(A);%只有把原始的彩色图像转化成灰度图,才可以产生灰度的直方图
subplot(2,3,1)
imshow(I);
title('初始图像');
subplot(2,3,4)
imhist(I);
title('初始图像的直方图');
subplot(2,3,2)
imshow(Idea);
title('预期图像');
subplot(2,3,5)
imhist(Idea);
title('预期图像的直方图');
[x,hgram1]=imhist(Idea);%从目标函数中提取hgarm
J=histeq(I,hgram1);
subplot(2,3,3)
imshow(J);
title('标定化后');
subplot(2,3,6)
imhist(J);
title('标定化后');

这里写图片描述
例如


图像分割

图像分割是指将图像中具有特殊意义的不同区域划分开来。
图像分割算法是基于图像灰度值的不连续性或其相似性。
图像的边缘是图像的最基本的特征,边缘点是指图像中周围像素灰度有了阶跃变化的那些像素点

常用的边缘检测算子

1、梯度算子
sobel算子,prewitt算子,roberts算子
2、基于高斯-拉普拉斯算子边缘检测

MATLAB实现:

BW=edge(I,type,thresh,direction,'nothinning');
%I是输入灰度图像
type是梯度算子的种类:sobel\prewitt\roberts
thresh是敏感度阈值函数,任何灰度值低于此阈值函数的都不会被检测到
direction指定的是操作者感兴趣的边缘方向:horizontal/vertical/both
nothinning是可选参数,是指可以跳过边缘细化算法来加快算法的运行速度,在默认的条件下,"thinning"就是边缘细化
bw是返回的二值图像,1白色为边缘部分
BW=edge(I,'log',thresh,sigma)
参数:
I:输入图像
"log"表示高斯-拉普拉斯算子
thresh也是敏感度阈值参数
sigma指定生成高斯滤波所使用的标准差,默认的标准差值为2,滤镜
clear all
%导入预期图像的灰度值
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
I=rgb2gray(A);
B1=edge(I,'sobel');
subplot(1,3,1)
imshow(B1);
B2=edge(I,'prewitt');
subplot(1,3,2)
imshow(B2);
B3=edge(I,'roberts');
subplot(1,3,3)
imshow(B3);

这里写图片描述
基于高斯-拉普拉斯算子的边缘检测

clear all
%导入预期图像的灰度值
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
I=rgb2gray(A);
B4=edge(I,'log');
imshow(B4);

这里写图片描述

canny算子的边缘检测
clear all
%导入预期图像的灰度值
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
I=rgb2gray(A);
B4=edge(I,'canny');
imshow(B4);

这里写图片描述
总之一句话,canny最好

霍夫曼变换

1、[H,theta,rho]=hough(BW,param1,val1,param2,val2);
BW是边缘检测后额二值图像
param1,val1param2,val2是一一配对的
H是变换得到的hough矩阵
thetarhoHough对应于矩阵的每一列和每一行的角度和半径组成的向量
2Houghpeaks()函数用于寻找hough矩阵中寻找指定数目的峰值点
Pesks=houghpeaks(H,numpeaks,param1,val1,param2,val2)
H是由于hough()函数得到的hough矩阵
numpeaks是指需要找到的峰值数目,默认值为1
param1,val1param2,val2是一一配对的
3houghlines()根据hough矩阵的峰值检测结果提取直线的线段
lines=houghlines(BW,theta,rho.peaks.param1,val1,param2,val2)
BW是边缘检测后的二值图像
theatrho是由hough函数返回得到
param1,val1param2,val2是一一配对的
clear all
%导入预期图像的灰度值
A=imread('D:\MATLAB\matlab编写的程序\原材料\1.png');
I=rgb2gray(A);
B4=edge(I,'canny');
figure;
imshow(B4);
[H,T,R]=hough(B4);%Hough矩阵图像中标出峰值位置,经过边缘检测后的图像进行拆分
figure;
imshow(H,[],'XData',T,'YData',R,'InitialMagnification','fit');
%在hough矩阵中寻找前5个大于hough矩阵中最大值的0.3倍峰值
P=houghpeaks(H,5,'threshold',ceil(0.3*max(H(:))));
x=T(P(:,2));
y=R(P(:,1));
plot(x,y,'s','color','red');%标出峰值的位置
lines=houghlines(B4,T,R,P,'FillGap',5,'Minlength',7);%合并小于5的线段,丢弃所有长度小于7的线段
figure,imshow(A),hold on 
max_len=0;
for k=1:length(lines)
    xy=[lines(k).point1;lines(k).point2];
    plot(xy(:,1),xy(:,2),'lineWidth',2,'color','green');

    %绘制线段的端点
     plot(xy(1,1),xy(1,2),'x','LineWidth',2,'color','red');
     plot(xy(2,1),xy(2,2),'x','LineWidth',2,'color','green');
    len = norm(lines(k).point1-lines(k).point2);
    if(len>max_len)
    max_len=len;
    xy_long=xy;
    end  
end

原理方面真的不是很懂啊,就事找出特征点,然后进行画图
这里写图片描述
红色的就是特征点,然后绿色的就是连接的线

特征提取

11111

SVM

用函数SVMtrain()来训练一个SVM分类器
SVMStruct=svmtrain(Trainning,Group)
Training是一个包含训练数据的m行和n列的2维矩阵,每行表示的1个训练样本,m表示训练样本数目,n表示样本维数

这里写图片描述

Group是一个代表训练样本类标签的1维向量,其中每个元素只能为0或者1;1表示正例,0表示反例
Group的维数(也就是列数),必须和Training和行数相等
SVMStruct是训练所得到的代表SVM分类器的结构体,其中包含

设定核函数

SVMStruct=svmtrain(...,'Kernel_Function','Kernel_FunctionValue');
Kernel_FunctionValue的取值:
2019-01-05 23:38:02 LVJINYANJY 阅读数 149
  • 宏定义与预处理函数函数库-C语言专题第6部分

    本课程综合讲解了C语言的预处理和宏定义,详细讲述了宏定义的细节规则和头文件包含等常用预处理;然后讲述了函数的使用、函数库的使用,静态链接库和动态链接库等的制作和使用。本章的目标是提升大家对函数及函数库的认知,提升在实战中使用函数库解决问题的能力。

    8061 人正在学习 去看看 朱有鹏
% 将两幅256×256的灰度图像进行二维傅立叶变换,分别得到各自的幅度谱图像和相位谱图像,显示这4幅图像。
% 将两幅图像的相位谱交换,进行反傅立叶变换,显示这两幅重建图像。

% 二维快速傅立叶变换函数fft2( ) 
% 相位提取函数 angle( )
% 幅度提取函数abs ( )

%
clear;clc;
%
im1 = double(imread('1-Debbie4.gif'));
im2 = double(imread('12-Panda.bmp'));
%
im1_f = fft2(im1);
im2_f = fft2(im2);
%
im1_abs = abs(im1_f);
im2_abs = abs(im2_f);
im1_ang = angle(im1_f);
im2_ang = angle(im2_f);
im1_d = fftshift(im1_f);
im2_d = fftshift(im2_f);
%
im1_e = im1_abs.*exp(1i*im2_ang);
im2_e = im2_abs.*exp(1i*im1_ang);
%
im1_r = real(ifft2(im1_e)); 
im2_r = real(ifft2(im2_e)); 


% display
figure
subplot(231)
imshow(mat2gray(im1));
xlabel('Original 1')
subplot(234)
imshow(mat2gray(im2));
xlabel('Original 2')
subplot(232)
imshow(mat2gray(10*log10(abs(im1_d))));
xlabel('Magititute 1')
subplot(235)
imshow(mat2gray(10*log10(abs(im2_d))));
xlabel('Magititute 2')
subplot(233)
imshow(mat2gray(angle(im1_d)));
xlabel('Angle 1')
subplot(236)
imshow(mat2gray(angle(im2_d)));
xlabel('Angle 2')

%
figure
subplot(121)
imshow(mat2gray(im1_r));
xlabel('Rec. Image 1')
subplot(122)
imshow(mat2gray(im2_r));
xlabel('Rec. Image 2')

 

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