数字图像处理在DSP上的实现.docx
《数字图像处理在DSP上的实现.docx》由会员分享,可在线阅读,更多相关《数字图像处理在DSP上的实现.docx(15页珍藏版)》请在冰豆网上搜索。
数字图像处理在DSP上的实现
数字图像处理在DSP上的实现(旋转)
1绪论
1.1设计目的
图像旋转是一种应用广泛的数字图像处理技术,随着应用水平的不断提高,对在嵌入式系统中实现高分辨率大图像旋转的需求也越来越高。
如在航空领域的高分辨率数字地图图像的显示处理过程中,由于现有的显示芯片均不能支持图像旋转功能,就需要在资源有限的嵌入式平台上实现大幅面地图图像的实时旋转。
采用DSP平台是一种实现方式,具体实现时需仔细考虑两个方面的问题,一是选用计算量小的旋转算法,二是充分发挥DSP平台强大的并行计算能力。
1.2设计任务
1.能从计算机上读取图片。
2.编写图像旋转程序,在TMS320C5509上实现。
2设计原理及分析
2.1设计原理
目前,已经有很多有效降低计算量的图像旋转算法,基于图像线性存储结构的旋转方法就是其中之一。
然而,在DSP平台上,有限的高速存储资源限制了这些算法效率的直接发挥,需要针对算法及DSP平台的性能结构特点进行高效的数据调度。
对于图像旋转问题而言,数据调度还需要克服由于存在大量非连续图像像素地址访问而严重影响DSP数据存取及CPU效率发挥的问题。
这是图像旋转本身的特殊性,在其他图像处理技术中是不存在的。
由DSP的结构特点可知,只有在数据和程序均位于片内存储器当中的条件下,DSP的效率才能得到最大化的发挥。
在大图像旋转算法中,由于涉及的图像数据量远大于DSP的片内存储器容量,源图像和最终视口图像等数据必须被存放在片外存储器中。
在这种情况下,为了保证DSPCPU高速处理能力的发挥,必须优化数据流,将源图像分块,依次搬移至片内处理,并设法保证CPU当前要处理的图像数据块已经事先在片内存储器中准备好了。
因此在算法整体优化结构上采用Ping-Pong双缓冲技术,利用EDMA与CPU并行工作来隐藏图像数据块在片内和片外之间的传输时间,使CPU能连续不断地处理数据,中间不会出现空闲等待。
传统的图像旋转一般通过矩阵乘法实现:
其中,α为旋转角度。
由于图像是线性存储的,各个像素点之间的相对位置关系确定。
如图1(a)所示,图像旋转前,任意像素点P(x,y)和P1(x1,y1)、P2(x2,y2)及A(xA,yA)在几何上是矩形的四顶点关系。
由于旋转变换是线性变换,如图1(b)所示,图像旋转后,各个像素点之间的相对位置关系不发生变化,
旋转算法的数据调度目的是使算法能够按照一定的规则,将源图像数据有规律地分块,并按次序分别传输到DSP片内存储器中,完成计算后,形成视口图像块,再将视口图像块按同样的顺序进行排列,形成旋转后的视口图像。
整个过程要求调入和调出的图像数据均是规则分块的,并且调入的源图像块中应该包含计算视口图像块的过程中所需要的全部像素数据,尤其需要解决其中的大量非连续图像像素地址访问问题。
视口逆时针旋转的情况与此类似。
区别有以下两点:
1源图像块的左边框中点与相应的视口图像块旋转后的左上角顶点对应;
②源图像块的顶点局部坐标地址值与视口图像块的顶点局部坐标地址值之间的对应关系式应为:
其中height指源图像块的高度。
3软件程序
3.1主程序
#include
#include
#include
#include
#include
intload_cut(char*fname);
intload_convolution_matrix(char*fname);
intconvolve_image(void);
intswap_pictures(void);
intminx,maxx,miny,maxy;
intLOADPAGE=0;
intENHANCEPAGE=1;
int*cmat,*pmat,*vmat;
intcmx,cmy,cmnum;
structpalettetypepalette,newpal;
intdriver,mode;
intcleancut=-1;
intinit_graphics(void)
{
driver=DETECT;mode=0;
detectgraph(&driver,&mode);
if(driver==VGA)mode=VGAMED;
initgraph(&driver,&mode,"");
getpalette(&palette);
getpalette(&newpal);
}
intcleanup_image(void)
{
inti,j,num,x,y,k;
if(cleancut<0)return;
setactivepage(LOADPAGE);
setvisualpage(ENHANCEPAGE);
for(x=minx;xfor(y=miny;yif(getpixel(x,y)!
=0)num=-1;
elsenum=0;
for(j=-1;j<2;j++){
for(i=-1;i<2;i++){
if(getpixel(x+i,y+j)!
=0)num++;
}
}
if(num>cleancut){
k=getpixel(x,y);
setactivepage(ENHANCEPAGE);
putpixel(x,y,k);
setactivepage(LOADPAGE);
}
}
}
k=ENHANCEPAGE;ENHANCEPAGE=LOADPAGE;LOADPAGE=k;
}
voidshow_test_image(void)
{
inti;
minx=cmx;miny=cmy;
maxx=100+minx;maxy=100+miny;
setcolor
(1);
moveto(minx,miny);
randomize();
for(i=0;i<20;i++)
lineto(random(100)+minx,random(100)+miny);
for(i=0;i<10;i++)
fillellipse(random(50)+25+minx,random(50)+25+miny,random(25),random(25));
}
main()
{
charfname[50];
intflag=0;
load_convolution_matrix("matrix.dat");
printf(".CUTfile
(1)ortestimage(0)?
");
scanf("%d",&flag);
flag=flag?
1:
0;
if(flag){
fflush(stdin);
printf("filenametoprocess:
");
gets(fname);
}
printf("Deletepixelswithxorfewerneighbors.x=");
scanf("%d",&cleancut);
if(cleancut>8)cleancut=8;
init_graphics();
setactivepage
(1);cleardevice();
setactivepage(0);cleardevice();
setactivepage(LOADPAGE);setvisualpage(LOADPAGE);
if(flag)load_cut(fname);
elseshow_test_image();
cleanup_image();
setvisualpage(ENHANCEPAGE);
convolve_image();
swap_pictures();
restorecrtmode();
}
inttoggle_colors(charc)
{
c=tolower(c);
c=c-'a';
if(c<0||c>=palette.size)return0;
newpal.colors[c]=palette.colors[c]-newpal.colors[c];
setpalette(c,newpal.colors[c]);
return1;
}
intswap_pictures(void)
{
intmode=0;
chara;
setvisualpage(LOADPAGE);
for(;;){
a=getch();
if(a==27)return;
if(toggle_colors(a))continue;
if(mode==0)setvisualpage(ENHANCEPAGE);
if(mode==1)setvisualpage(LOADPAGE);
mode=1-mode;
}
}
intconvolve_image(void)
{
inti,j,k,nval;
int*vx,*vy,*c;
intcolmax,offset,end,midy;
char**lines=NULL;
char*temp=NULL;
offset=-minx+(cmx/2);
end=cmy-1;midy=cmy/2;
lines=(char**)malloc(cmy*sizeof(char*));
for(i=0;isetactivepage(LOADPAGE);
for(j=-cmy/2;jfor(i=minx-cmx/2;i<(maxx+cmx/2+1);i++){
lines[j+midy][i+offset]=getpixel(i,j+miny);
}
}
colmax=getmaxcolor();
for(j=miny;jsetactivepage(LOADPAGE);
for(i=j+cmy/2,k=minx-cmx/2,nval=maxx+cmx/2;klines[end][k+offset]=getpixel(k,i);
for(i=minx;i/*Load&multiplyneighborsintomatrix*/
setactivepage(LOADPAGE);
vx=vmat;vy=vmat+1;c=cmat;nval=0;
for(k=0;kif(*c)nval+=lines[(*vy)+midy][i+(*vx)+offset]*(*c);
/*if(*c)nval+=getpixel(i+(*vx),j+(*vy))*(*c);*/
c++;
vx+=2;vy+=2;
}
/*Cutoffvaluestoohighortoolow*/
if(nval<0)nval=0;
if(nval>colmax)nval=colmax;
/*Placenewpixelvalue*/
setactivepage(ENHANCEPAGE);
putpixel(i,j,nval);
}
if(kbhit()){getch();break;}
/*rotatelinepointers*/
temp=lines[0];
for(i=1;ilines[end]=temp;
}
for(i=0;iif(lines[i]!
=NULL)free(lines[i]);
}
if(lines!
=NULL){
free(lines);
}
return;
}
intbuild_offset_vectors(void)
{
int*t;
intil,im,jl,jm,i,j;
il=-cmx/2;im=cmx+il;
jl=-cmy/2;jm=cmy+jl;
t=vmat;
for(j=jl;jfor(i=il;i*t++=i;*t++=j;
}
}
}
intload_convolution_matrix(char*fname)
{
/*Layoutofmatrixfile:
#x#y
x0y0x1y0...xny1
...............
x0ymx1ym...xnym
*/
FILE*mf;
int*t;
inti,j,im,jm;
if((mf=fopen(fname,"rt"))==NULL){
printf("Cannotloadmatrixfile.\n");
abort();
}
fscanf(mf,"%d%d",&im,&jm);
if((im&1)==0||(jm&1)==0){
printf("ConvolutionmatrixMUSThaveacenterpoint.\n");
abort();
}
if((cmat=(int*)calloc(im*jm,sizeof(int)))==NULL){
printf("Unabletocallocconvolutionmatrix.\n");
abort();
}
if((vmat=(int*)calloc(2*im*jm,sizeof(int)))==NULL){
printf("Unabletocallocoffsetvectormatrix.\n");
abort();
}
cmx=im;cmy=jm;cmnum=im*jm;
t=cmat;
for(j=0;jfor(i=0;iif(fscanf(mf,"%d",t++)!
=1){
printf("Unabletoreadmatrix.\n");
abort();
}
}
}
fclose(mf);
build_offset_vectors();
}
intload_cut(char*fname)
{
staticunsignedcharst[3000];
char*sp=st,*spend;
intstp=0;
intwidth,height;
FILE*fp;
intx,y,xl,yl;
inti,n,len,d,j;
fp=fopen(fname,"rb");
width=getw(fp);height=getw(fp);
xl=cmx;yl=cmy;
minx=xl;miny=yl;
maxx=xl+width;maxy=yl+height;
if(maxy>(getmaxy()-cmy)){
maxy=getmaxy()-cmy;
height=maxy-yl;
}
getw(fp);
y=yl-1;
for(sp=st,n=0;nstp=getw(fp);
for(sp=st,spend=st+stp;spsp=st;spend=sp+stp;x=xl;y++;
while(spif(*((unsignedchar*)sp)>0x80){
len=(*sp++)&0x7f;
if(!
(*sp)){x+=len;continue;}
setcolor(*sp++);
moveto(x,y);
linerel(len,0);
x+=len;
continue;
}else{
len=*sp++;
for(j=0;jcontinue;
}
}
}
fclose(fp);}
3.2初始化和读取图像程序
#include
#defineMODEPHOTO11
#defineMODEPHOTO22
#defineGRAYBARLEVEL16
voidReadImage(unsignedchar*pImage,char*cFileName,intnWidth,intnHeight);
voidInitImage(unsignedintnMode,unsignedchar*pImage,intnWidth,intnHeight)
{
swich(nMode)
{
caseMODEPHOTO1:
Readimage(pImage,"..\\DSP.bmp",nWidth,nHeight);
break;
caseMODEPHOTO2:
ReadImage(pImage,"..\\1.bmp",nWidth,nHeight);
break;
default:
break;
}
}
voidReadImage(unsignedchar*cFileName,intnWidth,intnHeight)
{
intj;
unsignedchar*pWork;
FILE*fp;
if(fp=fopen(cFileName,"rb"))
{
fseek(fp,1078L,SEEK_SET);
pWork=pImage+(nHeight-1)*nWidth;
for(j=0;jfread(pWork,nWidth,1,fp);
fclose(fp);
}
}
4运行结果分析
从实验结果可以看出,调整图像旋转,由于存在对称性,一幅图像任意角度的旋转可分解为一次90°或180°或270°的旋转,再加上一次±45°以内的旋转。
图4.1原图
图4.2顺时针旋转90度
图4.3逆时针旋转90度
结论
本文得到的结论如下:
实验采用高分辨率图像处理平台,以TMS320C5509芯片为主处理芯片,时钟为300MHz,片外为16MBSDRAM。
实验实现相应尺寸(80×80像素)的视口图像旋转,相应的源图像数据分别为80×80像素的BMP格式的数字地图图像,采用0.005弧度旋转角度递增间隔,对分别采用传统像素逐点矩阵相乘方法、基于图像线性存储结构方法以及基于本文数据调度策略的结构优化的线性存储结构方法三种实现方式进行对比,分别统计其平均每帧运行时间并转换成帧率,达到了本次课程设计的要求。
参考文献
[1]DANIELSSONPE.High-AccuracyRotationofImages[J].GraphicalModelsandImageProcessing,2002
[2]方华刚.DSP原理与应用.北京.北京机械工业出版社,2006.1
[3]朱虹.数字图像处理.北京.科学出版社,2007.4
[4]孙宗瀛.TMS320C55XDSP原理设计与应用.北京.清华大学出版社,2002
[5]郑红吴冠.TMS320C55XDSP应用系统设计.北京.北京航空航天大学出版社,2002
[6]TMS320C55XDSPProgrammer’sGuideSPRU376A[Z].TexasInstruments,2001
致谢
通过本次课程设计,加强了我们动手、思考和解决问题的能力,我觉得做课程设计同时也是对课本知识的巩固和加强,由于课本上的知识太多,平时课间的学习并不能很好的理解所学的知识。
而这次课程设计使我对于其在DSP中的使用有了更多的认识。
平时看课本时,有时问题老是弄不懂,做完课程设计,那些问题就迎刃而解了。
而且还可以记住很多东西。
这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为我所用。
在设计实验过程中,我也遇到过很多困难,通过同学们和老师的帮助最终解决了问题才得以完成课程设计,在这里对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!
课程设计(论文)评语及成绩评定
指导教师评语:
评分_______指导教师(签字)_______________________年____月____日
课程设计(论文)及答辩评分:
1.学生工作态度和平时表现(共20分)__________;
2.论文格式规范、语言流畅(共20分)__________;
3.数据完整、分析论述充分合理,结论正确(共20分)__________;
4.答辩表述能力(共20分)__________;
5.基本概念及回答问题情况(共20分)_________。
课程设计总成绩______答辩组成员(签字)_________________年___月__日