李现路:DSP6000图像位移与变形典型算法
一、图像的平移算法
图像平移的数学表达式原理:
初始坐标为(x0,y0)的点经过平移(tx,ty)(以向右,向下为正方向)后,坐标变为(x1,y1)。这两点之间的关系是x1=x0+tx,y1=y0+ty。
这样,平移后的图像上的每一点都可以在原图像中找到对应的点。例如,对于新图中的(0,0)像素,代入上面的议程组,可以求出对应原图中的点,可以直接将它的像素值同意设置为0或者255(对于灰度图就是黑色或白色)。
同样,若有点不在原图中,也就说明原图中有点被移出显示区域。如果不想丢失被移出的部分图像,可以将新生成的图像扩大tx,高度扩大ty。
平移处理的C语言代码:

Int intXOffset=-200; //水平偏移量
Int intYOffset=-200; //垂直偏移量,必须是2的整数
void geometryTrans()
{
    inti,j;
    intintCapX,intCapY;
   for(i=0;i<numLines;i++) //行数
    {
       for(j=0;j<numPixels;j++) //像素数 /每行
       {                
           intCapX = j-intXOffset;
           intCapY =i-intYOffset/2;            
           // 判断 是否在原图范围内
           if((intCapX>=0) &&(intCapX<numPixels))  
           {  
               //奇数行
               if((i<numLines/2) &&(intCapY>=0) &&(intCapY<numLines/2))
               {
                   // 传送亮度信号
                   *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +(i-intYOffset/2)*numPixels +intCapX);  
               }
               //偶数行
               else if((i>=numLines/2)&& (i<numLines)&&(intCapY>=numLines/2)&&(intCapY<numLines))
               {
                    // 传送亮度信号
                   *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +(i-intYOffset/2)*numPixels +intCapX);                
               }
               else
               {
                   *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0xFF;
               }                                                                            
           }
           else
           {
                *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0xFF;
           }                                  
       }    
    }
}    
二、图像的垂直镜像变换算法
数学表达式原理:
设图像高度为IHeight,宽度为IWidth,原图中(x0,y0)垂直镜像后将变为(x0,
IHeight-y0),其表达式为:
设图像高度为IHeight,宽度为IWidth,原图中(x0,y0)垂直镜像后将变为(x0,
IHeight-y0),其表达式为:
X0=x1; y0=IHeight-y1
算法的C语言代码:
    portNumber =0;
    vpHchannel0= bt656_8bit_ncfc(portNumber);
   bt656_capture_start(vpHchannel0);
   
   while(capNewFrame == 0){}
   
    capNewFrame=0;
   for(i=0;i<numLines;i++)
    {
          
          //前半部分为原始图像
       DAT_copy((void *)(capYbuffer + i * numPixels),
                (void *)(disYbuffer + i * numPixels),
                numPixels>>1);
       //后半部分为垂直镜像图像
       DAT_copy((void *)(capYbuffer + i * numPixels),
        (void *)(disYbuffer + (numPixels>>1)+ (numLines-1-i) * numPixels),
        numPixels>>1);
       
       //前半部分为原始图像
       DAT_copy((void *)(capCbbuffer + i * (numPixels>> 1)),
                (void *)(disCbbuffer + i * (numPixels>> 1)),
                numPixels>>2);
       //后半部分为垂直镜像图像
       DAT_copy((void *)(capCbbuffer + i * (numPixels>> 1)),
                (void *)(disCbbuffer + (numPixels>>2)+ (numLines-1-i) * (numPixels >>1)),
                numPixels>>2);                        
       
       //前半部分为原始图像
       DAT_copy((void *)(capCrbuffer + i * (numPixels>> 1)),
                (void *)(disCrbuffer + i * (numPixels>> 1)),
                numPixels>>2);
       //后半部分为垂直镜像图像        
       DAT_copy((void *)(capCrbuffer + i * (numPixels>> 1)),
                (void *)(disCrbuffer + (numPixels>>2)+ (numLines-1-i) * (numPixels >>1)),
                numPixels>>2);            
    }    
   
   bt656_display_start(vpHchannel1);
   
   for(;;)
    {
       
       if((capNewFrame == 1)&&(disNewFrame== 1))
       {
           
           capNewFrame =0;
           disNewFrame =0;
           for(i=0;i<numLines;i++)
           {
                  
                  //前半部分为原始图像
               DAT_copy((void *)(capYbuffer + i * numPixels),
                        (void *)(disYbuffer + i * numPixels),
                        numPixels>>1);
               //后半部分为垂直镜像图像
               DAT_copy((void *)(capYbuffer + i * numPixels),
                (void *)(disYbuffer + (numPixels>>1)+ (numLines-1-i) * numPixels),
                numPixels>>1);
               
               //前半部分为原始图像
               DAT_copy((void *)(capCbbuffer + i * (numPixels>> 1)),
                        (void *)(disCbbuffer + i * (numPixels>> 1)),
                        numPixels>>2);
               //后半部分为垂直镜像图像
               DAT_copy((void *)(capCbbuffer + i * (numPixels>> 1)),
                        (void *)(disCbbuffer + (numPixels>>2)+ (numLines-1-i) * (numPixels >>1)),
                        numPixels>>2);                        
               
               //前半部分为原始图像
               DAT_copy((void *)(capCrbuffer + i * (numPixels>> 1)),
                        (void *)(disCrbuffer + i * (numPixels>> 1)),
                        numPixels>>2);
               //后半部分为垂直镜像图像        
               DAT_copy((void *)(capCrbuffer + i * (numPixels>> 1)),
                        (void *)(disCrbuffer + (numPixels>>2)+ (numLines-1-i) * (numPixels >>1)),
                        numPixels>>2);            
            }
       }
   }    
}
三、图像的水平镜像变换算法
数学表达式原理:
设图像高度为IHeight,宽度为IWidth,原图中(x0,y0)经过水平镜像后从未将变为
(IWidth-x0,y0),其表达式为:
X0=IWidth-y1; y0=y1
算法的C语言代码:

void horizTranspose()
{
    inti,j;
   for(i=0;i<numLines;i++)
   {          
          
          //传送临时Y缓冲区
       DAT_copy((void *)(capYbuffer + i * numPixels),
                (void *)(tempYbuffer + i * numPixels),
                numPixels>>1);                                    
       //传送临时Cb缓冲区
       DAT_copy((void *)(capCbbuffer + i * (numPixels>> 1)),
                (void *)(tempCbbuffer + i * (numPixels>> 1)),
                numPixels>>2);        
       //传送临时Cr缓冲区
       DAT_copy((void *)(capCrbuffer + i * (numPixels>> 1)),
                (void *)(tempCrbuffer + i * (numPixels>> 1)),
                numPixels>>2);                                                          
       
       for(j=numPixels/2;j<numPixels;j++)
       {
           //传送临时Y缓冲区        
           *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +i*numPixels +numPixels-1-j);        
       }
       for(j=(numPixels>>2);j<(numPixels>>1);j++)
       {
           //传送临时Cb缓冲区
           *(Uint8 *)(tempCbbuffer +i*(numPixels>>1) + j) = *(Uint8*)(capCbbuffer + i*(numPixels>>1) +(numPixels>>1)-1-j);        
           //传送临时Cr缓冲区
           *(Uint8 *)(tempCrbuffer +i*(numPixels>>1) + j) = *(Uint8*)(capCrbuffer + i*(numPixels>>1) +(numPixels>>1)-1-j);        
       }
    }
}
四、图像的缩放算法
数学表达式原理:
假设图像x轴方向缩放比率fx,y轴方向缩放比率是fy,那么原图中点(x0,y0)对应
于新图中的点(x1,y1)的转换表达式为:
X0=x1/fx; y0=y1/fy
算法的C语言代码:

Float fXZoomRatio=0.5; //水平缩放比率
Float fYZoomRatio=0.5; //垂直缩放比率

void zoom()
{
    inti,j;
    intintCapX,intCapY;
   for(i=0;i<numLines;i++)
    {
       for(j=0;j<numPixels;j++)
       {                
           intCapX = (int)(j/fYZoomRatio+0.5);
           intCapY =(int)(i/fXZoomRatio+0.5);          
           //判断是否在原图范围内
           if((intCapX>=0) &&(intCapX<numPixels))  
           {  
               if((i<numLines/2) &&(intCapY>=0) &&(intCapY<numLines/2))
               {
                   //传送亮度信号
                   *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +intCapY*numPixels +intCapX);  
               }
               else if((i>=numLines/2)&& (i<numLines)&&(intCapY>=numLines/2)&&(intCapY<numLines))
               {
                    //传送亮度信号
                   *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +intCapY*numPixels +intCapX);                
               }
               else
               {
                   *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0xFF;
               }                                                                            
           }
           else
           {
                *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0xFF;
           }                                  
       }    
    }
}
五、图像的旋转实验
数学表达式原理:
下面我们来推导一下旋转运算的变换公式。如下图所示,点(x0,y0)经过旋转θ度后
坐标变成(x1,y1)。其数学表达式为:
X0=x1cos(θ)+y1sin(θ)+ccos(θ)-dsin(θ)+a ;
Y0=-xsin(θ)+y1cos(θ)+csin(θ)-dcos(θ)+ b
算法的C语言代码:

Float fAngle=3.1415927/3; //旋转的角度
*画矩形边框函数*/
Void drawRectangle();
*计算图像旋转参数*/
Void computeParameter();

void rotate()
{
    inti,j,intInc;
    intintCapYInc;
    intintCapX,intCapY;
   
   //方框内奇数行
   for(i=intALines;i<intDLines;i++)
    {
       for(j=intAPixels;j<intDPixels;j++)
       {
           intInc = i*2;  
           intCapX    =(int)(j*cosAngle + intInc*sinAngle + f1 + 0.5);
           intCapYInc = (int)(intInc*cosAngle - j*sinAngle + f1 +0.5);          
           if((intCapYInc%2)==0)
           {
               intCapY = intCapYInc/2;
           }
           else
           {
               intCapY = (intCapYInc-1)/2+numLines/2;
           }
           //判断是否在原图范围内
           if((intCapX>=0) &&(intCapX<numPixels)&& (intCapY>=0)&&(intCapY<numLines))  
           {
               //传送亮度信号
               *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +intCapY*numPixels +intCapX);                                                                        
           }
           else
           {
                *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0xFF;
           }
       }    
    }
   //方框内偶数行
   for(i=numLines/2+intALines;i<numLines/2+intDLines;i++)
    {
       for(j=intAPixels;j<intDPixels;j++)
       {        
           intInc = (i-numLines/2)*2 + 1;
           intCapX    =(int)(j*cosAngle + intInc*sinAngle + f1 + 0.5);
           intCapYInc = (int)(intInc*cosAngle - j*sinAngle + f1 +0.5);          
           if((intCapYInc%2)==0)
           {
               intCapY = intCapYInc/2;
           }
           else
           {
               intCapY = (intCapYInc-1)/2+numLines/2;
           }            
           //判断是否在原图范围内
           if((intCapX>=0) &&(intCapX<numPixels)&& (intCapY>=0)&&(intCapY<numLines))  
           {
               //传送亮度信号
               *(Uint8 *)(tempYbuffer + i*numPixels + j) = *(Uint8 *)(capYbuffer +intCapY*numPixels +intCapX);                                                                        
           }
           else
           {
                *(Uint8 *)(tempYbuffer + i*numPixels + j) = 0xFF;
           }
       }    
   }    
}
完整版本请见http://www.51qianru.cn/bbs/
                                             曙海教育
                                           曙海嵌入式学院
                       (课程:DSP培训,FPGA培训,MTK培训,Android培训,iPhone培训)

[转载] DSP6000图像位移与变形典型算法的更多相关文章

  1. 图像滤镜艺术---ZPhotoEngine超级算法库

    原文:图像滤镜艺术---ZPhotoEngine超级算法库 一直以来,都有个想法,想要做一个属于自己的图像算法库,这个想法,在经过了几个月的努力之后,终于诞生了,这就是ZPhotoEngine算法库. ...

  2. 【转载】全网最!详!细!tarjan算法讲解。

    转自http://www.cnblogs.com/uncle-lu/p/5876729.html [转载]全网最!详!细!tarjan算法讲解.(已改正一些奥妙重重的小错误^_^) 全网最详细tarj ...

  3. 转载: scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法

    版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...

  4. 数字图像去噪典型算法及matlab实现

    原文地址http://jncumter.blog.51cto.com/812546/243961   图像去噪是数字图像处理中的重要环节和步骤.去噪效果的好坏直接影响到后续的图像处理工作如图像分割.边 ...

  5. 推荐相关学习 & 典型算法、典型特征、典型推荐系统框架

    总的来说,信息爆炸,产生了信息过载.解决的方法主要有两类:检索和推荐.检索是主动的有目的的.意图明确,推荐是非主动的.意图不明确. 推荐方面最经典的,就是协同过滤推荐了.我博客这里有两篇,一篇偏理论, ...

  6. 转载: scikit-learn学习之K最近邻算法(KNN)

    版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...

  7. 图像处理中kmeans聚类算法C++实现

    Kmeans聚类算法是十分常用的聚类算法,给定聚类的数目N,Kmeans会自动在样本数据中寻找N个质心,从而将样本数据分为N个类别.下面简要介绍Kmeans聚类原理,并附上自己写的Kmeans聚类算法 ...

  8. 【转载】最短路径—Dijkstra算法和Floyd算法

    注意:以下代码 只是描述思路,没有测试过!! Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始 ...

  9. 【转载】用Scikit-Learn构建K-近邻算法,分类MNIST数据集

    原帖地址:https://www.jiqizhixin.com/articles/2018-04-03-5 K 近邻算法,简称 K-NN.在如今深度学习盛行的时代,这个经典的机器学习算法经常被轻视.本 ...

随机推荐

  1. python的基本数据类型与字符串的操作

    一.基本数据类型 (int, bool, str ) int: 整数 str:字符串,一般不存放大量的数据 bool:布尔值,用来判断.True ,Flase list:列表,用来存放大量的数据. [ ...

  2. 4_8.springboot2.x嵌入式servlet容器启动原理解析

    问题描述: 什么时候创建嵌入式的Servlet容器工厂? 什么时候获取嵌入式的Servlet容器并启动Tomcat? *获取嵌入式的Servlet容器工厂: 1).SpringBoot应用启动运行ru ...

  3. java笔试之参数解析(正则匹配)

    在命令行输入如下命令: xcopy /s c:\ d:\, 各个参数如下: 参数1:命令字xcopy 参数2:字符串/s 参数3:字符串c:\ 参数4: 字符串d:\ 请编写一个参数解析程序,实现将命 ...

  4. (转)线程池 ExecutorService 详细介绍以及注意点区别

    线程池 ExecutorService 相信java开发都用到,这里做个简单笔记 一 Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池 ...

  5. SPOJ10707 COT2-Count on a tree II

    COT2 - Count on a tree II 中文题意 离线询问一颗树上路径(u,v)中经过所有点的权值的种类数. 题解 树上莫队.即在树的欧拉序列上进行莫队.同一个点加第一次时增加,第二次时减 ...

  6. 74CMS漏洞打包(从老博客转)

    引子 这套CMS是上个月中做的审计,总共找到几个后台漏洞,可后台getshell,一个逻辑漏洞可任意发短信,还有一个前台注入漏洞.不过发到了某平台上之后,审核又要求我提交利用的poc,所以懒得发去了, ...

  7. vue中使用动画vue-particles实现背景粒子酷炫效果

    先来看我做的效果 我这个是用的背景色加上这个粒子效果实现的demo 平时我们做项目的话会添加背景图片这些,可能更加好看 看我的实现步骤 cnpm install -g vue-cli vue init ...

  8. Android 开发 MediaRecorder音频录制

    前言 MediaRecorder类是Android sdk提供的一个专门用于音视频录制,一般利用手机麦克风采集音频和摄像头采集图像.这个类是属于简单的音频录制类,录制音频简单容易但是对音频流的控制也比 ...

  9. drupal-note2 drush运行make文件

    进入durpal项目的根目录中执行 drush make build-openpublic.make /path/to/webroot 参考: Managing Drush make files fo ...

  10. shell脚本使用需要注意的地方

    shell脚本中,函数内部定义变量可以为局部变量和全局变量,局部变量使用local定义,全局变量不带local,全局变量可以在函数外部可见,如下: #!/bin/bash function calle ...