• [转载] DSP6000图像位移与变形典型算法


     

    李现路: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培训)

  • 相关阅读:
    在Ubuntu/Centos使用 Let's Encrypt 证书部署 HTTPS的方法
    Ubuntu14.04安装配置LAMP环境(php5.6)
    centos6 php5.4 升級到php 5.6
    为自己的2017年定个计划
    收益的一些话
    学习瓦力部署系统的项目配置和上线部署
    统计进仓和出仓数量随时间变化的剩余数量流程图
    Codeigniter 获取当前的控制器名称和方法名称
    [记]Windows 系统下设置Nodejs NPM全局路径
    [记]Cordova安装插件选择插件版本
  • 原文地址:https://www.cnblogs.com/eaglediao/p/7136547.html
Copyright © 2020-2023  润新知