• 图像平移


       图像平移非常简单,如图所示,初始坐标为(x0,y0)的点经过平移(tx,ty)后坐标变为(x1,y1)。这两点之间的关系是x1=x0+ty1=y0+ty

        以矩阵的形式表示为

                    

        它的逆变换为:



         平移变换的实现很简单,可以先新建一个与原图像一样大小的新图像,填充背景色。对于新图像中的每一个像素点(x1,y1),根据逆变换公式算出在原图像中的对应坐标(x0,y0),如果(x0,y0)不在原图像范围内,则把(x1,y1)对应的像素值设置为背景色;若(x0,y0)在原图像范围内,则把(x0,y0)的像素值赋给(x1,y1)。因此程序实现的时候,只需要遍历所有像素依次判断即可。

        下面从另一个角度来思考,以x方向的平移为例:

          设 图像宽width, 高height

        (1)当tx>0时,图像向右平移,平移后目标区域左下角横坐标为 xstart=tx, 对应于源图像的x0=0; 右上角横坐标 xend=width-1,对应源图像 x1=(width-1)-th ;

        (2)当tx<0时,图像向左平移,平移后目标区域左下角横坐标为 xstart=0, 对应于源图像的x0= - tx; 右上角横坐标 xend= (width-1)+tx,对应源图像 x1=width-1 ;

          y方向同理可得。    

        (3)然后把原图像中由(x0,y0)→(x1,y1)确定的区域copy到新图像中由(xstart, ystart) → (xend, yend) 确定的区域。

          C代码如下:

    /*
    * translate.cpp
    * 实现图像的平移
    * Created on: 2011-10-9
    * Author: LiChanghai
    */
    // 设定平移不改变图像的大小,平移出去的部分截掉
    // 平移后的背景设为0(黑色),图像宽width, 高height
    // 设平移向量为t=(tx, ty),由于当|tx|≥width 或 |ty|≥height 时
    // 图像完全平移出原来区域,只剩背景色,因此这里假定
    // |tx|≤width 且 |ty|≤height
    // 设平移后目标区域的左下角坐标为(xstart, ystart)
    // 对应于原图像的坐标为(x0, y0)
    // 目标区域右上角坐标为(xend, yend)(程序里不需要定义出来)
    // 对应于原图像的坐标为 (x1, y1)
    #include <string.h>
    bool translate(unsigned char *pImage, int width, int height, int biBitCount, int tx, int ty)
    {
    //定义相关变量
    int xstart, x0, x1, ystart, y0, y1, i;

    //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
    int lineByte=(width * biBitCount/8+3)/4*4;

    //申请新的位图数据存储空间, 并拷贝原图像
    unsigned char *pImage2;
    pImage2=new unsigned char[lineByte*height];
    memcpy(pImage2, pImage, lineByte*height);

    //将原图像设置为背景色
    memset(pImage, 0, lineByte*height);

    //确定平移前后的坐标关系
    if(tx>0)
    {
    xstart=tx; x0=0;
    x1=(width-1)-tx;
    }
    else
    {
    xstart=0; x0=-tx;
    x1=width-1;
    }

    if(ty>0)
    {
    ystart=ty; y0=0;
    y1=(height-1)-ty;
    }
    else
    {
    ystart=0; y0=-ty;
    y1=height-1;
    }

    // copy数据
    for(i=0; i<y1-y0+1; i++) //需要复制 y1-y0+1行
    memcpy(pImage+(ystart+i)*lineByte+xstart, pImage2+(y0+i)*lineByte+x0, x1-x0+1);

    return 1;
    }


           这种方式不用遍历每一个像素,因此运算量小。该程序在Eclipse上调试通过。




  • 相关阅读:
    获取jsonPath的节点名称
    如何删除 macOS High Sierra 上的 swapfile
    Prototype fake it till make it.观后感
    intellij idea 初步环境熟悉
    一个比较综合的项目--》>图片缓存,下拉刷新等
    写的很好的博客->有关性能优化、图片缓存等
    layout优化之-》viewStub,requestFocus,merge,include
    有关ActionBar
    android:installLocation 解析
    Android开发效率—Eclipse快捷键
  • 原文地址:https://www.cnblogs.com/haigege/p/2203822.html
Copyright © 2020-2023  润新知