图像处理中的几何中心法

2012-03-11 00:05:42 breezewin 阅读数 2040

一.  设计一个程序,对一幅灰度图像的实现如下几何变换,1)放大为原图1.5倍;2)绕中心旋转30度(CW);3)采用偏移量插值实现一个透视变换.灰度差值用最近邻插值和双线性插值。

1.放大为原图的1.5倍:

 (1) 最近邻插值法:

原理:输出图像像素的灰度值等于离它所映射到的位置最近的输入像素的灰度值。

具体实现代码:

编写图像缩放的函数myresize.m :

function myresize( I , d )
[M,N]=size(I);
I1=uint8(zeros(floor(M*d),floor(N*d)));
for i=2:floor(M*d)
    for j=2:floor(N*d)
        x=floor(i/d);   y=floor(j/d);
        if((x<M)&&(y<N))
            I1(i,j)=I(x,y);
        end
    end
end
figure;imshow(I);
figure;imshow(I1);
end

Command窗口中输入:

I=imread('lena3.jpg')
myresize(I,1.5)

处理效果:

                         处理前256×256


                   处理后384×384

(2)双线性插值法:

  原理:对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为 (i+u,j+v),其中i,j为非负整数,u,v为[0,1]区间的浮点数,则这个像素的值 f(i+u,j+v)可由原图像中的坐标为(i,j),(i+1,j),(i,j+1),(i+1,j+1)所对应的周围四个像素的值决定。

 具体实现:

clear,clc
I=imread('lena3.jpg');
[M,N]=size(I);
d=1.5;
I1=uint8(zeros(floor(M*d),floor(N*d)));
M1=floor(M*d);  N1=floor(N*d);
for i=2:M1-1
    for j=2:N1-1
        x=i/d;  a=floor(x);   u=x-a;
        y=j/d;  b=floor(y);   v=y-b;       
%a、b为整数部分,u、v为小数部分I1(i,j)=(1-u)*(1-v)*I(a,b)+(1-u)*v*I(a,b+1)    
+u*(1-v)*I(a+1,b)+u*v*I(a+1,b+1);
    end
end
%处理四周边缘的点,采用线性插值法
I1(1,1)=I(1,1);  I1(1,N1)=I(1,N);
I1(M1,1)=I(M,1); I1(M1,N1)=I(M,N);
for j=2:N1-1
     y=j/d;  b=floor(y);   v=y-b;  
     I1(1,j)=(1-v)*I(1,b)+v*I(1,b+1);
     I1(M1,j)=(1-v)*I(M,b)+v*I(M,b+1);
end
for i=2:M1-1
     x=i/d;  a=floor(x);   u=x-a;
     I1(i,1)=(1-u)*I(a,1)+u*I(a+1,1);
     I1(i,N1)=(1-u)*I(a,N)+v*I(a+1,N);
end
figure;imshow(I);
figure;imshow(I1);

并在命令窗口中输入:I2=imresize(I,1.5,'bilinear'),即调用系统的函数,与自己所得到的I1进行比较,结果如下:

可以看出基本上还是吻合的。但进一步研究发现,自己所写的程序存在不足:对于

256×256的图片,最多只能放大到原图的2倍,当高于2倍时,a、b的值仍有可能取

到0,算法需要进一步的改进。可以选择不处理边缘的值,将边缘的值均置为0,此时

可以实现放大的倍数不受限制,并且代码简单,但此方法的处理后图像的边缘无法获得。

优化后代码如下:

clear,clc
I=imread('lena3.jpg');
[M,N]=size(I);
d=1.5;
I1=uint8(zeros(floor(M*d),floor(N*d)));
for i=1:floor(M*d)
    for j=1:floor(N*d)
        x=i/d;  a=floor(x);   u=x-a;
        y=j/d;  b=floor(y);   v=y-b;       
       if((a>0)&&(b>0)&&(a<M)&&(b<N))  %边缘加限制  I1(i,j)=(1-u)*(1-v)*I(a,b)+(1-u)*v*I(a,b+1)+u*(1-v)*I(a+1,b)
+u *v*I(a+1,b+1);
        else    
I1(i,j)=0;
        end
    end
end
figure;imshow(I);    
figure;imshow(I1);


处理效果:

处理前256×256:

处理后384×384:

2.图像绕中心旋转30度(CW):

(1)最近邻插值法:

原理:将平移变换和旋转变换组合起来,以产生围绕任一点(x0,y0)旋转:先将图像进行平移,从而使位置(x0,y0)成为原点,然后,旋转角度,再平移其原点。

图像以图像中心为中心点的旋转公式(逆时针):

x1=(y0-N/2)sin(a)+(x0-M/2)cos(a)+M/2;

y1=(y0-N/2)cos(a)-(x0-M/2)sin(a)+N/2;

其中,(x0,y0)为原图上的点,(x1,y1)为变换后的点,a为旋转的角度。

 

具体实现:

clear,clc
I=imread('lena4.jpg');    %原图为128×128
[M,N]=size(I);
ang=30;
I1=I;
for i=1:M
   for j=1:N
x=floor((i-M/2)*cos(ang*pi/180)+(j-N/2)*sin(ang*pi/180)+0.5+M/2);
y=floor((j-N/2)*cos(ang*pi/180)-(i-M/2)*sin(ang*pi/180)+0.5
+N/2);
     if((x<M)&(y<N)&(x>0)&(y>0))   
       I1(i,j)=I(x,y);   
     else
     I1(i,j)=0;      %无映射及边缘处灰度值为0
     end
   end
end
subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(I1);


处理结果:

分析:采用上述的最近邻插值法,可以发现,图像的边缘处理不完善,并且图像有一点失真,另外,由于处理时,图像的画布没有扩大,导致图像的四角缺失。

(2) 双线性插值法:

   采用系统旋转函数imrotate,其格式为B=imrotate(A,angle,method),

    nearest:  最邻近线性插值(默认);

    bilinear:双线性插值 ;

bicubic:  双三次插值;

具体实现:

clear,clc
I=imread('lena3.jpg');
I1=imrotate(I,30,'bilinear');   %双线性插值将图像逆时针旋转30度
subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(I1);

处理后结果:

分析:调用imrotate进行双线性插值旋转,处理的效果明显比上最邻近插值法好,能够

很好地保持原图的完整性,并失真度较小,比较理想。

 

  3. 采用偏移量插值实现一个透视变换:

    原理:首先确定图片四个顶点的偏移量,从而计算出方程组的系数矩阵,此矩阵及变换系数,进一步确定a、b、c、d和e、f、g、h,最后根据x' = a*x + b*y + c*x*y +d 、y' = e*x + f*y + g*x*y +h确定出变换后的横坐标和纵坐标。

具体实现:

clear,clc
I= imread('lena3.jpg');
[M N]=size(I);
I1 = zeros(M,N);
R=[1,1,M/4-1,0
    1,N,0,0
    M,1,-M/5,N/5-1
    M,N,0,-N/5];
    %R表示原图中的点对应的偏移量
A1=[R(:,1) R(:,2) R(:,1).*R(:,2) ones(4,1)];    
%方程组的系数矩阵
x1=A1\R(:,3);     %a,b,c,d
x2=A1\R(:,4);     %e,f,g,h
T=[x1';x2'];
for i = 1:M
    for j = 1:N
      a = T*[i;j;i*j;1];   a = int32(a);
      s=i+a(1);   t= j+a(2);  % (i,j)->(s,t)
if((s>=1)&&( s <= M) &&( t >= 1) &&( t <= N))
            I1(s,t)=I(i,j);
        end
    end
end
I1 = uint8(I1);
subplot(1,2,1);imshow(I);
subplot(1,2,2);imshow(I1);

  处理效果:

分析:实现的是向前映射透视,如需实现向后透视,重新获取变换系数矩阵,并使变换

后的图像坐标向原图映射,即(s,t)->(i,j)的变换。

 

二.  绘制一幅灰度图像的梯度幅度图像(三点法求梯度),针对梯度幅度图像合理的选择一个阈值(通过试验即可)将其二值化,以获得图像边缘检测图像。

原理:三点法求梯度,图像的梯度之为水平方向相邻像素之差的绝对值和垂直方向相邻像素之差的绝对值中的最大值。最后选取一个合适的阈值,当大于该阈值时,其灰度值设置为255,小于该值时设置为0。

具体实现:

clc,clear
I=imread('lena3.jpg');
[M N]=size(I);
I1=[I(:,1),I(:,1:N-1)];  %矩阵向右移一位,第一列保持不变
I2=[I(1,:);I(1:M-1,:)];  %矩阵向下移一位,第一行保持不变
I3=I2-I;   I4=I1-I;    
X=max(I3(1:M,1:N),I4(1:M,1:N));   %获取梯度图像的矩阵
d=30;   %选取合适的阈值进行二值化处理
for i=1:M
    for j=1:N
      if (X(i,j)>d)
         X(i,j)=1;
      else
         X(i,j)=0;
      end
  end
end
figure;
subplot(1,2,1),imshow(I);
subplot(1,2,2),imshow(X);


处理效果:


2017-08-03 09:42:36 chaihuimin 阅读数 2692
2018-11-04 17:09:16 Notzuonotdied 阅读数 1108

I have to remind myself that some birds don’t mean to be caged . Their feathers are just too bright. And when they fly away, the part of you that knows it was a sin to lock them up. DOES rejoice. Still, the place you live in is that much more drab and empty that they’re gone. I guess I just miss my friend. ——《肖申克的救赎》

前言

几何变换,又称空间变换,是图形处理的一个方面,是各种图形处理算法的基础。它将一幅图像中的坐标位置映射到另一幅图像中的新坐标位置,其实质是改变像素的空间位置,估算新空间位置上的像素值。几何变换算法一般包括空间变换运算和插值算法。

几何变换不改变图像的像素值, 只是在图像平面上进行像素的重新安排。适当的几何变换可以最大程度地消除由于成像角度、透视关系乃至镜头自身原因所造成的几何失真所产生的负面影响。几何变换常常作为图像处理应用的预处理步骤, 是图像归一化的核心工作之一。

一个几何变换需要两部分运算:首先是空间变换所需的运算, 如平移、缩放、旋转和正平行投影等, 需要用它来表示输出图像与输入图像之间的(像素)映射关系;此外,还需要使用灰度插值算法, 因为按照这种变换关系进行计算, 输出图像的像素可能被映射到输入图像的非整数坐标上。

概念

基础概念 说明
图像的几何变换 指用数学建模的方法来描述图像的位置、大小、形状等变换。
几何变换的内容 图像的空间平移、比例缩放、旋转、仿射变换和图像插值。
几何变换的实质 改变像素的空间位置。

图像集合变换的表达式

(x,y)=T{(u,v)}(x, y) = T\{(u, v)\}

  • (x,y)(x, y)为变换后图像像素的笛卡尔坐标,(u,v)(u , v)为原始图像中像素的笛卡尔坐标。
  • 变换后,如果(x,y)=(u,v)(x, y)=(u , v),则变换后的图像仅仅是原图像的简单拷贝。
  • 注意,几何变换不改变像素值,而是改变像素所在的位置。这说明像素的亮度和色彩并不发生变化,仅仅是像素位置发生改变。

齐次坐标表示

  • 所谓齐次坐标就是用N+1N+1维向量表示NN维向量。
  • 平面上的点PP的坐标为(x,y)(x, y),其齐次坐标表示为(wx,wy,w)(wx, wy, w),其中ww为任意常数。
  • 如果规定齐次坐标的第三个分量ww11,则称为规范齐次坐标。

引入齐次坐标的原因

  • 在对图像进行操作时候,经常要对图像连续做几次变换。例如做了平移后再做旋转与缩放。因为旋转、缩放都是线性变换,因此可将旋转和缩放合并成一个变换矩阵来表示,如:

[xy1]=[x0y01]T{ \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}^T

  • 在直角坐标系中,平移不是线性变换,因此不能与旋转、缩放等操作合并成一个变换矩阵。
  • 引入齐次坐标后,平移变为线性变换,从而可以采用一个通用的变换模型(仿射变换模型)表示图像的各种几何变换。

仿射变换

[xy1]=[x0y01]T{ \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}^T

  • T仿射矩阵

T=[abpcdqmns]T=\left[ \begin{array}{ccc} a &amp; b &amp; p\\ c &amp; d &amp; q\\ m &amp; n &amp; s \end{array} \right ]

  • a b c da \ b \ c \ d:实现比例变换、旋转变换、偏移变换
  • m nm \ n:实现平移变换、mmnn分别为XXYY方向的平移量。
  • ss:实现等比例变换
  • p qp \ q:实现透视变换

图像的位置变换

  • 所谓图像的位置变换是指图像的大小和形状不发生变化,只是将图像进行平移、旋转、镜像等。
  • 图像的位置变换主要是用于目标识别中的目标配准。

平移

  • 平移的原理:
    • 在图像平移是将一幅图像中所有的点都按照指定的平移量在水平、垂直方向移动,平移后的图像与原图像相同

平移变换

  • 平移的直角坐标公式:

{x=x0+Δx(x0,y0)为平移之前的像素坐标y=y0+Δy(x,y) \begin{cases} x=x_0+\Delta x &amp; \text{$(x_0, y_0)$为平移之前的像素坐标}\\ y=y_0+\Delta y &amp; \text{$(x, y)为对应像素平移后的坐标$} \end{cases}

  • 平移的齐次坐标公式

[xy1]=[x0y01]×[100010ΔxΔy1] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} 1 &amp; 0 &amp; 0\\ 0 &amp; 1 &amp; 0\\ \Delta x &amp; \Delta y &amp; 1 \end{array} \right ]}

平移的逆变换

  • 平移的直角坐标公式:

{x=x0Δx(x0,y0)为平移之前的像素坐标y=y0Δy(x,y) \begin{cases} x=x_0 - \Delta x &amp; \text{$(x_0, y_0)$为平移之前的像素坐标}\\ y=y_0 - \Delta y &amp; \text{$(x, y)为对应像素平移后的坐标$} \end{cases}

  • 平移的齐次坐标公式

[x0y01]=[xy1]×[100010ΔxΔy1] { \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} 1 &amp; 0 &amp; 0\\ 0 &amp; 1 &amp; 0\\ -\Delta x &amp; -\Delta y &amp; 1 \end{array} \right ]}

  • 说明:平移后的图像上的每一点都可以在原图像中找到对应的点。

图像的镜像

前置条件:设图像高度为HH,宽度为WW,原图中的像素点(x0,y0)(x_0 , y_0)经过镜像后的坐标为(x,y)(x , y)

水平镜像:以图像的垂直中轴线为中心交换图像的左右两部分。

  • 水平镜像的直角坐标公式:

{x=x0y=Wy0 \begin{cases} x=x_0 \\ y=W - y_0 \end{cases}

  • 水平镜像的齐次坐标公式

[xy1]=[x0y01]×[1000100W1] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} 1 &amp; 0 &amp; 0\\ 0 &amp; -1 &amp; 0\\ 0 &amp; W &amp; 1 \end{array} \right ]}

垂直镜像:以图像的水平中轴线为中心交换图像的上下两部分

  • 垂直镜像的直角坐标公式:

{x=Hx0y=y0 \begin{cases} x=H - x_0 \\ y=y_0 \end{cases}

  • 垂直镜像的齐次坐标公式

[xy1]=[x0y01]×[100010H01] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} -1 &amp; 0 &amp; 0\\ 0 &amp; 1 &amp; 0\\ H &amp; 0 &amp; 1 \end{array} \right ]}

图像的旋转

前置条件:图像中的像素点旋转前的坐标为(x0,y0)(x_0, y_0),与y轴的角度为α\alpha,旋转θ\theta角度后的坐标为(x,y)(x, y),与y轴的角度为αθ\alpha - \theta

直角坐标公式

  • 旋转前
    • x0=rsinαx_0=rsin\alpha
    • y0=rcosαy_0=rcos\alpha
  • 旋转后
    • x=rsin(αθ)=r(sinαcosθcosαsinθ)=x0cosθy0sinθx=rsin(\alpha-\theta)=r(sin\alpha cos\theta-cos\alpha sin\theta)=x_0cos\theta-y_0sin\theta
    • y=rcos(αθ)=r(cosαcosθ+sinαsinθ)=y0cosθ+x0sinθy=rcos(\alpha-\theta)=r(cos\alpha cos\theta+sin\alpha sin\theta)=y_0cos\theta + x_0sin\theta
  • 整理旋转后的公式
    • x=x0cosθy0sinθx=x_0cos\theta - y_0sin\theta
    • y=x0sinθ+y0cosθy=x_0sin\theta + y_0cos\theta

齐次坐标公式

[xy1]=[x0y01]×[cosθsinθ0sinθcosθ0001] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} cos\theta &amp; sin\theta &amp; 0\\ -sin\theta &amp; cos\theta &amp; 0\\ 0 &amp; 0 &amp; 1 \end{array} \right ]}

图像旋转出现的问题

  • 导致在旋转后的图像中出现空洞点
    • 旋转计算后的值为小数或者负数,而坐标值应该为正整数。
    • 旋转计算后的结果值所在范围与原坐标所在的范围不同。
  • 解决方法
    • 图像旋转出现的两个问题的本质都是因为像素值的填充是不连续的。
    • 可以采用插值填充的方法来解决。

图像形状的变换

形状变换类型 说明
偏移变换 三维物体投影到平面时所产生的水平方向或者垂直方向的形状变化。
平面上比例变换 放大、缩小等。

水平偏移

直角坐标公式

{x=x0y=Shx0+y0 \begin{cases} x=x_0 \\ y=S_hx_0+y_0 \end{cases}

齐次坐标公式

[xy1]=[x0y01]×[1Sh0010001]=[x0Shx0+y01] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} 1 &amp; S_h &amp; 0\\ 0 &amp; 1 &amp; 0\\ 0 &amp; 0 &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; S_hx_0+y_0 &amp; 1 \end{array} \right ]}

垂直偏移

直角坐标公式

{x=x0+Svy0y=y0 \begin{cases} x=x_0 + S_vy_0 \\ y=y_0 \end{cases}

齐次坐标公式

[xy1]=[x0y01]×[100Sv10001]=[x0+Svy0y01] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} 1 &amp; 0 &amp; 0\\ S_v &amp; 1 &amp; 0\\ 0 &amp; 0 &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0+S_vy_0 &amp; y_0 &amp; 1 \end{array} \right ]}

图像的比例变换

直角坐标公式

{x=cxx0比例系数&gt;1:放大y=cyy0比例系数&lt;1:缩小 \begin{cases} x=c_xx_0 &amp; \text{比例系数&gt;1:放大}\\ y=c_yy_0 &amp; \text{比例系数&lt;1:缩小} \end{cases}

齐次坐标公式

[xy1]=[x0y01]×[cx000cy0001]=[cxx0cyy01] { \left[\begin{array}{ccc} x &amp; y &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} x_0 &amp; y_0 &amp; 1 \end{array} \right ]}\times{ \left[\begin{array}{ccc} c_x &amp; 0 &amp; 0\\ 0 &amp; c_y &amp; 0\\ 0 &amp; 0 &amp; 1 \end{array} \right ]}={ \left[\begin{array}{ccc} c_xx_0 &amp; c_yy_0 &amp; 1 \end{array} \right ]}

图像的比例缩放的算法

图像的缩小

图像的缩小实际上就是对原有的多个数据进行挑选或者处理,从而获得期望缩小尺寸的数据,并且尽量保持原有的特征不丢失。最简单的方法就是等间隔的选取数据

图像的放大

图像的放大从字面上看,是图像缩小的逆操作,但是从信息处理的角度来看,则难易程度完全不一样。

图像缩小是从多个信息中选出所需要的信息,而图像放大则是需要对多出的空位填入适当的值,是信息的估计,较图像缩小难度更大。

插值方式 效率 说明
最近邻插值 简单、快速 将放大后未知的像素点位置换算到原始图像上,并与原始图像上邻近的4个像素点做比较,最靠近的【如欧式距离等方式计算】邻近点的像素值即为该像素点的像素值。
双线性插值 较慢 将放大后未知的像素点位置换算到原始图像上,并将原始图像上邻近的4个像素点的灰度级别加权求和得到(权值可以采用距离进行度量,距离越近,权值越大)。
双三线性插值
  • 从理论上讲,最近邻插值的效果最差,双三次插值的效果最好,双线性插值的效果介于两者之间。
  • 最近邻插值:算法简单,插值结果不连续,视觉上锯齿效应明显
  • 双线性插值:插值的结果是连续的,视觉上比最近邻插值要平滑

双线性插值

双向性插值法将放大后未知的像素点位置换算到原始图像上,并将原始图像上邻近的4个像素点的灰度级别加权求和得到。这里的加权采用的是/[Width Height]欧式距离等距离公式/[Width \ Height]

前置条件 图例
假设放大之后的图像GG的像素点PP换算到原始图像上的位置为(x+Δx,y+Δy)(x+\Delta x, y+\Delta y),则在F上的4个邻近点的ABCDA、B、C、D分别为(x,y)(x, y)(x,y+1)(x, y+1)(x+1,y)(x+1, y)、(x+1, y+1),而eeff的点的位置为(x,y+Δy)(x, y+\Delta y)(x+1,y+Δy)(x+1, y+\Delta y)
说明:横向为y轴,竖向为x轴。
在这里插入图片描述

注意,这里采用的是欧式距离来计算距离,作为权值。

假如存在两个点A(x1,y1)A(x_1, y_1)B(x2,y2)B(x_2, y_2),则欧式距离为:

distance=(x1x2)2+(y1y2)2distance = \sqrt {(x_1 -x_2)^2+(y_1-y_2)^2}

所以权值的计算为:weight=distancewidths distanceweight = \frac {distance}{width`s \ distance}或者weight=distanceheights distanceweight = \frac {distance}{height`s \ distance}

双线性插值算法原理分析:

  • 首先计算水平方向A(x,y)A(x, y)B(x,y+1)B(x, y+1)P(x+Δx,y+Δy)P(x+\Delta x, y+\Delta y)的影响,得到ee点的灰度值

F(x,y+Δy)=(xx)2+((y+1)(y+Δy))2((xx)2+((y+1)y)2F(x,y)+(xx)2+((y+Δy)y)2((xx)2+((y+1)y)2F(x,y+1)F(x, y+\Delta y)=\frac {\sqrt{(x-x)^2+((y+1)-(y+\Delta y))^2}}{\sqrt{((x-x)^2+((y+1)-y)^2}}F(x, y)\\ +\frac {\sqrt {(x-x)^2+((y+\Delta y)-y)^2}}{\sqrt{((x-x)^2+((y+1)-y)^2}}F(x, y+1)

  • 计算C(x+1,y)C(x+1, y)D(x+1,y+1)D(x+1, y+1)P(x+Δx,y+Δy)P(x+\Delta x, y+\Delta y)点的影响,得到f(x+1,y+Δy)f(x+1, y+\Delta y)点的灰度值

F(x+1,y+Δy)=((x+1)(x+1))2+((y+1)(y+Δy))2((x+1)(x+1))2+((y+1)y)2F(x+1,y)+((x+1)(x+1))2+((y+Δy)y)2((x+1)(x+1))2+((y+1)y)2F(x+1,y+1)F(x+1, y+\Delta y)=\frac {\sqrt{((x+1)-(x+1))^2+((y+1)-(y+\Delta y))^2}}{\sqrt{((x+1)-(x+1))^2+((y+1)-y)^2}}F(x+1, y)\\ +\frac {\sqrt {((x+1)-(x+1))^2+((y+\Delta y)-y)^2}}{\sqrt{((x+1)-(x+1))^2+((y+1)-y)^2}}F(x+1, y+1)

  • 计算e(x,y+Δy)e(x, y+\Delta y)f(x+1,y+Δy)f(x+1, y+\Delta y)对于P(x+Δx,y+Δy)P(x+\Delta x, y+\Delta y)点的影响,得到P(x+Δx,y+Δy)P(x+\Delta x, y+\Delta y)点的灰度值

F(x+Δx,y+Δy)=((x+1)(x+Δx))2+((y+Δy)(y+Δy))2((x+1)x)2+((y+Δy)(y+Δy))2F(x,y+Δy)+((x+Δx)x)2+((y+Δy)(y+Δy))2((x+1)x)2+((y+Δy)(y+Δy))2F(x+1,y+Δy)F(x+\Delta x, y+\Delta y)=\frac {\sqrt{((x+1)-(x+\Delta x))^2+((y+\Delta y)-(y+\Delta y))^2}}{\sqrt{((x+1)-x)^2+((y+\Delta y)-(y+\Delta y))^2}}F(x, y+\Delta y)\\ +\frac {\sqrt {((x+\Delta x)-x)^2+((y+\Delta y)-(y+\Delta y))^2}}{\sqrt{((x+1)-x)^2+((y+\Delta y)-(y+\Delta y))^2}}F(x+1, y+\Delta y)

附录

2017-10-23 16:13:24 yyangzhenjie 阅读数 3895

经常听到同事说用投影法做图像处理的相关知识,一直没有理解,所以查找资料,这里做一个总结:

投影,在立体几何中我们学到过,是空间直线在某个方向上的投影,那么图像处理中也是这种投影思想。

最简单的投影:

水平方向投影,将图像数组进行列求和;

垂直方向投影,将图像数组进行行求和;

对于二值图像或明显特征的灰度图分割前景与背景,经常用到投影法。

2013-12-23 22:20:14 Geng19930909 阅读数 0

     对图像进行操作,不外乎有点运算,代数运算和空间运算等。

     点运算对单幅图像做处理,不改变像素的空间位置。

     代数运算对多幅图像做处理,不改变像素的空间位置。

     空间运算对单幅图像做处理,但是改变像素的空间位置。

     这里我们要讲的是空间运算,常见的空间运算包括平移,缩放,旋转等等。

     常见的几何运算的算法有2个:空间变换算法和灰度级插值算法。

    灰度级插值:

     1)向前映射法:

       通过输入图像像素位置 计算输出图像对应像素位置,

      将该位置像素的灰度值按某种方式分配到输出图像相邻四个像素。

     

    2)向后映射法:

    通过输出图像像素位置 计算输入图像对应像素位置,

    根据输入图像相邻四个像素的灰度值计算该位置像素的灰度值。

    在实际应用中,由于向前映射法需要多次运算才能得到输出图像,所以使用得不如向后映射法常见。

    在这儿我主要讲向后映射法相关的内容:

    1)最近邻插值法

    对于一个像素点做空间运算时,其输出的灰度或像素值等于其最近的像素点的灰度或像素值。

     对于编程来说,对于输出图像点(Xo,Yo)得到做几何运算之后的点(Xi,Yi),那么在原图像中对应的像素点就为(round(Xi),round(Yi))。

     以下是用Python写的最近邻缩放,lvl表示缩放等级也就是缩放的百分比。

    

#最近邻缩放
def singleZoom(lvl):
    h,w = originalImage.size
    opix = originalImage.load()
    nh = int(round(h * lvl , 0))
    nw = int(round(w * lvl , 0))
    singleImage = Image.new('RGB' , (nh,nw))
    npix = singleImage.load()
    for i in range (nh):
        for j in range (nw):
            npix[i,j] = (255,255,255)
    for i in range (nh):
        for j in range (nw):
            x = int(round(i / lvl , 0))
            y = int(round(j / lvl , 0))
            if (x >= h):
                x = h - 1
            if (y >= w):
                y = w - 1
            npix[i,j] = opix[x,y]

     2)双线性插值法:

     由运算后的点(Xi,Yi)相邻的四个点围城一个正方形,这四个点分别有其对应的灰度值或像素值等,从而确定这个点(Xi,Yi)的灰度值或像素值。

     将问题转换一下叙述就是:

     单位正方形顶点值已知,求正方形内任一点的f(x,y)

     求解方法如下:

    所以就得到了结果,可以根据这个公式来求解像素点的灰度值或像素值。

    以下是用Python写的双线性插值缩放,lvl表示缩放等级也就是缩放的百分比。

   

#双线性缩放
def doubleZoom(lvl):
    h,w = originalImage.size
    opix = originalImage.load()
    nh = int(round(h * lvl , 0))
    nw = int(round(w * lvl , 0))
    singleImage = Image.new('RGB' , (nh,nw))
    npix = singleImage.load()
    for i in range (nh):
        for j in range (nw):
            npix[i,j] = (255,255,255)
    for i in range (nh):
        for j in range (nw):
            xx = i / lvl;
            yy = j / lvl;
            x = int(i / lvl)
            y = int(j / lvl)
            xx = xx - x
            yy = yy - y
            if (0 <= x and x < h - 1 and 0 <= y and y < w - 1):
                f00r = opix[x,y][0]
                f00g = opix[x,y][1]
                f00b = opix[x,y][2]
                f01r = opix[x,y + 1][0]
                f01g = opix[x,y + 1][1]
                f01b = opix[x,y + 1][2]
                f10r = opix[x + 1,y][0]
                f10g = opix[x + 1,y][1]
                f10b = opix[x + 1,y][2]
                f11r = opix[x + 1,y + 1][0]
                f11g = opix[x + 1,y + 1][1]
                f11b = opix[x + 1,y + 1][2]
                r = xx * (f10r - f00r) + yy * (f01r - f00r) + (f11r + f00r - f10r - f01r) * xx * yy + f00r
                g = xx * (f10g - f00g) + yy * (f01g - f00g) + (f11g + f00g - f10g - f01g) * xx * yy + f00g
                b = xx * (f10b - f00b) + yy * (f01b - f00b) + (f11b + f00b - f10b - f01b) * xx * yy + f00b
                r = int(round(r , 0))
                g = int(round(g , 0))
                b = int(round(b , 0))
                npix[i,j] = (r,g,b)