[转载] 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培训)
[转载] DSP6000图像位移与变形典型算法的更多相关文章
- 图像滤镜艺术---ZPhotoEngine超级算法库
原文:图像滤镜艺术---ZPhotoEngine超级算法库 一直以来,都有个想法,想要做一个属于自己的图像算法库,这个想法,在经过了几个月的努力之后,终于诞生了,这就是ZPhotoEngine算法库. ...
- 【转载】全网最!详!细!tarjan算法讲解。
转自http://www.cnblogs.com/uncle-lu/p/5876729.html [转载]全网最!详!细!tarjan算法讲解.(已改正一些奥妙重重的小错误^_^) 全网最详细tarj ...
- 转载: scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法
版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...
- 数字图像去噪典型算法及matlab实现
原文地址http://jncumter.blog.51cto.com/812546/243961 图像去噪是数字图像处理中的重要环节和步骤.去噪效果的好坏直接影响到后续的图像处理工作如图像分割.边 ...
- 推荐相关学习 & 典型算法、典型特征、典型推荐系统框架
总的来说,信息爆炸,产生了信息过载.解决的方法主要有两类:检索和推荐.检索是主动的有目的的.意图明确,推荐是非主动的.意图不明确. 推荐方面最经典的,就是协同过滤推荐了.我博客这里有两篇,一篇偏理论, ...
- 转载: scikit-learn学习之K最近邻算法(KNN)
版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...
- 图像处理中kmeans聚类算法C++实现
Kmeans聚类算法是十分常用的聚类算法,给定聚类的数目N,Kmeans会自动在样本数据中寻找N个质心,从而将样本数据分为N个类别.下面简要介绍Kmeans聚类原理,并附上自己写的Kmeans聚类算法 ...
- 【转载】最短路径—Dijkstra算法和Floyd算法
注意:以下代码 只是描述思路,没有测试过!! Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始 ...
- 【转载】用Scikit-Learn构建K-近邻算法,分类MNIST数据集
原帖地址:https://www.jiqizhixin.com/articles/2018-04-03-5 K 近邻算法,简称 K-NN.在如今深度学习盛行的时代,这个经典的机器学习算法经常被轻视.本 ...
随机推荐
- 【题解】P1440 均分纸牌
均分纸牌 题目描述: 有\(N\)堆纸牌,编号分别为\(1,2,-,N\).每堆上有若干张,但纸牌总数必为\(N\)的倍数.可以在任一堆上取若干张纸牌,然后移动. 移牌规则为:在编号为\(1\)堆上取 ...
- LTE基本架构
1.LTE结构 这是一张非常有名的LTE架构图,从图中可以看出,整个网络构架被分为了四个部分: (1)UE就可以看作是我们的手机终端 (2)PDN可以看作是网络上的服务器 (3)E-UTRAN可以看 ...
- day3:python测试题
1.Python的怎么单行注释和多行注释: 单行注释:# 多行注释: ''' ''' 或者 “”“ ”“” . 2.布尔值分别是什么 ? True /Fa ...
- nginx下Thinkphp 隐藏index.php
thinkphp config配置: 'URL_MODEL' => '2', //URL模式 nginx rewrite配置: location / { if (!-e $request_fil ...
- Java 10的10个新特性,将彻底改变你写代码的方式!
Java 9才发布几个月,很多玩意都没整明白,现在Java 10又快要来了.. 这时候我真尼玛想说:线上用的JDK 7 甚至JDK 6,JDK 8 还没用熟,JDK 9 才发布不久不知道啥玩意,JDK ...
- 关于ueditor 文本框
遇到一个问题,需要将从ueditor中的获得的带格式的文本,从数据库中取出,在放回到 ueditor中去,但是 文本中\n总是截断字符串,出现 这种情况,后面的字符就不能算到里面去了,程序就报错了. ...
- springcloud系列15 bus的使用
可以结合wekbbok进行通知: 将更新的代码进行点击就好:
- sqlite获取表字段
sqlite下能通过sqlite_master获取指定数据库的表信息和表结构 但是通过sqlite_master不能获取表字段的信息 如果需要获取指定表字段的所有信息 可以使用如下语法: PRAGMA ...
- C++ 系列:typedef 和 #define 的区别
总结一下typedef和#define的区别 1.概念 #define 它在编译预处理时进行简单的替换,不作正确性检查.它是预处理指令. typedef 它在自己的作用域内给一个已经存在的类型一个别名 ...
- uoj33 树上GCD
题意:给你一棵树,根节点为1,每条边长度为1.定义f(u,v)=gcd(u-lca(u,v),lca(u,v)-v),求有多少个无序点对f(u,v)=i.对每个i输出答案. n<=20W. 标程 ...