Linux下的放大镜的设计与实现由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“科学放大镜教学设计”。
Linux下的放大镜的设计与实现
摘 要
本论文旨在设计一个在Linux系统下使用的放大镜应用程序。阐述了Linux系统的发展历史,Linux系统的重要作用以及其应用领域。介绍了Linux下的应用软件开发工具Qt,及基于面向对象语言C++,容易扩展,允许组件编程。
本文分三个模块:图像数据采集模块,图像数据处理模块和图像数据输出模块。其中,关键部分是图像数据处理模块,采用的算法分别是最临近点插值算法和双线性插值算法,通过使用这两种不同的算法,来实现图像不同程度的放大要求。
关键词:放大镜 图像处理 Linux系统
Design and implementation of a magnifying gla under Linux
Abstract
The main point of this eay was to design a magnifier application which used under Linux system.Explained the history,vital function and application about Linux.I introduced a application software development tool—Qt,which is based on object oriented language c++,is easily expended and accepted component programming.The program is divided into three modules: image data capture,image data proceing and image data output.The key part is image data proceing among these modules, which I adopted two different algorithms that they are nearest neighbor interpolation and bilinear interpolation algorithm.By using the two different algorithms,the various degree of amplification requirements is realized Key Words:magnifying gla;image data proceing;Linux system 1.引言
在这科学技术飞速发展的时代,尤其是电子产业的发展,使得计算机的应用领域不断扩大,而计算机本身也得到了不断提升。
大存储量、处理能力强的手持设备,凸显出了强劲的发展势头。掌上电脑、第三代手机[2]等皆是手持设备,在这几年的发展中,不断出现新的成就,越来越方便人们的日常生活。Linux系统,作为四大主流操作系统中的一员,在手持设备的发展中演绎着重要的角色。Linux系统受到了人们越来越多的关注,这归功于其代码资源丰富、开放的源码、可移植性比较好等。
计算机中的放大镜是为了观察计算机中细微的不易辨析的文字或图片而设计的。有了放大镜程序,计算机的功能将更加完善,计算机的使用者能够观察到其中更加细微的变化。通过此次的开发,设计出一个在Linux系统下能够方便使用的放大镜程序,起到放大图片和文字的作用,为Linux系统的桌面应用添加实用的工具。Windows系统有着自己的放大镜程序,但是Linux系统并没有此程序,因此设计一个Linux系统下的放大镜程序是很有意义的。同时,通过此次设计,对Linux系统有着更加深入的了解,同时也是巩固和加深以C++为基础的面向对象编程技术。
1.1 Linux系统的发展历史及其特点
从第一台计算机的诞生到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.1 Linux系统的概况
开源软件的影响力在不断增强,在世界范围内,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++类,来简化开发过程。
像Google Erath(三维地图虚拟软件)、stellarium(天文学自由软件)等,都是用Qt开发出来的。使用Qt Creator[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(QApplication::desktop());mCapturePixmap = QPixmap::grabWindow(desktop->winId());这里reinterpret_cast(QApplication::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 放大镜的主界面
在这个界面中,有两个按钮,命名是“圆形”,“方形”。若点击了“圆形”按钮之后,出现形状是圆形的放大镜,这个就是那个简易放大镜。若是点击了“方形”按钮之后,出现的方大镜是方形的,这个就是那个清晰放大镜。需要注意的是,这两个放大镜并不能同时出现,一次只能出现一个。还有就是,子窗口的启动运用到了进程QProce类。此时,子窗口运行于独立的进程中,如果只是简单的通过关闭按钮关闭子窗口,那么该进程并没有结束,最后可能会成为孤儿进程[3]。因此,为了避免此类现象的发生,采用了主动杀死进程的方法。当用户希望退出当前子窗口时,再点击一下父窗口中的按钮,那么子窗口进程将会被结束掉,子窗口将会退出。
4.2 采集模块的设计
采集模块主要的作用是采集鼠标所在处的屏幕图像数据。实现方式如下面所给的代码: void MagnifierWidget::moveEvent(QMoveEvent *event){ //获取鼠标所在位置的图片信息
QPixmap drawpix = mCapturePixmap.copy(pos().x(),pos().y(),width(),height());
source = drawpix.toImage();//把图片转换成QImage形式
dest = source;
mFilter->filter(source,dest,source.rect());
mDraw->repaint();//重绘图片
return QWidget::moveEvent(event);//返回鼠标点击事件 } 该方法的调用是在数据连接已经建立的基础上使用的。该方法在获得图像数据后,首先做的事情是把图像的格式进行转化,把它转化成QImage形式,接着调用mFilter对象中的filter()方法,是实现图像数据的放大处理。
4.3 处理模块的设计
图像数据处理模块可以说此次放大镜设计的核心部分,它实现了两种不同的放大功能。按照用户不同的需求,采用不同的放大算法执行图片放大。
“圆形”部分:
在这个部分里,使用的是最临近点插值算法,满足用户即时放大的需求。该插值算法的优点在运行效率快,但是缺点也很明显,放大后的图片有的地方像素点不连续,清晰度不是很高。其中,主要的实现方法如下:
bool MagnifierFilter::filter(const QImage & source,QImage & dest,QRect region){
for(int i = region.left();i
{
for(int j = region.top();j
{
int x = mMatrixX->getData(i,j);
int y = mMatrixY->getData(i,j);
//设置(i,j)的像素点
dest.setPixel(i,j,source.pixel(x,y));
} 上述方法实现的功能是调用最临近点插值算法的方法函数,通过索引(x,y)把源图片中相应坐标处的像素点放置到目标图像中,实现图像的放大。而其中最临近点插值算法的实现方法的核心代码[7]展示如下,for(int h = 0;h
{
int position = h * mWidth;
tmpProgre = qreal(h+1)/(qreal)mHeight;} return true;}
if(tmpProgre
tmpProgre > UpProgre)
{
progreY = mEasingCurve.valueForProgre(tmpProgre);
valuey = mHeight * progreY;
}
else
{
progreY =(progreDived)*
(tmpProgreFloorProgre)+ progreFromFloor;
valuex = mWidth * progreX;
}
dataX[position + w] = valuex;
dataY[position + w] = valuey;
“方形”部分:
在此部分中,利用双线性插值算法,实现图像的放大要求。由于双线性插值算法计算时间长,所以满足不了即时性的要求。但是,该算法放大的图片清晰度高,能够观察细小的变化。该算法实现的核心代码如下,void PicZoom_Bilinear2(const TPixels32Ref& Dst , const TPixels32Ref& Src){
if((0 == Dst.width)||(0 == Dst.height)
||(0 == Src.width)||(0 == Src.height))return;
long xrIntFloat_16 =((Src.width)
long yrIntFloat_16 =((Src.height)
const long csDErrorX =-(1 > 1);
const long csDErrorY =-(1 > 1);
long dst_width = Dst.width;
//y0 + y * yr >= 0;y0 = csDErrorY => y >=-csDErrorY/yr
long border_y0 =-csDErrorY/yrIntFloat_16 + 1;
if(border_y0 >= Dst.height)border_y0 = Dst.height;
long border_x0 =-csDErrorX/xrIntFloat_16 + 1;
if(border_x0 >= Dst.width)border_x0 = Dst.width;
//y0 + y * yr
if(border_x1
Color32 * pDstLine = Dst.pdata;
long Src_byte_width = Src.byte_width;
long srcy_16 = csDErrorY;
long y;
for(y = 0;y
{
long srcx_16 = csDErrorX;
for(long x = 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
{
long srcx_16 = csDErrorX;
long x;
for(x = 0;x
{
Bilinear2_Border(Src , srcx_16 , srcy_16 , &pDstLine[x]);//border
srcx_16 += xrIntFloat_16;
}
{
unsigned long v_8 =(srcy_16 & 0xFFFF)>> 8;
Color32 * PSrcLineColor =
(Color32*)((UInt8*)(Src.pdata)+ Src_byte_width*(srcy_16 >> 16));
for(long x = 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
{
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_y1;y
{
long srcx_16 = csDErrorX;
for(long x = 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;
} } 这一段代码,利用的就是双线性插值算法。当然,这只是算法实现中的部分。
4.4 输出模块的设计
此模块实现的功能比较简单,就是把放大后的图片输出到指定窗体中,根据用户的要求不同,设计了两种不同的窗体,如图4.2和图4.3所示。
图 4.2 圆形窗体示意图 图 4.3 方形窗体示意图 在图4.2中可以看到,放大镜是圆形区域,和生活中的放大镜很是相像。该放大镜优点在于使用灵活,窗体随着鼠标的移动而移动,并实时改变窗体中的显示内容,达到放大当前区域图像的功能。对于该放大镜,重写鼠标的事件:
MagnifierWidget::mousePreEvent(QMouseEvent *event)需要注意的是,此时鼠标的左键功能是已经改变,它的作用是退出当前窗体,右键功能是隐藏该窗体。也就是说,点击了左键,那么该窗体将会直接被关闭。点击了鼠标的右键,窗体将会被隐藏,当鼠标再次放在窗体隐藏的区域,窗体就会自动弹跳出来。之所以把鼠标左击事件重写,就是为了方便用户的使用,当用户想操作系统中的文件时,并不希望隔着放大镜来操作,而且也是为了放便用户关闭窗口,不必为关闭窗口而四处寻找主窗口。
图4.3所示窗体是方形,在窗体中可以看到有一个水平的滚动条,此滚动条的作用是调控放大倍数。使用者可以根据自身需求,通过拉动滚动条改变图像的放大倍数,以达到观察入微的效果。
两个窗口中绘图事件的实现代码是类似的,如下所示,void DrawWidget::paintEvent(QPaintEvent *event){
QPainter paint(this);//声明画笔
static QPixmap pix;//图片映射
pix = QPixmap::fromImage(mMagifier->dest);//获取图片信息
paint.drawPixmap(0,0,pix);//绘画图片,默认位置(0,0)
paint.drawImage(QRect(0,0,height(),width()),image);//以(1,1)为中心画圆
paint.drawEllipse(1,1,width()-2,height()-2);} 在这段代码里,Qpainter是申明了一个画笔,Qpixmap用来映射图片数据。drawEllipse()方法是用来绘画椭圆的。
到此,按照当初的需求分析,已经完成了放大镜的毕业设计。从总体看来,做的还不是很完善,有许多需要改进的地方,比如进程的处理,当初考虑的不够周到。不过,放大镜的基本功能是实现了,能够实行即时放大,达到预期的效果。
六年级科学下册《放大镜下的晶体》教学设计教 师: 韩 燕【教学目标】 知识与技能:一些固体物质的内部有一定的结构,如果构成这些物质的微粒按一定的空间次序排列,形成了有规则的......
《放大镜下的晶体》教学设计 教学目标:1、通过观察常见的固体物质的晶体,知道物质内部都是有一定结构的,晶体是物质存在的一种形式。2、通过两个实验,观察晶体、制作晶体,并进行......
《放大镜》教学反思新课标指出:一年级科学教学的主要宗旨是培养学生对科学的兴趣,产生对科学的情感,让他们热爱科学,让他们在生活中关注大自然,有好的科学习惯,让他们拥有一定的科......
引言 在日本设计师的作品中,展示出一个活生生的海报的世界。简单的海报以符号的堆积,每个作品中仿佛从世界中还原了出来,带着他们来自远古时代的神秘气息,这样的设计形态,引起我......
平办公自动化管理系统的设计与实现-原创论文-毕业设计 工资管理系统的设计与实现-原创论文-毕业设计 工商管理毕业论文-原创论文-毕......