Linux下的放大镜的设计与实现.docx
- 文档编号:5361629
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:11
- 大小:24.27KB
Linux下的放大镜的设计与实现.docx
《Linux下的放大镜的设计与实现.docx》由会员分享,可在线阅读,更多相关《Linux下的放大镜的设计与实现.docx(11页珍藏版)》请在冰豆网上搜索。
Linux下的放大镜的设计与实现
Linux下的放大镜的设计与实现
摘要
本论文旨在设计一个在Linux系统下使用的放大镜应用程序。
阐述了Linux系统的发展历史,Linux系统的重要作用以及其应用领域。
介绍了Linux下的应用软件开发工具Qt,及基于面向对象语言C++,容易扩展,允许组件编程。
本文分三个模块:
图像数据采集模块,图像数据处理模块和图像数据输出模块。
其中,关键部分是图像数据处理模块,采用的算法分别是最临近点插值算法和双线性插值算法,通过使用这两种不同的算法,来实现图像不同程度的放大要求。
关键词:
放大镜图像处理Linux系统
DesignandimplementationofamagnifyingglassunderLinux
Abstract
ThemainpointofthisessaywastodesignamagnifierapplicationwhichusedunderLinuxsystem.Explainedthehistory,vitalfunctionandapplicationaboutLinux.Iintroducedaapplicationsoftwaredevelopmenttool—Qt,whichisbasedonobjectorientedlanguagec++,iseasilyexpendedandacceptedcomponentprogramming.
Theprogramisdividedintothreemodules:
imagedatacapture,imagedataprocessingandimagedataoutput.Thekeypartisimagedataprocessingamongthesemodules,whichIadoptedtwodifferentalgorithmsthattheyarenearestneighborinterpolationandbilinearinterpolationalgorithm.Byusingthetwodifferentalgorithms,thevariousdegreeofamplificationrequirementsisrealized
KeyWords:
magnifyingglass;imagedataprocessing;Linuxsystem
1.引言
在这科学技术飞速发展的时代,尤其是电子产业的发展,使得计算机的应用领域不断扩大,而计算机本身也得到了不断提升。
大存储量、处理能力强的手持设备,凸显出了强劲的发展势头。
掌上电脑、第三代手机[2]等皆是手持设备,在这几年的发展中,不断出现新的成就,越来越方便人们的日常生活。
Linux系统,作为四大主流操作系统中的一员,在手持设备的发展中演绎着重要的角色。
Linux系统受到了人们越来越多的关注,这归功于其代码资源丰富、开放的源码、可移植性比较好等。
计算机中的放大镜是为了观察计算机中细微的不易辨析的文字或图片而设计的。
有了放大镜程序,计算机的功能将更加完善,计算机的使用者能够观察到其中更加细微的变化。
通过此次的开发,设计出一个在Linux系统下能够方便使用的放大镜程序,起到放大图片和文字的作用,为Linux系统的桌面应用添加实用的工具。
Windows系统有着自己的放大镜程序,但是Linux系统并没有此程序,因此设计一个Linux系统下的放大镜程序是很有意义的。
同时,通过此次设计,对Linux系统有着更加深入的了解,同时也是巩固和加深以C++为基础的面向对象编程技术。
1.1Linux系统的发展历史及其特点
从第一台计算机的诞生到10亿人上网花费了仅仅50多年时间。
而Linux系统也只是用了十年时间,就从出现走向了成熟。
计算机行业的更新速度让人震惊。
自1991年Linux系统的出现,它就在桌面系统和服务器中以惊人的速度占据重要地位,体现出系统功能的强大与完善。
Linux系统的高效性和灵活性,使其应用领域十分广泛,因此它被业内人士认为是最有前途的操作系统之一。
更加突出的是,Linux系统在嵌入式行业显示了其极大的优势,开放源码,可移植性好,系统稳定等,赢得众多开发人员的青睐。
目前,比较热门的智能家居设计,就是嵌入式产品的典型。
Linux系统的出现,也是让人相当的称赞。
一位名叫LinusTorvalds的学生,他的想法十分简单,设计一个既有Uinux系统的完整功能,还要能替代Minix的操作系统,由此,诞生了Linux系统。
Linux系统刚刚出现,就受到了开发人员和众多计算机爱好者的喜爱。
Linux系统两个主要原因,导致它受到如此的欢迎,一是软件自由,用户可以按照自身的需要裁剪源代码,设计出自己需要的程序来。
二是它拥有Unix系统的完整功能,即使是以前没有使用过Linux系统,但是只要是接触过Unix系统,就能很容易操作Linux平台。
Linux系统的一大特点是多平台性,也就是说Linux系统可以在多种硬件平台运行上,比如x86、SPARC、680x0[1]等处理器上。
可以看出,Linux系统有着诸多的优势和良好的发展前景,难怪有那么多的开发人员和厂商投身于Linux领域的开发和生产中。
1.2研究Linux系统下放大镜设计的目的和意义
图像数据的处理,是本次设计的关键所在,也是放大镜实现放大功能的前提。
通过对放大镜实现功能的具体分析,选择了两种比较适合的插值算法。
一种是最临近插值算法,另外一种是双线性插值算法[12]。
这两种算法各有自身的优点,前者是处理数据的速度比较快,后者是数据处理的结果比较准确。
因此,根据不同的需求,设计出两种不同类型的放大镜,一次满足用户的放大需求。
此次的放大镜设计,是对Linux系统更加深入的学习和理解,掌握Linux系统的开发方法,对于今后自身的开发技术的提高很有帮助。
在Linux系统中,与Windows系统最大的区别是一切皆是文件,对于系统内核来说,无论是软件、进程等,都被看作是文件。
总的来看,使用Linux的用户可以按照自己的意愿修改源码,对于从事开发开发行业的人来说,有着极大的好处。
学习Linux系统,使得自己对操作系统,开发工具,开发语言等都会有这更加深入的了解,对今后的开发工作十分有促进意义。
因此,学习在Linux系统下开发应用程序,一方面是对系统、语言等的进一步研究,另一方面也是把自己所学到的知识运用到开发中,检验自身的学习成果。
2.放大镜设计的需求分析
2.1Linux系统的概况
开源软件的影响力在不断增强,在世界范围内,Linux系统于桌面、服务器、行业制定等领域得到了长久的发展,特别在服务器行业,更是占据重要地位。
Linux内核2.6的出现,展现了Linux系统的重大进步,是其走向成熟和稳定的标识。
如今,虽然Linux系统版本繁多,但是不同版本内核是相同的,这也是Linux实行标准化、互换性的基础。
在服务器方面,由于IBM和因特尔等公司的鼎力支持,Linux系统取得了长期有效的发展。
电子商务在近年来的发展中不断的扩大,越来越多的用户和厂商开始重视Linux系统的桌面技术。
目前,比较有开发价值的桌面技术是:
3D桌面,桌面搜索技术,桌面友好性。
不得不承认,Linux系统正在逐步走向计算机中的各个领域,以其独特的优势,占据着主导地位。
2.2需要的技术支持
此次开发,使用的开发工具是跨平台开发框架Qt。
Qt提供了一种安全的类型称为信号与槽机制(signals/bits)[11],用它代替了callback,达到了安全传递信号的功能。
Qt的专注点在于C++图形界面开发,它的优点在于面向对象、跨平台性等。
Qt支持Windows,Linux,SCO等众多的操作系统,体现了其良好的跨平台的特性。
大量的API文档,丰富的C++类包,这是Qt开发的优势所在,也是开发人员迫切需要的。
开发人员可以从文档中了解Qt技术的使用方法,使用已存在的C++类,来简化开发过程。
像GoogleErath(三维地图虚拟软件)、stellarium(天文学自由软件)等,都是用Qt开发出来的。
使用QtCreator[10]作为此次开发的工具,对于了解Qt的作用,开发的流程,以及Qt中工具的使用,很有帮助。
使用Qt开发,利用Qt自身优势,开发出一款满意的放大镜程序。
2.3实现功能的划分
此次设计,把放大镜程序分成了两个部分,一个是“圆形”,一个是“方形”。
所谓“圆形”和“方形”是按照最终设计结果来命名的。
“圆形”是指模拟真实的放大镜,设计出能够即时放大文字或图片的程序,此窗体的外观和普通放大镜一样,因此称为“圆形”。
“方形”放大镜,实际上是一个方形窗体,窗体悬浮在桌面上,窗体中显示的内容随着鼠标位置的不同而改变。
之所以分为“圆形”和“方形”,是从算法效率上考虑。
最临近点插值算法运行效率高于双线性插值算法,但是其放大的图片不如后者清晰。
因此,用前一种插值算法来实现“圆形”放大,就是即时放大功能,用后一种插值算法来实现“方形”放大,即有效放大。
3.放大镜的概要设计
3.1功能设计的概述
放大镜的设计,实现的功能是放大桌面某一部分的图片或者文字,能够让使用者观察到计算机屏幕中细微的图像。
具体的实现原理是,获取鼠标所在位置的图像,并把图像数据放到缓存中[4],然后利用缓存中的数据,通过相应的放大函数处理数据使得图片放大,最后显示到设计好的窗体中。
此次的放大镜设计,可以有两种划分模式[6],一个是按照功能划分,那么可以划分成三个模块:
图像数据采集模块、图像数据处理模块、图像数据输出模块。
系统功能划分如图3.1所示。
如果是按照放大镜实现放大的技术上划分,可以分成两个部分,即“圆形”部分和“方形”部分。
在此,我选择了使用第一种方式来描述,因为它更加贴近软件开发的设计模式。
图3.1系统功能模块划分图
3.2模块划分
3.2.1图像数据采集模块
此模块的功能是获取当前屏幕任意区域的图像数据。
程序设计的大概流程如下:
(1)建立起数据连接,开启数据集;
(2)初始化列表,使得列表的显示条件符合数据记录的要求
(3)遍历数据集中的数据,把数据加到列表中
(4)断开数据集,断开数据连接
在这图像数据的采集过程中,使用到的方法如下:
QWidget*desktop=reinterpret_cast
:
desktop());
mCapturePixmap=QPixmap:
:
grabWindow(desktop->winId());
这里reinterpret_cast
:
desktop())方法的作用是定义了一个指向流的指针[5],管理图形界面中用户应用控制流。
使用QPixmap类中grabWindow()方法读取图像的数据流。
调用这两种方法,获取指定图片的数据,保存在临时变量中,用于对数据的进一步处理。
3.2.2图像数据处理模块
按照要求处理得到的图像数据,实现不同放大。
选择什么样的放大方法,如何放大,这个就决定了图片在最后放大后时质量,以及放大的形式的不同。
但是这两种方法有着共同的功能,那就是获取图像数据,进行放大处理。
需要具体分析的是,两种放大方法的算法设计。
第一种是最临近点插值算法:
最临近点插值算法是一种简单而有快速的插值算法。
通过把目标图片上的未知像素点,映射到原始数据上,和原始影像上4个与其相邻的像素点进行比较,把最接近未知像素点的值作为目标图片中未知像素点的值。
如图3.2所示:
p最接近D点,于是p的像素值就是D点像素值
图3.2最临近点插值算法示意图
最临近点插值算法的公式如下:
(1)
公式
(1)中,表示的是输出图像中坐标是位置的像素点颜色值。
表示的是输入图像中坐标是处的像素点颜色值。
第二种是双线性插值算法:
使用双线性插值是放大后的图片质量比较高,就是计算量有点大。
不过,与最临近插值算法相比,不会出现像素点不连续的状况。
图3.3是其示意图:
图3.3双线性插值算法示意图
其公式如下:
(2)
在该公式中,i,j代表了像素点的位置,比如原图中(i,j)的像素值用f(i,j)来表示。
3.2.2图像数据输出模块
输出模块的作用比较简单,主要的作用就是实现放大后的数据流输出的功能。
该模块使用了独立的输出方法,即重写了QPainter类中的PaintEvent()方法,绘画出放大后的图片。
这样写的好处是,可以根据自身需要,随时调用绘画方法,显示放大后的图像。
4.放大镜的详细设计
4.1详细设计的概述
之前,已经讲述了论文设计的实现方法,接下来要做的是进行详细设计,最终完成放大镜的设计工作。
首先,先看一下放大镜设计的主界面[9],如图4.1所示。
图4.1放大镜的主界面
在这个界面中,有两个按钮,命名是“圆形”,“方形”。
若点击了“圆形”按钮之后,出现形状是圆形的放大镜,这个就是那个简易放大镜。
若是点击了“方形”按钮之后,出现的方大镜是方形的,这个就是那个清晰放大镜。
需要注意的是,这两个放大镜并不能同时出现,一次只能出现一个。
还有就是,子窗口的启动运用到了进程QProcess类。
此时,子窗口运行于独立的进程中,如果只是简单的通过关闭按钮关闭子窗口,那么该进程并没有结束,最后可能会成为孤儿进程[3]。
因此,为了避免此类现象的发生,采用了主动杀死进程的方法。
当用户希望退出当前子窗口时,再点击一下父窗口中的按钮,那么子窗口进程将会被结束掉,子窗口将会退出。
4.2采集模块的设计
采集模块主要的作用是采集鼠标所在处的屏幕图像数据。
实现方式如下面所给的代码:
voidMagnifierWidget:
:
moveEvent(QMoveEvent*event)
{
//获取鼠标所在位置的图片信息
QPixmapdrawpix=mCapturePixmap.copy(pos().x(),pos().y(),width(),height());
source=drawpix.toImage();//把图片转换成QImage形式
dest=source;
mFilter->filter(source,dest,source.rect());
mDraw->repaint();//重绘图片
returnQWidget:
:
moveEvent(event);//返回鼠标点击事件
}
该方法的调用是在数据连接已经建立的基础上使用的。
该方法在获得图像数据后,首先做的事情是把图像的格式进行转化,把它转化成QImage形式,接着调用mFilter对象中的filter()方法,是实现图像数据的放大处理。
4.3处理模块的设计
图像数据处理模块可以说此次放大镜设计的核心部分,它实现了两种不同的放大功能。
按照用户不同的需求,采用不同的放大算法执行图片放大。
“圆形”部分:
在这个部分里,使用的是最临近点插值算法,满足用户即时放大的需求。
该插值算法的优点在运行效率快,但是缺点也很明显,放大后的图片有的地方像素点不连续,清晰度不是很高。
其中,主要的实现方法如下:
boolMagnifierFilter:
:
filter(constQImage&source,QImage&dest,QRectregion)
{
for(inti=region.left();i { for(intj=region.top();j { intx=mMatrixX->getData(i,j); inty=mMatrixY->getData(i,j); //设置(i,j)的像素点 dest.setPixel(i,j,source.pixel(x,y)); } } returntrue; } 上述方法实现的功能是调用最临近点插值算法的方法函数,通过索引(x,y)把源图片中相应坐标处的像素点放置到目标图像中,实现图像的放大。 而其中最临近点插值算法的实现方法的核心代码[7]展示如下, for(inth=0;h { intposition=h*mWidth; tmpProgress=qreal(h+1)/(qreal)mHeight; if(tmpProgress tmpProgress>UpProgress) { progressY=mEasingCurve.valueForProgress(tmpProgress); valuey=mHeight*progressY; } else { progressY=(progressDived)*\ (tmpProgress-FloorProgress)+progressFromFloor; valuey=mHeight*progressY; } for(intw=0;w { tmpProgress=qreal(w+1)/(qreal)mWidth; if(tmpProgress progressX=mEasingCurve.valueForProgress(tmpProgress); valuex=mWidth*progressX; } else { progressX=(progressDived)*\ (tmpProgress-FloorProgress)+progressFromFloor; valuex=mWidth*progressX; } dataX[position+w]=valuex; dataY[position+w]=valuey; “方形”部分: 在此部分中,利用双线性插值算法,实现图像的放大要求。 由于双线性插值算法计算时间长,所以满足不了即时性的要求。 但是,该算法放大的图片清晰度高,能够观察细小的变化。 该算法实现的核心代码如下, voidPicZoom_Bilinear2(constTPixels32Ref&Dst,constTPixels32Ref&Src) { if((0==Dst.width)||(0==Dst.height) ||(0==Src.width)||(0==Src.height))return; longxrIntFloat_16=((Src.width)<<16)/Dst.width+1; longyrIntFloat_16=((Src.height)<<16)/Dst.height+1; constlongcsDErrorX=-(1<<15)+(xrIntFloat_16>>1); constlongcsDErrorY=-(1<<15)+(yrIntFloat_16>>1); longdst_width=Dst.width; //y0+y*yr>=0;y0=csDErrorY=>y>=-csDErrorY/yr longborder_y0=-csDErrorY/yrIntFloat_16+1; if(border_y0>=Dst.height)border_y0=Dst.height; longborder_x0=-csDErrorX/xrIntFloat_16+1; if(border_x0>=Dst.width)border_x0=Dst.width; //y0+y*yr<=(height-2)=>y<=(height-2-csDErrorY)/yr longborder_y1=(((Src.height-2)<<16)-csDErrorY)/yrIntFloat_16+1; if(border_y1 longborder_x1=(((Src.width-2)<<16)-csDErrorX)/xrIntFloat_16+1; if(border_x1 Color32*pDstLine=Dst.pdata; longSrc_byte_width=Src.byte_width; longsrcy_16=csDErrorY; longy; for(y=0;y { longsrcx_16=csDErrorX; for(longx=0;x { Bilinear2_Border(Src,srcx_16,srcy_16,&pDstLine[x]);//border srcx_16+=xrIntFloat_16; } srcy_16+=yrIntFloat_16; ((UInt8*&)pDstLine)+=Dst.byte_width; } for(y=border_y0;y { longsrcx_16=csDErrorX; longx; for(x=0;x { Bilinear2_Border(Src,srcx_16,srcy_16,&pDstLine[x]);//border srcx_16+=xrIntFloat_16; } { unsignedlongv_8=(srcy_16&0xFFFF)>>8; Color32*PSrcLineColor= (Color32*)((UInt8*)(Src.pdata)+Src_byte_width*(srcy_16>>16)); for(longx=border_x0;x { Color32*PColor0=&PSrcLineColor[srcx_16>>16]; Color32*PColor1=(Color32*)((UInt8*)(PColor0)+Src_byte_width); Bilinear2_Fast(PColor0,PColor1, (srcx_16&0xFFFF)>>8,v_8,&pDstLine[x]); srcx_16+=xrIntFloat_16; } } for(x=border_x1;x { B
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 放大镜 设计 实现