基于opencv的图像处理系统的设计与实现

概要

  随着计算机技术的飞速发展,图像技术在各领域的研究和应用日渐深入和广泛。opencv是近年来推出的开源、免费的计算机视觉库,利用其所包含的函数可以很方便地实现数字图像处理。本文旨在对opencv进行一个快速全面简介,通过介绍图像处理的相关函数,使读者能快速形成对opencv印象。
本系统用opencv作为图像处理的核心,使用Qt作为程序的界面开发工具,使得界面开发和图像处理分离开,方便程序进行开发。同时利用面向对象的VS2013编程工具,用C++语言进行程序编写,大大提高了计算机的运行速度。
  本文首先阐述了opencv的特点以及结构,然后以图像变换、图像增强、形态学处理和滤镜为例介绍了opencv在数字图像处理中的典型应用。
  opencv算法库为C++编程处理数字图像提供了很大的方便,其必将成为图像视频处理领域的强有力的工具。

一、研究背景与意义

1.1 研究图像处理的背景和意义

  数字图像处理指的是应用数字计算机对图像进行分析、加工和处理。人们采集、表现与传送数据比较完整方便的途径主要来自于图像,伴着计算机技术开发程度的日益加深,数字图像处理技术的适用范围越来越广。人们要想简捷、实时的采集源自全球各处的图像,且确保图像的质量和清晰程度,就应当不断对数字图像处理技术进行研究。其中可以应用一此特殊的数学计算,以此对图像数据实现加工与分析,满足人们的视觉感受与现实需求。此外,还可以使用光学中的一此理论方法,对图像进行加工处理,然而其加工过程相对数字处理更加复杂,且存在很多限制性,不如数字图像处理灵活方便[[[] 吴国荣. 数字图像处理的发展现状与趋势研究[J]. 中国新通信,2017,03:153.]]。
  数字图像处理的产生和迅速发展主要受三个因素的影响:一是计算机的发展;二是数学的发展(特别是离散数学理论的创立和完善);三是广泛的农牧业、林业、环境、军事、工业和医学等方面的应用需求的增长。
  数字图像处理的基本特点:
  (1)目前,数字图像处理的信息大多是二维信息,处理信息量很大。如一幅256×256低分辨率黑白图像,要求约64kbit的数据量;对高分辨率彩色512×512图像,则要求768kbit数据量;如果要处理30帧/秒的电视图像序列,则每秒要求500kbit~22.5Mbit数据量。因此对计算机的计算速度、存储容量等要求较高。
  (2)数字图像处理占用的频带较宽。与语言信息相比,占用的频带要大几个数量级。如电视图像的带宽约5.6MHz,而语音带宽仅为4kHz左右。所以在成像、传输、存储、处理、显示等各个环节的实现上,技术难度较大,成本亦高,这就对频带压缩技术提出了更高的要求。
  (3)数字图像中各个像素是不独立的,其相关性大。在图像画面上,经常有很多像素有相同或接近的灰度。就电视画面而言,同一行中相邻两个像素或相邻两行间的像素,其相关系数可达0.9以上,而相邻两帧之间的相关性比帧内相关性一般说还要大些。因此,图像处理中信息压缩的潜力很大。
  (4)由于图像是三维景物的二维投影,一幅图像本身不具备复现三维景物的全部几何信息的能力,很显然三维景物背后部分信息在二维图像画面上是反映不出来的。因此,要分析和理解三维景物必须作合适的假定或附加新的测量,例如双目图像或多视点图像。在理解三维景物时需要知识导引,这也是人工智能中正在致力解决的知识工程问题。
  (5)数字图像处理后的图像一般是给人观察和评价的,因此受人的因素影响较大。由于人的视觉系统很复杂,受环境条件、视觉性能、人的情绪爱好以及知识状况影响很大,作为图像质量的评价还有待进一步深入的研究。另一方面,计算机视觉是模仿人的视觉,人的感知机理必然影响着计算机视觉的研究。例如,什么是感知的初始基元,基元是如何组成的,局部与全局感知的关系,优先敏感的结构、属性和时间特征等,这些都是心理学和神经心理学正在着力研究的课题。
随着计算机更新换代,技术的高速发展以及操作系统和平台的开源性,数字图像处理系统的性能得到了很大的提高,而另一方面,产品日益大规模集成化,成品价格日益下降,使得图像处理技术更加广泛地应用于各行各业[[[] 李志玉,邓月明. 面向行业应用的数字图像处理研究综述[J]. 电脑与信息技术,2015, 04:32-34.]]。
  1、航天和航空技术方面的应用数字图像处理技术在航天和航空技术方面的应用,除了上面介绍的JPL对月球、火星照片的处理之外,另一方面的应用是在飞机遥感和卫星遥感技术中。许多国家每天派出很多侦察飞机对地球上有兴趣的地区进行大量的空中摄影。对由此得来的照片进行处理分析,以前需要雇用几千人,而现在改用配备有高级计算机的图像处理系统来判读分析,既节省人力,又加快了速度,还可以从照片中提取人工所不能发现的大量有用情报。这些图像无论是在成像、存储、传输过程中,还是在判读分析中,都必须采用很多数字图像处理方法。现在世界各国都在利用陆地卫星所获取的图像进行资源调查(如森林调查、海洋泥沙和渔业调查、水资源调查等),灾害检测(如病虫害检测、水火检测、环境污染检测等),资源勘察(如石油勘查、矿产量探测、大型工程地理位置勘探分析等),农业规划(如土壤营养、水份和农作物生长、产量的估算等),城市规划(如地质结构、水源及环境分析等)。我国也陆续开展了以上诸方面的一些实际应用,并获得了良好的效果。在气象预报和对太空其它星球研究方面,数字图像处理技术也发挥了相当大的作用。
  2、生物医学工程方面的应用数字图像处理在生物医学工程方面的应用十分广泛,而且很有成效。除了上面介绍的CT技术之外,还有一类是对医用显微图像的处理分析,如红细胞、白细胞分类,染色体分析,癌细胞识别等。此外,在X光肺部图像增晰、超声波图像处理、心电图分析、立体定向放射治疗等医学诊断方面都广泛地应用图像处理技术。
  3、通信工程方面的应用当前通信的主要发展方向是声音、文字、图像和数据结合的多媒体通信。具体地讲是将电话、电视和计算机以三网合一的方式在数字通信网上传输。其中以图像通信最为复杂和困难,因图像的数据量十分巨大,如传送彩色电视信号的速率达100Mbit/s以上。要将这样高速率的数据实时传送出去,必须采用编码技术来压缩信息的比特量。在一定意义上讲,编码压缩是这些技术成败的关键。除了已应用较广泛的熵编码、DPCM编码、变换编码外,目前国内外正在大力开发研究新的编码方法,如分行编码、自适应网络编码、小波变换图像压缩编码等。
  4、工业和工程方面的应用在工业和工程领域中图像处理技术有着广泛的应用,如自动装配线中检测零件的质量、并对零件进行分类,印刷电路板疵病检查,弹性力学照片的应力分析,流体力学图片的阻力和升力分析,邮政信件的自动分拣,在一些有毒、放射性环境内识别工件及物体的形状和排列状态,先进的设计和制造技术中采用工业视觉等等。其中值得一提的是研制具备视觉、听觉和触觉功能的智能机器人,将会给工农业生产带来新的激励,目前已在工业生产中的喷漆、焊接、装配中得到有效的利用。
  5、军事公安方面的应用在军事方面图像处理和识别主要用于导弹的精确末制导,各种侦察照片的判读,具有图像传输、存储和显示的军事自动化指挥系统,飞机、坦克和军舰模拟训练系统等;公安业务图片的判读分析,指纹识别,人脸鉴别,不完整图片的复原,以及交通监控、事故分析等。目前已投入运行的高速公路不停车自动收费系统中的车辆和车牌的自动识别都是图像处理技术成功应用的例子。
  6、文化艺术方面的应用目前这类应用有电视画面的数字编辑,动画的制作,电子图像游戏,纺织工艺品设计,服装设计与制作,发型设计,文物资料照片的复制和修复,运动员动作分析和评分等等,现在已逐渐形成一门新的艺术:计算机美术。
  7、机器人视觉:机器视觉作为智能机器人的重要感觉器官,主要进行三维景物理解和识别,是目前处于研究之中的开放课题。机器视觉主要用于军事侦察、危险环境的自主机器人,邮政、医院和家庭服务的智能机器人,装配线工件识别、定位,太空机器人的自动操作等。
  8、视频和多媒体系统:目前,电视制作系统广泛使用的图像处理、变换、合成,多媒体系统中静止图像和动态图像的采集、压缩、处理、存贮和传输等。

1.2 图像处理的研究现状

  目前,低成本硬件加上相关技术发展再加之发展中的新应用领域,可以预料数字图像处理将会继续迅速发展,并在应用上发挥更重要的作用。就国内的研究情况而言,在理论方面己取得不少成果。如医学诊断的应用、图像压缩编码、目标识别和跟踪等,但在实际应用还很欠缺,所以将理论应用于实践势在必行。未来将从超高速、高分辨率、立体化、多媒体、智能化和标准化方向发展,具体体现在以下几个方面[[[] 贺东霞,李竹林,王静. 浅谈数字图像处理的应用与发展趋势[J]. 延安大学学报(自然科学版),2013,04:18-21.]]:
  1、计算机视觉:随着计算机技术和人工智能、思维科学研究的迅速发展,数字图像处理将向更高更深层次发展。机器人视觉作为智能机器人的重要感觉器官,主要进行三维景物理解和识别,是目前研究之中的开放话题。主要用于军事侦察、危险环境的自主机器人、邮政、医院和家庭服务的智能机器人、装配线工件识别定位、太空机器人的自动操作等。因人类本身对自己的视觉还了解甚少,因此计算机视觉是一个有待人们进一步探索的新领域。
  2、虚拟现实:虚拟现实是指由于计算机实时生成一个虚拟的三维空间。目前,虚拟现实随着计算机软硬件技术的提高,虚拟现实系统将会受到很大重视并将迅速的发展。通过采用数据手套及在机器人身上的摄像机,人们可以真实感受机器人所处的环境,并且能够操纵机器人。另外,网上虚拟现实也是一个研究重点。
  3、三维重建:人类对社会事物的认识和工具的使用一直喜欢将其掌握在自己手中,通过亲身实际操作来完成社会生产。因此,将原来二维的东西通过三维来展现早己成为时代的发展趋势。如地图方面对三维电子地图的应用;军事方面,利用电子沙盘可实现任意角度旋转、放大缩小,水平、垂直等方向上的距离的计算。另外,两点之间的障碍物、剖面轮廓等也能被直观显示。除此之外,还能模拟飞行路线等。所有这些为指挥作战带来了极大的方便。如何在计算机中对场景进行快速、有效的重建,不仅仅是基于上面所提到的优势促使人类去研究实践,而事实上它一直以来都是计算机视觉研究领域的热点和难点,也是数字图像处理的发展趋势之一。
  4、图像压缩、分割、识别算法的研究:图像理解虽然在理论方法研究上己取得不少的进展,但它本身是一个比较难的研究领域,存在不少困难,正因为如此,图像处理理论和技术受到各界的广泛重视,当前图像处理面临的主要任务是研究新的处理方法、构造新的处理系统,开拓更广泛的应用领域。比如,针对各种类型图像开发专业压缩算法、图像分割算法、图像识别算法。尤其是对小波变换、模糊数学等的研究。

二、开发环境与工具介绍

  在整个平台的设计和开发过程中我们用到了Qt作为我们的界面工具,在图像处理方面,我们还调用了OpenCV中的一些函数,后台用到了数据库用来存储医学图像的数据。

2.1 Qt的概述

2.1.1 Qt的介绍

  Qt是一个跨平台的C++图形用户界面库,由挪威Troll Tech公司出品。目前产品包括Qt、基于Framebuffer的Qt Embedded、快速开发工具Qt Designer、国际化工具Qt Linguist等部分。Qt不但支持所有Unix系统,而且支持Linux,也支持Windows平台。
   Qt是基于面向对象的C++语言,它提供了信号(signal)和槽(slot)的对象通信机制,具有可查询和可设计的属性,以及强大的事件和事件过滤器。同时,它还具有字符国际化,即支持根据上下文进行国际化字符串翻译。许多Qt特性基于QObject的继承,通过标准C++技术实现。
图形用户界面是用户与计算机进行交互的操作方式,即用户与计算机之间互相传递信息的方式,它因美观、大方、简单易用而深受广大用户的喜爱。由挪威TrollTech公司开发的Qt是一个用于跨平台的图形界面程序开发的C++工具包,提供给应用程序开发者建立图形用户界面所需的所有功能。Qt是使用源代码级“一次编写,随处编译”的方式用于构建多平台图形用户界面程序,它完全面向对象且很容易扩展,提供给应用程序开发者建立艺术级图形用户界面所需的功能,提供了信号与槽的机制替代回调函数,使组件间信号传递更安全、简单,因此,它己经成为全世界范围内数千种成功的应用程序的基础,为世界上数千个最大的公司,包括IBM ,摩托罗拉和夏普等提供开发软件[[[] 黄艳芳. 基于Qt4的图形用户界面程序设计与游戏开发[J].电子设计工程,2011,17:49- 53. ]]。

2.1.2 Qt的特点

  Qt作为新型的GUI开发工具,具有与一般的工具包所不同的特征,使它的应用非常广泛,其特点如下所述:
  1. 面向对象
  Qt具有模块设计和组件或元素的可重用性的特点。一个组件不需要知道它的内容和用途,通过signal和slot与外界通信、交流。而且,所有Qt的组件都可通过继承。
   2. 组件间的相互通信
   Qt提供signal和slot概念,这是一种安全可靠的方法,它允许回调,并支持对象之间在彼此不知道对方信息的情况下,进行合作,这使Qt非常合适于真正的组件编程。
   3. 友好的联机帮助
   Qt包括大量的联机参考文档,有超文本HTML方式、UNIX帮助页、man手册和补充的指南。对于初学者,指南将一步步地解释Qt编程。
  4. 用户自定义
其他的工具包在应用时都存在一个普遍的问题,就是经常没有真正适合需求的组件,生成的自定义组件对用户来说,也是一个黑匣子。比如,在Motif手册中就讨论了用户自定义的组件的问题。而在Qt中,能够创建组件,具有绝对的优越性,生成自定义组件非常简单,并且容易修改组件。
  5. 方便性
  由于Qt是一种跨平台的GUI工具包,所以,它对编程者隐藏了在处理不同窗口系统时的潜在问题。为了将基于Qt程序更加方便,Qt包含了一系列类,该类能够使程序员避免了在文件处理、时间处理等方面存在依赖操作系统方面的细节问题。
  6. 国际化
  Qt为本地化应用提供完全的支持,所有用户界面的文本或字符串都可以利用翻译工具将其译成各国语言。另外,Qt完全支持双字节16bit国际字符标准。
  7. 丰富的API函数
  为了适合用户的需求,Qt的API提供了250个C++类,该类大多数用于专门的GUI。Qt还提供了基于模板的初始化、文件和通用的I/O设备、目录管理、日期/时间类、常用表达式解析等。目的是利用这些类,建立或生成不同的功能,用它们来实现Qt的通用化。除此之外,也可以利用STL标准模块库或其他工具包。
  8. 完整的一套组件
  Qt编程的基本模块(构件)称为组件,一个组件是一个用户界面的组成部分,比如按钮、滚动条。Qt包含用来创建专业外观的用户界面所需要的所有组件。

2.1.3 Qt编程相关技术

  1、信号与槽
  信号和槽机制是Qt编程的基础这个机制可以让编程人员把这些互不了解的对象绑定在一起。信号是一个特定的标识一个槽就是一个函数槽和普通的C++成员函数几乎是一样的 可以是虚函数可以被重载可以是公有的保护的或者私有的并且也可以被其他C++成员函数直接调用还有它们的参数可以是任意类型唯一不同的是槽还可以和信号连接在一起当某个事件出现时通过发送信号可以将与之相关的槽函数激活即执行槽函数代码 在程序中使用QObject connect 函数来将某个信号和某个槽进行关联 而信号和槽之间的真正关联是由Qt的信号和槽机制来实现的 connect函数语法如下connect sender SIGNAL signal receiver SLOT slot sender和receiver 是QObject对象指针signal和slot是不带参数的函数原型。
信号和槽的关联关系可以有几种模式
1)一个信号和一个槽关联。
2) 一个信号和多个槽关联当发射这个信号的时候会以不确定的顺序一个接一个地调用这些槽。
3)多个信号和一个槽关联无论发射的是哪一个信号都会调用这个槽另外一个信号还可以与另外一个信号相连接当发射第一个信号时也会发射第二个信号,信号与信号之间的连接和信号与槽之间的连接有时是难以区分的。
信号与槽除了可以在程序中用connect函数手动关联外Qt的元对象还提供了信号与槽的自动关联对于Qt窗口部件已经提供的信号 如果能按下面的规则命名槽函数那么Qt就能够自动进行关联。采用的都是自动关联信号与槽的方 式更加简单快捷。
  2、事件
  事件功能简单来说就是当一个事件产生后相关控件作出回应 Qt事件的处理过程是首先QApplication的事件循环体从事件队列中拾取本地窗口系统事件或者其他事件译成QEvent然后把QEvent送 给QObject::event最后再送给QWidget::event 对事件进行处理Qt已经将上述那些繁琐的调用步骤封装极大减轻了编程人员的负担。
  3、定时器
  Qt中的QTimer类提供了定时器信号和单触发定时器,它在内部使用定时器事件来提供更通用的定时器QTimer的使用比较简单创建一个QTimer使用start 来开始并且把它的timeout 连接到适当的槽 当这段时间过去了它将会发射timeout 信号QTimer的精确度依赖于底下的操作系统和硬件绝大多数平台支持20 ms的精确度一些平台可以提供更高的。如果Qt不能传送定时器触发所要求的数量 它将会默默地抛弃一些 一些操作系统限制可能用到的定时器的数量Qt会尽力在限制范围内工作当QTimer的父对象被销毁时它也会被自动销毁。
  4、按钮
  QPushButton窗口部件提供了命令按钮 主要用来提供点击动作控件pushButton 用自动关联信号与槽的方式void_on_pushButton_clicked 关联信号与槽 当按钮被鼠标空格键或者键盘快捷键激活它发射clicked 信号连接这个信号来执行按钮的操作。
  5、绘图
  Qt的2D图形系统的基础是类QPainter。QPainter能够绘制各种几何图形点线矩形椭圆圆弧弦扇形多线段贝赛尔曲线还能绘制位图图像和文字。在控件上绘图时先创建一个QPainter把绘图设备指针传给QPainter对象然后在绘图函 数paintEvent QPaintEvent *event中通过函数painter.setPen 设置画笔的颜色大小和所绘曲线类型通过函数painter.draw()函数绘制需要的图形通过函数QBrush brush QColor 设置画刷颜色用画刷给图形填充颜色paintEvent 函数是一个事件处理函数在控件需要重新绘制的时候调用Qt中很多情况下都会产生绘制事件调用paintEvent 函数:
1 当控件第一次显示时Qt自动产生绘制事件使控件绘制自身。
2 当控件尺寸发生变化时系统产生绘制事件。
3 如果控件被其他的窗口遮住窗口移走时产生绘制被遮住部分的事件。
4 如果 调 用 了QWidget::update和QWidget::repaint 函数产生绘制事件update 函数和repaint 函数有所不同 repaint 立刻产生绘制事件重新绘制控件而调用update 后只是交给Qt一个产生绘制事件的计划 如果控件在屏幕上不可见那么这两个函数什么都不做 如果update 被调用了多次之后Qt就把这几个连续的绘制事件合为一个事件避免闪烁。

2.2 OpenCV概述

2.2.1 OpenCV的定义

  OpenCV(open source computer vision library)诞生于Intel研究中心,是一个开放源码的计算机视觉库。0penCV采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上。0penCV还提供了Python、Ruby、 MATLAB以及其他语言的接口。它包含的函数有500多个,覆盖了计算机视觉的许多应用领域[[[] 秦小文,温志芳,乔维维. 基于OpenCV的图像处理[J]. 电子测试,2011,07:39-41.]]。

2.2.2 OpenCV的特点

(1)OpenCV采用C/C++语言编写,可以运行在Linux/Windows/Mac等操作系统上。
(2)OpenCV提供了Python、Ruby、MATLAB以及其他语言的接口。
(3)它采用优化的C代码编写,能够充分利用多核处理器的优势
(4)具有良好的可移植性

2.2.3 OpenCV的设计目标

   执行速度尽量快,主要关注实时应用。如果是希望在Intel平台上得到更快的处理速度,可以购买Intel的高性能多媒体函数库IPP(Integrated Performance Primitives)。IPP库包含许多从底层优化的函数,这些函数涵盖多个应用领域。如果系统已经安装了IPP库,OpenCV会在运行时自动使用相应的IPP库。

三、系统分析与设计

3.1 平台的功能架构

  本平台根据“自顶向下,逐步求精”的程序设计原则,总体功能包括文件、变换、图像增强、形态学处理、滤镜,在每个功能下实现各自不同的子功能,如下对各自的功能进行一个简单的介绍。
  1、 文件
文件要完成主要功能就是实现图像的读取和保存,系统的正常退出,如图3.1所示。
在这里插入图片描述

图 3.1 文件结构示意
  2、变换
变换分为图像的镜像、旋转、缩放和截图,如图3.2所示。
在这里插入图片描述

图 3.2 变换结构示意
  镜像操作可以使得图像实现沿着水平轴方向来进行翻转和沿着垂直方向轴来进行翻转。
旋转操作可以自定义图像的旋转角度,正值代表顺时针旋转,负值代表逆时针旋转。并且可以选择是否保留图像的全部信息。
  缩放操作可以使得图片以任意的水平或者垂直系数对图像进行设置,本平台还提供了几种常见的插值方式来对图像进行缩放。
  截图可以自定义选取的图片的区域,鼠标按下操作的位置代表图像的左上角顶点,鼠标抬起操作的位置代表图像的右下角顶点,之后进行截取ROI感兴趣区域,选取完成区域以后会弹窗提示选择的区域大小。
  3、图像增强
图像增强分为参数调整、非线性滤波、线性滤波和图像修复,如图3.3所示
在这里插入图片描述

图 3.3 图像增强结构示意
  参数调整可以对图像进行亮度和对比度的调整,即图像的明暗程度和图像的边缘对比强度。
线性滤波是用各自的线性滤波器对图像进行处理。
非线性滤波是用各自的处理算法对图像及西宁处理。
图像修复可以将受损的图片、有水印的图片进行一个回复原图的工作。
  4、形态学处理
数字图像处理中的形态学处理是指把数字形态学作为工具从图像中提取对于表达和描绘区域形状有用处的图像分量,主要包括膨胀、腐蚀、开运算、闭运算、形态学梯度、顶帽和黑帽功能,如图3.4所示。

在这里插入图片描述

图 3.4 形态学处理结构示意
  膨胀与腐蚀能实现多种多样的功能,主要如下;
·消除噪声;
·分割出独立的图像元素,在图像中连接相邻的元素;
·寻找图像中的明显的极大值区域或极小值区域;
·找出图像的梯度。
开运算可以用来消除小物体,在纤细点处分离物体,并且在平滑较大物体的边界额同时不明显改变其面积。
闭运算能够排除小型黑洞(黑色区域)。
形态学梯度可以对二值图像的团块的边缘突出出来,常用来保留物体的边缘轮廓。
顶帽运算往往用来分离比邻近点亮一些的斑块。在一幅图像具有大幅的背景,而微小物体比较有规律的情况下,常用顶帽运算进行背景提取。
黑帽运算之后突出比原图轮廓周围区域更暗的区域,所以黑帽运算用来分离比邻近点暗一些的斑块。
  5、滤镜
  给图像添加滤镜效果,主要包括调色、羽化、素描、颜色变换和扩散,如图3.5所示。

在这里插入图片描述

图 3.5 滤镜结构示意
调色,分为怀旧和连环画效果。怀旧可以使得读取的图像实现怀旧照片的效果。连环画使得读取的图片实现连环漫画或者说是上世纪小人书的漫画效果。
羽化,可以使得图像模糊边缘,使得图像有一种朦胧的艺术效果。
素描,可以将彩色图片变成一张素描作品。
扩散,可以使得图像有着毛玻璃的特效。

四、 详细设计

4.1 图像变换

4.1.1 图像镜像变换

  图像镜像(Mirror)变换分为两种:一种是水平镜像,另一种是垂直镜像。图像的镜像变换不会改变图像的形状。
  1、图像的水平镜像是指将指定区域的图像以原图像的垂直中轴线为中心,将图像分为左右两部分进行对称变换显示在屏幕。水平镜像时每行图像信息的处理方式是相同的,而且行顺序不发生变化,只是每一行的像索信息按从左到右的顺序进行了左右颠倒,所以镜像后图像的高和宽不变[[[] 赛恒吉雅. 数字图像镜像变换方法的实现[J]. 科技传播,2010,09:143+142.]]。其矩阵表达式由式(4.1)可见。
在这里插入图片描述

水平镜像的处理效果如图4.1所示:

图4.1(a)原图                  图4.1(b) 水平镜像

图4.1 水平镜像效果图
  2、垂直镜像与水平镜像图类似只是图像的垂直镜像操作是以原图像的水平中轴线为中心,将图像分为上下两部分进行对称变换显示在屏幕。垂直镜像时每列图像信息的处理方式是相同的,而且列顺序不发生变化,镜像后图像的高和宽不变。其矩阵表达式由式(4.2)可见。
在这里插入图片描述

垂直镜像的处理效果如图4.2所示:

在这里插入图片描述

图4.2 垂直镜像的效果图
  3、代码分析。
函数原型:flip(InputArray src, OutputArray dst, int flipCode)。
第一个参数:src:输入矩阵。
第二个参数:dst:翻转后矩阵,类型与src一致。
第三个参数: flipCode:翻转模式:
flipCode=0垂直翻转(沿X轴翻转);
flipCode>0水平翻转(沿Y轴翻转);
flipCode<0水平垂直翻转(先沿X轴翻转,再沿Y轴翻转)。

4.1.2 图像的几何变换

  旋转(rotation)有一个绕着什么转的问题,通常的做法是以图像的中心为圆心旋转,将图像上的所有像素都旋转一个相同的角度。图像的旋转变换是图像的位置变换,但旋转后,图像的大小一般会改变。和图像平移一样, 在图像旋转变换中既可以把转出显示区域的图像截去,旋转后也可以扩大图像范围以显示所有的图像。
在实际照片旋转中,我们经常采用另一种剪切形式的调整方式:图像旋转后,缩小图片,使图片各个边角均不出现黑边。 如图4.3所示。

在这里插入图片描述

图4.3 旋转图片
  这种调整方式下,新图像大小的计算如下:
旋转后的外边框宽度由式(4.3)所示,高度由式(4.4)所示
out_width = widthcos(a) + heightsin(a) (4.3)
out_height = heightcos(a) + widthsin(a) (4.4)
画辅助线,如图4.4所示。
在这里插入图片描述

图4.4 旋转图像参数效果图
  其最长的边长由式(4.5)所示,角a 即旋转角度。
len = width*cos(a) (4.5)
由于外边框大小已知,则Y的值由式(4.6)计算,X的值由式(4.7)计算:
Y = len / ( 1 / tan( a ) + 1 / tan( b ) ) (4.6)
X = Y * 1 / tan( b ) (4.7)
最后求得红框的长由式(4.8)得出,宽由式(4.9)得出。
new_width = out_width - 2 * X (4.8)
new_height = out_height - 2 * Y (4.9)
这样我们就可以自定义旋转角度,并可以选择是否有黑边,最终其旋转效果如图4.5所示。

在这里插入图片描述

图4.5 旋转30°的图像

4.1.3 图像的缩放

  本平台的调整图像大小用的是resize这个函数。可以实现将读取的图像以任意的水平或者垂直系数对图像进行方法或者缩小,并且可以选择图像的插值方式。
  1、函数原型:void resize(InputArray src,OutputArray dst, Size dsize, double fx=0, double fy=0, int interpolation=INTER_LINEAR ) 。resize()为OpenCV中专职调整图像大小的函数。此函数将源图像精确地转换为指定尺寸的目标图像。
第一个参数,InputArray类型的src,输入图像,即源图像,填Mat类的对象即可。
第二个参数,OutputArray类型的dst,输出图像,当其非零时,有着dsize(第三个参数)的尺寸,或者由src.size()计算出来。很多时候,我们并不用考虑第二个参数dst的初始图像尺寸和类型(即直接定义一个Mat类型,不用对其初始化),因为其尺寸和类型可以由src,dsize,fx和fy这其他的几个参数来确定。
第三个参数,Size类型的dsize,输出图像的大小;如果它等于零,由式(4.10)计算:
dsize = Size(round(fxsrc.cols),round(fysrc.cols)) (4.10)
其中,dsize,fx,fy都不能为0。
第四个参数,double类型的fx,沿水平轴的缩放系数,有默认值0,且当其等于0时,由式(4.11)计算:
fx = (double)dsize.width/src.cols (4.11)
第五个参数,double类型的fy,沿垂直轴的缩放系数,有默认值0,且当其等于0时,由式(4.12)计算:
fy = (double)dsize.height/src.rows (4.12)
第六个参数,int类型的interpolation,用于指定插值方式,默认为INTER_LINEAR(线性插值)。
可选的插值方式如下[[[] 李秀英,袁红. 几种图像缩放算法的研究[J]. 现代电子技术,2012,05:48-51.]]:
·INTER_NEAREST - 最近邻插值
最近邻插值,是用图像中的特定点的像素值填充缩放后的图像,即将原始的信号进行逐点处理,把其中的每一点都用其灰度值进行m次复制(m为缩放倍数),即输出像素的灰度值等于离它所映射到的位置最近的输入像素的灰度值。最邻近插值计算十分简单,在许多隋况下,其结果也可令人接受。然而,当图像中包含像素之间灰度级有变化的细微结构时,最邻近插值法会在图像中产生人工的痕迹,出现明显的块状现象,整幅图像十分粗糙。
·INTER_LINEAR - 线性插值(默认值)
线性插值算法由于其较低的计算量和高于最近邻域插值的代数逆合(二阶)而被广泛应用。因为采用线性插值算法在对图像的放大是对行列信号作两次处理后得到的,所以称这种方法为双线性插值。但是,它通常会平滑掉图像中许多重要的高频信息。
双线性插值比最邻近域法产生的图像平滑,但当放大倍数增大时,放大后的图像会出现明显的块状现象。线性插值基本思想就是把目标点附近的原始点的灰度值按一定的权值相加。
·INTER_AREA - 区域插值(利用像素区域关系的重采样插值)
当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于INTER_NN方法。
·INTER_CUBIC –三次样条插值(超过4×4像素邻域内的双三次插值)
三次插值也称三次卷积插值,高精度三次样条插值或者双三次插值,它是的一个近似。其表达式由式(4.13)所示:
在这里插入图片描述

·INTER_LANCZOS4 -Lanczos插值(超过8×8像素邻域的Lanczos插值)
Lanczos算法实际上是Arnoldi算法对于对称矩阵的特殊形式,可应用于对称矩阵线性方程组求解的Krylov子空间方法以及对称矩阵的特征值问题。很显然这种算法参考了更多的源图像像素值,计算量增大了很多,也是效果最好的一种。
若要缩小图像,一般情况下最好用INTER_AREA来插值,
而若要放大图像,一般情况下最好用INTER_CUBIC(效率不高)或INTER_LINEAR(效率较高)。
  2、平台以resize函数为核心,利用Qt界面来实现用户输入函数所需要的参数,对读取的图像进行调整。函数的第三个参数fx是水平缩放系数,第四个参数fy是垂直缩放系数,第五个参数interpolation是图像插值方式,如图4.6所示。

在这里插入图片描述

图 4.6 图像大小调整界面

4.1.4 图像的截图

  本平台的截图功能是对于读取的图片的感兴趣区域(ROI)的选取。
截图的选取分为三步:首先是需要重写鼠标操作,其二是获取label控件的相对位置,最后截取感兴趣区域。
  1、鼠标操作函数原型:
void mousePressEvent(QMouseEvent event):鼠标按下的时候函数所进行的操作;
void mouseMoveEvent(QMouseEvent
event):鼠标移动的时候所进行的操作;
void mouseReleaseEvent(QMouseEvent *event):鼠标抬起的时候所进行的操作。
  2、图片相对位置的计算:截图功能是获取读取的图像的某一部分,所以对于鼠标在相对于图片控件上的相对位置就尤为重要。又因为通过以上的函数原型得到的鼠标位置是绝对位置,即是在程序窗口的位置。所以需要通过一系列的函数来计算图片相对于控件的相对位置。计算程序窗口上控件位置的所需要的函数如图4.7所示。

在这里插入图片描述

图 4.7 程序窗体大小函数
第一步,通过重写的鼠标操作来获取鼠标的绝对位置,即声明一个QPoint类的对象m_beginPoint。通过m_beginPoint = event->pos(),保存在刚才声明的类对象中。
第二步,计算偏移量:
对于水平方向的偏移量xoffset由式(4.14)所示,geometry().width()是程序窗口的宽度,img.width()是图片的宽度。
xoffset = (geometry().width() - img.width()) / 2 (4.14)
对于垂直方向的偏移量yoffset由式(4.15)所示,frameGeometry().height()是程序窗口的高度,img.height()是图片的高度。
yoffset = (frameGeometry().height() - img.height()) / 2 (4.15)
第三步,计算图片相对位置,x的位置由式(4.16)所示,y的位置由式(4.17)所示。
int x = m_beginPoint.x() - xoffset (4.16)
int y = m_beginPoint.y() - yoffset (4.17)
  3、平台以以上的理论为基础,当鼠标点击的时候记录起始点的位置,鼠标抬起的时候记录结束点的位置。鼠标抬起的时候会弹出一个界面,显示出截图的信息,如图4.8所示。

在这里插入图片描述

图 4.8 程序截图功能

结论

  本平台利用了opencv对图像进行了初步的处理,分为如下几个模块:图像变换、图像增强、形态学处理和图像滤镜。
  图像变换模块,实现了图片的水平和垂直镜像翻转、自定义旋转角度、缩放和截图功能。对于自定义旋转角度,本平台新建了一个弹出窗口,左边是预览窗口,右边则是参数的设置,这样用户每作出调整,左边就会给出处理之后的结果,方便用户的使用。关于图像的缩放,本文对于其缩放的插值算法进行了较为详细的原理分析。关于程序的截图,代码使用了Qt来实现。因为opencv如果使用截图功能,他有自己的GUI,还必须要使用其的回调函数,再将结果转回到Qt界面将会相当麻烦。
  图像增强模块,亮度对比度的调整就是对读取图像的像素进行操作,是公式的简单应用。对于图像的两种滤波操作:非线性滤波和线性滤波。程序对于这两种滤波各自的分类以及原理进行了简单扼要的分析,并对其应用的噪声进行了简介。关于图像修复,也是利用了两种算法。并且对其中的快速修复算法进行了较为细致的理论介绍。
  形态学处理模块,对于其理论本文进行了简单明了的介绍。对于其应用,opencv将每一个形态学操作都封装成了函数,直接调用即可。这也是opencv的魅力所在,opencv将许多的较为复杂并且常用的图像处理都封装成了函数,方便学习者花较少的时间的进行快速开发。
滤镜模块,实现了几种常用的滤镜处理,如调色、素描、羽化和扩散。
本平台的局限之处是对于函数的参数调整,必须等用户点击确定按钮之后,程序才会进行处理,没有实现将图片进行实时处理。

目录

目 录
摘 要 1
Abstract 2
1. 绪论 1
1.1 研究图像处理的背景和意义 1
1.2 图像处理的研究现状 3
1.3 本文所做的工作 3
1.4 本文的章节安排 3
1.5 本章小结 4
2. 开发环境与工具介绍 5
2.1 Qt的概述 5
2.1.1 Qt的介绍 5
2.1.2 Qt的特点 5
2.1.3 Qt编程相关技术 6
2.2 OpenCV概述 7
2.2.1 OpenCV的定义 7
2.2.2 OpenCV的特点 7
2.2.3 OpenCV的设计目标 8
2.2.4 OpenCV的结构和内容 8
2.2.5 OpenCV安装 8
2.3 本章小结 11
3. 系统分析与设计 12
3.1 平台的功能架构 12
3.2 本章小结 14
4. 详细设计 15
4.1 图像变换 15
4.1.1 图像镜像变换 15
4.1.2 图像的几何变换 16
4.1.3 图像的缩放 17
4.1.4 图像的截图 19
4.2 图像增强 20
4.2.1 亮度/对比度调整 20
4.2.2 线性滤波 21
4.2.3 非线性滤波 25
4.2.4 图像修复 29
4.3 形态学处理 31
4.3.1 膨胀和腐蚀 31
4.3.2 开运算 33
4.3.3 闭运算 33
4.3.4 形态学梯度 34
4.3.5 顶帽和黑帽 34
4.4 滤镜 35
4.4.1 调色 35
4.4.2 羽化 36
4.4.3 素描 38
4.4.4 扩散 39
4.5 本章小结 39
5. 平台的运行和维护 40
结论 44
参考文献 45
致谢 46
附录A 外文原文 47
附录B 中文翻译 61

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/462769.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git学习记录

目录 Git Git介绍 版本控制 版本控制工具 集中式版本控制工具 分布式版本控制工具 Git工作机制 ​编辑 Git和代码托管中心 Git安装 Git常用命令 设置用户签名 初始化本地库 查看本地库状态 添加到暂存区 提交到本地库 修改文件 历史版本 查看历史版本 版本…

python的opencv最最基础初学

localhost中详解OpenCV的函数imread()和函数imshow(),并利用它们实现对图像的读取和显示_opencv imshow-CSDN博客 其实以下均为numpy 显示一张图片 import cv2 ####opencv读取的格式是BGR import matplotlib.pyplot as plt import numpy as np %matplotlib inline imgcv2.…

“一键解锁复古魅力:底片效果瞬间生成!“

时光荏苒&#xff0c;岁月如梭。你是否曾怀念那些旧时光里&#xff0c;老照片所散发出的独特韵味&#xff1f;那种历经岁月沉淀的底片效果&#xff0c;仿佛能带我们回到那些被遗忘的角落&#xff0c;重温那些温馨的瞬间。 首先第一步&#xff0c;我们要进入视频剪辑高手&#…

算法---滑动窗口练习-6(找到字符串中所有字母异位词)

找到字符串中所有字母异位词 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;找到字符串中所有字母异位词 2. 讲解算法原理 有效字符个数count更新条件&#xff1a;满足【hash1表&#xff08;遍历s的表&#xff09;中对应元素出现次数<hash2表&am…

C语言之归并排序

目录 一 简介 二 代码实现 三 时空复杂度 A.时间复杂度&#xff1a; B.空间复杂度&#xff1a; C.总结&#xff1a; 一 简介 归并排序&#xff08;Merge Sort&#xff09;是一种基于分治策略的高效排序算法&#xff0c;其基本思想是将一个大问题分解为若干个规模较小且相…

RK3568平台开发系列讲解(基础篇)内核是如何发送事件到用户空间

🚀返回专栏总目录 文章目录 一、相关接口函数二、udevadm 命令三、实验沉淀、分享、成长,让自己和他人都能有所收获!😄 一、相关接口函数 kobject_uevent 是 Linux 内核中的一个函数, 用于生成和发送 uevent 事件。 它是 udev 和其他设备管理工具与内核通信的一种方式。…

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

Golang实现Redis分布式锁&#xff08;Lua脚本可重入自动续期&#xff09; 1 概念 应用场景 Golang自带的Lock锁单机版OK&#xff08;存储在程序的内存中&#xff09;&#xff0c;分布式不行 分布式锁&#xff1a; 简单版&#xff1a;redis setnx》加锁设置过期时间需要保证原…

数据结构的概念大合集01(含数据结构的基本定义,算法及其描述)

概念大合集01 1、数据结构基础的定义2、数据结构2.1 数据元素之间关系的集合2.2数据结构的三要素2.2.1数据的逻辑结构2.2.2数据的存储&#xff08;物理&#xff09;结构2.2.3数据的运算 3、数据类型4、抽象数据类型类型&#xff08;ADT&#xff09;5、算法及其描述5.1算法的5个…

ChatGLM3-6B独立部署提供HTTP服务failed to open nvrtc-builtins64_121.dll

背景 我在本地windoes部署ChatGLM3-bB&#xff0c;且希望部署后能提供HTTP server的能力。 模型部署且启动是成功了&#xff0c;但是在访问生成接口/v1/chat/completions时报错failed to open nvrtc-builtins64_121.dll。 问题详细描述 找不到nvrtc-builtins64_121.dll Runtime…

mac电脑修改终端zsh显示的用户名

电脑名称一直没有修改&#xff0c;所以电脑名称都是Apple的MacBook Pro&#xff0c;如下图所示&#xff1a; mac电脑终端显示用户名太长一点也不美观&#xff0c;而且占用很长的行&#xff0c;浪费空间&#xff0c;可以通过修改来调整要显示什么内容&#xff1a; 方式一 要想换…

Windows→Linux,本地同步到服务器

适用背景&#xff1a; 用自己电脑修改代码&#xff0c;使用实验室/公司的服务器炼丹的朋友 优势&#xff1a; 本地 <--> 服务器&#xff0c;实时同步&#xff0c;省去文件传输的步骤 本地改 -> 自动同步到服务器 -> 服务器跑代码 -> 一键同步回本地&#xff…

汽车氛围灯静电浪涌的难点

汽车氛围灯&#xff0c;顾名思义&#xff0c;是烘托车内氛围的照明灯&#xff0c;是汽车内饰情感化设计的一种体现。 一般有暖色&#xff08;红色等&#xff09;和冷色系&#xff08;蓝色、紫色等&#xff09;两种&#xff0c;在夜晚开启后绚丽浪漫&#xff0c;可营造车内情调&…

JSP+Servlet开发汽车租赁管理系统

开发工具&#xff1a;EclipseJdkTomcatSQLServer数据库 链接: https://pan.baidu.com/s/1O5tGguNl6V1CvSpN-amNXA 提取码: exak 如果需要&#xff0c;联系下面的客服人员

SQL的执行与优化

文章目录 MySQL查询原理与优化一、select语句的执行顺序二、join 的执行与优化1、驱动表 & 被驱动表2、Simple Nested Loop Join3、Index Nested Loop Join4、Block Nested Loop Join5、Hash Join6、join 优化小结 三、on 与 where 对比四、group by 的执行与优化1、group …

在Docker容器中配置`code-server`以访问宿主机的Docker环境

在Docker容器中配置code-server以访问宿主机的Docker环境 部分内容使用gpt生成&#xff0c;但经过测试可用。 要在code-server容器内部安全地管理和访问宿主机的Docker环境&#xff08;主要是为了访问宿主机的texlive&#xff09;&#xff0c;遵循以下步骤能够确保流畅的集成和…

Day66:WEB攻防-Java安全SPEL表达式SSTI模版注入XXEJDBCMyBatis注入

目录 JavaSec搭建 Hello-Java-Sec搭建 Java安全-SQL注入-JDBC&MyBatis Java安全-XXE注入-Reader&Builder Java安全-SSTI模版-Thymeleaf&URL Java安全-SPEL表达式-SpringBoot框架 知识点&#xff1a; 1、Java安全-SQL注入-JDBC&MyBatis 2、Java安全-XXE注…

vanna:基于RAG的text2sql框架

文章目录 vanna简介及使用vanna的原理vanna的源码理解总结参考资料 vanna简介及使用 vanna是一个开源的利用了RAG的SQL生成python框架&#xff0c;在2024年3月已经有了5.8k的star数。 Vanna is an MIT-licensed open-source Python RAG (Retrieval-Augmented Generation) fram…

SAP CAP篇十五:写个ERP的会计系统吧,Part II

本文目录 本系列文章目标开发步骤数据库表设计初始数据初始数据&#xff1a;AccountCategories初始数据&#xff1a;AccountUsages初始数据&#xff1a;ChartOfAccounts初始数据&#xff1a;AccountSubjects Service 定义生成Fiori AppApp运行 本系列文章 SAP CAP篇一: 快速创…

【GitHub】使用git链接下载很慢?试试服务器配置SSH,起飞

参考文献 保姆级教学&#xff0c;教你用配置SSH拉取github代码 CentOS ssh -T gitgithub.comgit config --global user.name "learnore" git config --global user.email "15200831505163.com"cd /root/.ssh vim id_rsa.pubGitHub Settings 结果 下载速…

路由器端口转发远程桌面控制:一电脑连接不同局域网的另一电脑

一、引言 路由器端口转发&#xff1a;指在路由器上设置一定的规则&#xff0c;将外部的数据包转发到内部指定的设备或应用程序。这通常需要对路由器进行一些配置&#xff0c;以允许外部网络访问内部网络中的特定服务和设备。端口转发功能可以实现多种应用场景&#xff0c;例如远…
最新文章