1.2 opencv图像处理基本操作

在图像处理过程中.读取图像、显示图像、保存图像足最葙木的操作。本节将简单介绍这 几项基本操作。

1.2.1读取图像

OpenCV提供了函数CV2.imread()来读取图像,该函数支持各种静态阁像格式。该函数的语 法格式为

retval = cv2.imread( filename[, flags])

式中:

• retval 是返冋值,其值足读取到的图像。如果未读取到阁像,则返回“None”。
• filename表示要读取的图像的完整文件名。
• (lags足读収标记。该标记用来控制读取文件的类型,具体如表所示。表 中的第 一列参数与第三列数值是等价的。例如cv2.1MREAD_UNCHANGED=-l,在设置参数 时,既可以使用第一列的参数值,也可以采用第三列的数值。

序号 含义 数值
1 cv2.IMRFAD_UNCHANGED 保持格式不变 -1
2 cv2.IMRHAD_GRAVSCALE 将图像调整为单通道的灰度图像 0
3 cv2.1MREAD_COLOR 将图像调整为3通道的BGR图像,该值是默认值 1
4 cv2.IMREAD_ANYDCPTH 当载入的图像深度为16位或者32位时.就返回其对应的深 度图像:否则,将其转换为8位图像 2
5 cv2.IMREAD_ANVCOLOR 以任何可能的颜色格式读取图像 4
6 cv2.IMKEAD_LOAD_GDAI 使用gdal驱动程序加载图像 8
7 cv2.IMREAD_REDUCED_GRAYSCALE_2 将图像转换为单通道灰度图像,并将图像尺寸减小1/2
8 cv2.IMREAD_REDUCED_COIOR_2 将图像转换为3通道BGR彩色图像,并将图像尺寸减小1/2
9 cv2.IMREAD_REDUCED_GRAYSCALE _4 始终将图像转换为单通道灰度图像,并将图像尺寸减小为原1/4丨
10 cv2.IMREAD_REDUCED_COLOR_4 将图像转换为3通道BGR彩色图像,并将图像尺寸减小1/4
11 cv2.rMREAD_REDUCED_GRAYSCALE_8 始终将图像转换为单通道灰度图像,并将图像尺寸减小为原1/8
12 cv2.IMREAD_REDUCED_COLOR_8 将图像转换为3通道BGR彩色图像,并将图像尺寸减小1/8
13 cv2.IMREAD_IGNORE_ORIENTATION 不以EXIF的方向为标记旋转图像

cv2.imread()函数支持的图像格式

序号 图像 扩展名
1 windows位图 .bmp,.dib
2 JPEG文件 .jpeg、.jpg、*.jpe
3 JPEG2000文件 *.jp2
4 便携式网络图形 文件 *.png
5 WebP文件 *.webp
6 便携式图像格式 .pbm、.pgm、.ppm、.pxm、*.pnm
7 sun格式 .sr、.ras
8 TIFF文件 *.tiff, *tif
9 OpenEXR图像文件 *.exr
10 Radiance 格式高动态范围成像图像 *.hdr , *.pic
11 GDAL支持的栅格和矢址地理空间数椐 Raster、Vector 两大类

例如,想要读取当前目录下文件名为lena.bmp的图像,并保持按照原有格式读入,则使用 的语句为:


lena=cv2.imread("lena.bmp",-1);

需要注意,上述程序要想正确运行,首先需要导入cv2模块,大多数常用的OpenCV函数 都在CV2模块内。与cv2模块所对应的cv模块代表传统版本的模块。这里的cv2模块并不代表 该模块是专门针对OpenCV 2版本的,而是指该模块引入了一个改善的API接口。在cv2模块 内部釆用了面向对象的编程方式,而在cv模块内更多采用的是面向过程的编程方式。

本书中所使用的模块函数都是cv2模块函数,为了方便理解,在函数名前面加了 “cv2.”。 但是如果函数名出现在标题中,那么希望突出的是该函数本身,所以未加“cv2.”。

【例1.1】使用cv2.imread()函数读取一幅图像。

根据题目要求,编写代码如下:

import cv2
lena=cv2.imread(“lenacolor.png")
print(lena)

上述程序首先读取当前目录下的图像lena.bmp 然后使用print语句打印读取的图像数据,运行上述程序
会输出图像的部分像素值

1561037795(1).png

1.2.2 显示图像

OpenCV提供了多个与显示有关的函数,下面对常用的几个进行简单介绍。

1.namedWindow 函数

函数cv2.namedWindow()用来创建指定名称的窗口,其语法格式为:

None = cv2.namedWindow( winname )

式中,winname是要创建的窗口的名称。

例如,下列语句会创建一个名为lesson的窗口 :

cv2.namedWindow (''lesson")

2.imshow 函数

函数cv2.imshow()用来显示图像,其语法格式为:

None = cv2.imshow( winname, mat )

式中:
1.winname是窗口名称。
2.mat是要显示的图像。

【例1.2】

在一个窗口内显示读取的图像。
根据题目耍求,编写代码如下:


import cv2

lena=cv2.imread("lena.bmp") 
cv2.namedWindow("lesson") 
cv2.imshow("lesson", lena )

#不暂停无法正常查看图片
cv2.waitKey (0) 

在本程序中,首先通过 cv2.imread函数读取图像 lena.bmp,接下来通过 cv2.namedWindow()函数创建一个名为 lesson 的窗口,最后通过cv2.imshow()函数在窗口 lesson 内显示图像 lena.bmp
运行上述程序,得到的运行结果如图 1-3 所示

1561038704(1).png

在实际使用中,可以先通过函数 cv2.namedWindow()来创建一个窗口,再让图 cv2.imshow引用该窗口来显示图像。也可以不创建窗口,直接使用函数cv2.imshow引用不存在的窗口,并在其中显示指定图像,这样函数cv2.imshow()实际上会完成如下两步操作

第1步:函数 cv2.imshow()创建一个指定名称的新窗口。
第2步:函数cv2 imshow()将图像显示在刚创建的窗口内。

例如,在下面的语句中,函数cv2.imshow()完成了创建demo窗口和显示 Image图像的
作,该语句的功能与例1.2相同。


import cv2
lena=cv2.imread("lena.bmp") 
cv2.imshow("demo", lena )

在显示图像时,初学者最经常遇到的一个错误是“cror:(-215: Assertion failed) sIzewidth:&& size height in function ' cv; imshow",说明当前要显示的图像是空的(None),这通常是由于在读取文件时没有找到图像文件造成的。一般来说,没有找到要读取的图像文件,可能是因为文件名错误:如果确认要读取的图像的完整文件名(路径名和文件名)没有错,那么往往是工作路径配置错误造成的。

例如,当前程序所在路径为 e:\lesson,要读取当前路径下存在的图像 image \lena. bmp。那如果设置的当前工作路径是 e:\lesson,程序就会读取当前工作路径下的文件imagel\lena. bmp.该文件的完整文件名就是 e:\lesson\imagel\lena,bmp.正是我们想要读
的指定文件如果设置的当前工作路径不是 e: \lesson,例如,当前的工作路径是 e: \python,程序仍会读取当前工作路径下的文件 Image \ lena. bmp(而不是读取当前程序所在路径下的image\lena.bmp) 该文件的完整文件名就是 e:\python\image\lena.bmp 显然 这样是无法读取到指定图像的

为了理免上述错误,可以在读取图像前判图像文件是否存在,并在显示图像前判断图像 是否存在

3. waitKey 函数

函数 cv2.waitKey() 用来等待按键,当用户按下键盘后,该语句会被执行,并获取返回值
其语法格式为


retval = cv2.waitKey([delay])

式中
1.retval 表示返回值。如果没有按键被按下,则返回-1;如果有按键被按下,则返回该按键的ASCII码
2.delay 表示等付键盘触发的时间,单位是 ms 当该值是负数或者零时,表示无限等待, 该值的默认值为0
在实际使用中,可以通过函数 cv2.waitKey()获取按下的按键,并针对不同的键做出不同的反应,从而实现交互功能。例如,如果按下A键,则关闭窗口 如果按下B键,则生成一个窗口副本

下面通过一个示例演示如何通过函数 cv2.waitKey() 实现交互功能

【例 1.3】在一个窗口内显示图像,并针对按下的不同按键做出不同的反应

函数 cv2.waitKey()能够获取按键的 ASCII码,例如,如果该函数的返回值为 97,表示按 下了键盘上的字母a键。通过将返回值与 ASCII码值进行比较,就可以确定是否按下了某个特定的键

例,通过语句 “返回值==97” 就可以判断是否按下了字母a键

Python 是供了函数 ord(),用来获取字符的 ASCII 码值,因此,在判断是否按下了某个特定的按键时,可以先使用 ord()函数获取该特定字符的 ASCII码值,再将该值与cv2.waitKey() 数的返回值进行比较,从而确定是合按下了某个特定的键,这样,在程序设计中就不需要ASCII 值的直接参与了,从而避免了使用 ASCII 进行比较可能带来的不便。例如,要判断是否 按下了字母A键,可以直接使用“返回值== ord("A") 语句来完成

根题目要求及以上分析,写代码如


import cv2
lena=cv2.imread("lena.bmp") 
cv2.imshow("demo", lena )
key = cv2.waitKey()

if key  == ord('A'):
  cv2.imshow("PressA",lena)
elif key == ord('B'):
  cv2.imshow("PressB",lena)   

运行上述程序,按下键盘上的A 键或者B键,会在一个新的窗口内显示图像 lena.bmp
们的不同之处在于:

如果按下的是键盘上的A键,则新出现的窗口名称为PressA

如果按下的是键盘上的B键,则新出现的窗口名称为PressB

从另外一个角度理解,该函数还能够让程序实现暂停功能。当程序运行到该语句时,会按照参数 delay的设定等待特定时长。根据该值的不同,可能有不同的情况:

1.如果参数 delay 的值为 0,则程序会一直等待。直到有按下键盘按键的事件发生时,才会执行后续程序。
2.如果参数 delay 的值为一个正数,则在这段时间内,程序等待按下键盘按键,当有按下键盘按键的事件发生时,就继续执行后续程序语句:如果在 delay 参数所指定的时间内直没有这样的事件发生,则超过等待时间后,继续执行后续的程序语句。

【例 1.4】在一个窗口内显示图像,用函数 cv2.waitKey()实现程序暂停,在按下键盘的按键后让程序继续运行

根据题目要求,编写代码如下


    import cv2
    lena=cv2.imread("lena.bmp") 
    cv2.imshow("demo", lena )
    key = cv2.waitKey()

    if key  == -1:
        print("触发了按键")

运行上述程序,首先会在一个名为 demo 的窗口内显示 lena. bmp 图像,在未按下键盘上的按键时,程序没有新的状态出现:当按下键盘上的任意一个按键后,会在控制台打印“触发了按键”。

在本例中,由于 cv2.waitKey() 函数的参数值是默认值 0,所以在未按下键盘上的技键时程序会一直处于暂停状态,当按下键盘上的任意一个按键时,程序中 key ==cv2.waitKey() 下方的语句便得以执行,程序输出“触发了按键“。

4. destroyWindow 函数

函数 cv2.destroyWindow () 用来释放(销毁)指定窗口,其语法格式为

None = cv2.destroyWindow (winname)
其中, winname 是窗口的名称

在实际使用中,该函数通常与函数 cv2.waitKey() 组合实现窗口的释放

【例 1.5】编写一个程序,演示如何使用函数 cv2.destroyWindow () 释放窗口

根据题目要求,编写代码如下


    import cv2
    lena=cv2.imread("lena.bmp") 
    cv2.imshow("demo", lena )
    key = cv2.waitKey()
    cv2.destroyWindow ("demo") 

运行上述程序,首先会在一个名为 demo 的窗口内显示 ena.bmp 图像,在程序运行的过程中,当未按下键盘上的按键时,程序没有新的状态出现:当按下键盘上的任意一个按键后,窗 口 demo 会被释放.

5. destroyAllWindows 函数

函数 cv2.destroyAllWindows () 用来释放(销段)所有窗口,其语法格式为

None=cv2.destroyAllWindows () 

【例 1.6】写一个程序,演示如何使用函数cv2.destroyAllWindows () 释放所有窗口 根据题目要求,编写代码如下


    import cv2
    lena=cv2.imread("lena.bmp") 
    cv2.imshow("demo", lena )
    cv2.imshow("demo2", lena )
    key = cv2.waitKey()
    cv2.destroyAllWindows () 

运行上述程序,会分别出现名称为 demol和 demo2 的窗口,在两个窗口中显示的都 是ena.bmp图像,在未按下键盘上的按键时,程序没有新的状态出现:当按下键盘上的任意一个按键后,两个窗口都会被释放

1.2.3 保存图像

OpenCV 提供了函数 cv2.imwrite(),用来保存图像,该函数的语法格式为:

retval = cv2.imwrite( filename , img[, params])

式中:
1.retval 是返回值。如果保存成功,则返回逻辑值真(True):如果保存不成功,则返回逻辑值假( False)。

2.filename 是要保存的目标文件的完整路径名,包含文件扩展名.

3.img是被保存图像的名称

4.params 是保存类型参数 是可选的

【例 1.7】编写一个程序,将读取的图像保存到当前日录下

根据题目要求,编写代码如下



    import cv2
    lena=cv2.imread("lena.bmp") 
    r =cv2.imwrite( "result.bmp",lena)

上述程序会先读取当前目录下的图像 lena.bmp,生成它的一个副本图像,然后将该图像以名称 result.bmp 存储到当前目录下.

日前 OpenCV 库包含如下两部分

1.OpenCV 主库:即通常安装的 OpenCV库,该库是成熟稳定的,由核心的 OpenCV团

2.OpenCV 页献库:该扩展库的名称为 OpenCV_contrib,主要由社区开发和维护,其包含 的视觉应用比 OpenCV主库更全面。需耍注意的是,OpenCV 贡献库中包合非 OpenCV 许的部分,并且包含受专利保护的算法。因此,在使用该模块前需要特别注意。

OpenCV 贡献库中包含了非常多的扩展模块,举例如下

  1. bioinspired 生物视觉模块
    2.datasets 数据集读取模块
    3.dnn 深度神经网络模块
    4.face 人脸识別模块
    5.matlab MATLAB 接口模块。
    6.stereo 双目立体匹配模块
    7.text 视觉文本匹配模块
    8.tracking 基于视觉的目标跟踪模块
    9.ximgpro 图像处理扩展模块
    10 xobjdetect 增强 2D 目标检测摸块
  2. xphoto 计算摄影扩展模块
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容