[Python从零到壹] 三十四.OpenCV入门详解——显示读取修改及保存图像

网友投稿 936 2022-05-29

该系列文章主要讲解Python OpenCV图像处理和图像识别知识,前期主要讲解图像处理基础知识、OpenCV基础用法、常用图像绘制方法、图像几何变换等,中期讲解图像处理的各种运算,包括图像点运算、形态学处理、图像锐化、图像增强、图像平滑等,后期研究图像识别、图像分割、图像分类、图像特效处理以及图像处理相关应用。

上一篇文章介绍了图像处理基础知识,这篇文章将详细讲解OpenCV入门知识,包括OpenCV常见数据类型、显示图像、读取像素、修改像素、创建图像、复制图像、保存图像等内容。希望文章对您有所帮助,如果有不足之处,还请海涵。接下来,让我们开启整个系列的学习吧!

文章目录

一.什么是图像处理

二.图像处理基础

三.Python语言

四.OpenCV安装和基础

五.总结

-:

https://github.com/eastmountyxz/Python-zero2one

前文赏析:

第一部分 基础语法

[Python从零到壹] 一.为什么我们要学Python及基础语法详解

[Python从零到壹] 二.语法基础之条件语句、循环语句和函数

[Python从零到壹] 三.语法基础之文件操作、CSV文件读写及面向对象

第二部分 网络爬虫

[Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例

[Python从零到壹] 五.网络爬虫之BeautifulSoup基础语法万字详解

[Python从零到壹] 六.网络爬虫之BeautifulSoup爬取豆瓣TOP250电影详解

[Python从零到壹] 七.网络爬虫之Requests爬取豆瓣电影TOP250及CSV存储

[Python从零到壹] 八.数据库之MySQL基础知识及操作万字详解

[Python从零到壹] 九.网络爬虫之Selenium基础技术万字详解

[Python从零到壹] 十.Selenium爬取在线百科知识万字详解(NLP语料构造必备技能)

第三部分 数据分析和机器学习

[Python从零到壹] 十一.数据分析之Numpy、Pandas、Matplotlib和Sklearn入门知识万字详解

[Python从零到壹] 十二.机器学习之回归分析万字总结

[Python从零到壹] 十三.机器学习之聚类分析万字总结全网首发(K-Means、BIRCH、层次聚类、树状聚类)

[Python从零到壹] 十四.机器学习之分类算法五万字总结全网首发(决策树、KNN、SVM、分类对比实验)

[Python从零到壹] 十五.文本挖掘之数据预处理、Jieba工具和文本聚类万字详解

[Python从零到壹] 十六.文本挖掘之词云热点与LDA主题分布分析万字详解

[Python从零到壹] 十七.可视化分析之Matplotlib、Pandas、Echarts入门万字详解

[Python从零到壹] 十八.可视化分析之Basemap地图包入门详解

[Python从零到壹] 十九.可视化分析之热力图和箱图绘制及应用详解

[Python从零到壹] 三十四.OpenCV入门详解——显示读取修改及保存图像

[Python从零到壹] 二十.可视化分析之Seaborn绘图万字详解

[Python从零到壹] 二十一.可视化分析之Pyechart绘图万字详解

[Python从零到壹] 二十二.可视化分析之OpenGL绘图万字详解

[Python从零到壹] 二十三.十大机器学习算法之决策树分类分析详解(1)

[Python从零到壹] 二十四.十大机器学习算法之KMeans聚类分析详解(2)

[Python从零到壹] 二十五.十大机器学习算法之KNN算法及图像分类详解(3)

[Python从零到壹] 二十六.十大机器学习算法之朴素贝叶斯算法及文本分类详解(4)

[Python从零到壹] 二十七.十大机器学习算法之线性回归算法分析详解(5)

[Python从零到壹] 二十八.十大机器学习算法之SVM算法分析详解(6)

[Python从零到壹] 二十九.十大机器学习算法之随机森林算法分析详解(7)

[Python从零到壹] 三十.十大机器学习算法之逻辑回归算法及恶意请求检测应用详解(8)

[Python从零到壹] 三十一.十大机器学习算法之Boosting和AdaBoost应用详解(9)

[Python从零到壹] 三十二.十大机器学习算法之层次聚类和树状图聚类应用详解(10)

第四部分 Python图像处理基础

[Python从零到壹] 三十三.图像处理基础篇之什么是图像处理和OpenCV配置

[Python从零到壹] 三十四.OpenCV入门详解——显示读取修改及保存图像

第五部分 Python图像运算和图像增强

第六部分 Python图像识别和图像处理经典案例

第七部分 NLP与文本挖掘

第八部分 人工智能入门知识

第九部分 网络攻防与AI安全

第十部分 知识图谱构建实战

扩展部分 人工智能高级案例

一.OpenCV常见数据类型

OpenCV是一个轻量级高效的跨平台计算机视觉库,实现了图像处理和计算机视觉方面的多种通用算法。所谓的图像可以理解为一个数组,图像处理就是对数组的处理。首先,本文将介绍OpenCV中常见的数据类型,包括点Point类、颜色Scalar类、尺寸Size类、矩形Rect类、矩阵Mat类[1-2]。

1.点Point

表示二维坐标系中的点,含x和y。其示例如下:

#OpenCV示例 Point p; p.x=1, p.y=2; Point p=Point(1, 2); #Python示例 points_list = [(160, 160), (136, 160)]

2.颜色Scalar

包含四个元素的数组,设置像素值RGB三通道,第四个参数可忽略。其示例如下:

#OpenCV示例 BGR三分量 Scalar(b, g, r); #Python示例 (0, 0, 255)

3.尺寸Size

它和Point相似,主要成员包括height和width。其示例如下:

#OpenCV示例 Size(5, 5); Size_(_Tp _width, _Tp _height); #Python示例 width, height = img.shape

4.矩形Rect

Rect类称为矩形类,包含Point类的成员x和y(代表矩形左上角的坐标)和Size类的成员width和height(代表矩形的大小)。其示例如下:

#OpenCV示例 Rect rect = rect1 & rect2; #求两矩形交集 Rect rect = rect1 | rect2; #求两矩形并集 Rect rectShift = rect + point; #矩形平移 Rect rect = rect1 + size; #矩形缩放 #Python示例 cv2.rectangle(img, (20,20), (150,250), (255,0,0), 2)

5.矩阵Mat

通用的矩阵类,用来创建和操作多维矩阵。其示例如下:

#OpenCV示例 Mat M(3,2, CV_8UC3, Scalar(0,0,255)); #Python示例 np.zeros((256,256,3), np.uint8)

二.OpenCV读取与显示图像

在OpenCV2中,图像的读取和显示是最简单的两句代码,它们通过imread()和imshow()函数实现[3]。OpenCV读取图像的imread()函数原型如下,它将从指定的文件加载图像并返回矩阵,如果无法读取图像(因为缺少文件、权限不正确、格式不支持或图像无效等),则返回空矩阵(Mat::data==NULL)。

retval = imread(filename[, flags])

– filename表示需要载入的图片路径名,其支持Windows位图、JPEG文件、PNG图片、便携文件格式、Sun rasters光栅文件、TIFF文件、HDR文件等。

flags为int类型,表示载入标识,它指定一个加载图像的颜色类型,默认值为1。其中cv2.IMREAD_UNCHANGED表示读入完整图像或图像不可变,包括alpha通道;cv2.IMREAD_GRAYSCALE表示读入灰度图像;cv2.IMREAD_COLOR表示读入彩色图像,默认参数,忽略alpha通道。

OpenCV中显示图像调用imshow()函数,它将在指定窗口中显示一幅图像,窗口会自动调整为图像大小,其原型如下所示:

imshow(winname, mat)

– winname表示窗口的名称

– mat表示要显示的图像

下面是第一个示例程序,主要用于读取和加载经典的“Lena”图像。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 #读取图片 img = cv2.imread("Lena.png") #显示图像 cv2.imshow("Demo", img) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()

输出结果如图2-1所示:

需要注意,在图像显示过程中,如果代码中没有waitKey(0)函数,其运行结果可能会出现错误,加载一幅灰色的图像,如图2-2所示。

因此,在显示图像过程中,通常还会调用两个操作窗口的函数,它们分别是waitKey()和destroyAllWindows()。

retval = waitKey([, delay])

– 键盘绑定函数,共一个参数delay,表示等待的毫秒数,看键盘是否有输入,返回值为ASCII值。如果其参数为0,则表示无限期的等待键盘输入;参数大于0表示等待delay毫秒;参数小于0表示等待键盘单击。

destroyAllWindows()

– 该函数可以轻易删除所有建立的窗口。如果你想删除特定的窗口可以使用 cv2.destroyWindow(),并在括号内输入要删除的窗口名。

同时,可以设置加载图像后无限期等待,直到输入指定的按键才退出窗口,如下面的代码需要输入ESC才退出。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 #读取图片 img = cv2.imread("Lena.png") #显示图像 cv2.imshow("Demo", img) #无限期等待输入 k=cv2.waitKey(0) #如果输入ESC按键退出 if k==27: cv2.destroyAllWindows()

此外,在对比实验中,我们通常需要显示多张图片,此时可以调用NumPy和Matplotlib库辅助完成[4],具体实现过程如下所示。

NumPy(Numeric Python)是Python提供的数值计算扩展包,拥有高效的处理函数和数值编程工具,主要用于科学计算,如矩阵数据类型、线性代数、矢量处理等。

Matplotlib是Python强大的数据可视化工具和2D绘图库,常用于创建海量类型的2D图表和一些基本的3D图表,类似于MATLAB和R语言。Matplotlib提供了一整套和Matlab相似的命令API,十分适合交互式地进行制图,而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中。Matplotlib是一名神经生物学家John D. Hunter博士于2007年创建,函数设计上参考了Matlab,现在在Python的各个科学计算领域都得到了广泛应用。

该程序是调用cv2.imread()函数分别读取四张图片,并转换为RGB颜色空间,接着通过for循环分别设置各子图对应的图像、标题及坐标轴名称,其中plt.subplot(2,2)表示生成2×2张子图。

# -*- coding: utf-8 -*- # By:Eastmount import cv2 import numpy as np import matplotlib.pyplot as plt #读取图像 img1 = cv2.imread('lena.png') img1 = cv2.cvtColor(img1, cv2.COLOR_BGR2RGB) img2 = cv2.imread('xluo.png') img2 = cv2.cvtColor(img2, cv2.COLOR_BGR2RGB) img3 = cv2.imread('flower.png') img3 = cv2.cvtColor(img3, cv2.COLOR_BGR2RGB) img4 = cv2.imread('huawei.png') img4 = cv2.cvtColor(img4, cv2.COLOR_BGR2RGB) #显示四张图像 titles = ['lena', 'people', 'flower', 'huawei'] images = [img1, img2, img3, img4] for i in range(4): plt.subplot(2, 2, i+1), plt.imshow(images[i], 'gray') plt.title(titles[i]) plt.xticks([]),plt.yticks([]) plt.show()

输出如图2-3所示,它显示了四幅图像。在图像处理对比中,同时对比多种算法的处理效果是非常重要的手段之一。

三.OpenCV像素处理

OpenCV中读取图像的像素值可以直接通过遍历图像的位置实现,如果是灰度图像则返回其灰度值,如果是彩色图像则返回蓝色(B)、绿色(G)、红色(G)三个分量值。其示例如下:

灰度图像:返回值 = 图像[位置参数]

示例:test=img[88,42]

彩色图像:返回值 = 图像[位置元素, 0 | 1 | 2 ]获取BGR三个通道像素

示例:blue=img[88,142,0] green=img[88,142,1] red=img[88,142,2]

当需要修改图像中的像素时,则定位指定像素并直接赋新像素值即可,彩色图像需要依次给三个分量赋值。如下列代码所示。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 #读取图片 img = cv2.imread("Lena.png") #读取像素 test = img[88,142] print("读取的像素值:", test) #修改像素 img[88,142] = [255, 255, 255] print("修改后的像素值:", test) #分别获取BGR通道像素 blue = img[88,142,0] print("蓝色分量", blue) green = img[88,142,1] print("绿色分量", green) red = img[88,142,2] print("红色分量", red) #显示图像 cv2.imshow("Demo", img) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()

读取的像素值及修改后的像素值结果如图2-4所示。

下面代码是将100到200行、150到250列的像素区域设置为白色的效果。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 #读取图片 img = cv2.imread("Lena.png") #该区域设置为白色 img[100:200, 150:250] = [255,255,255] #显示图像 cv2.imshow("Demo", img) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()

图2-5是最终显示的效果图,它将img[100:200, 150:250] 区域显示为白色。

四.NumPy像素处理

前面是直接读取和修改图像像素的方法,下面讲解通过NumPy库读取像素和修改像素的方法。NumPy是Python提供的数值计算扩展包,拥有高效的处理函数和数值编程工具,Array是NumPy库中最基础的数据结构,表示数组。NumPy可以很方便地创建各种不同类型的多维数组,并且执行一些基础操作。

在图像处理中,NumPy读取像素调用item()函数实现,修改像素调用itemset()实现,其原型如下所示[5]。使用Numpy进行像素读取,调用方式如下:

返回值 = 图像.item(位置参数)

例如:blue = img.item(78, 100, 0)

使用Numpy的itemset函数修改像素,调用方式如下:

图像.itemset(位置, 新值)

例如:img.itemset((88,99), 255)

最终实现代码如下所示。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy #读取图片 img = cv2.imread("Lena.png") print(type(img)) #Numpy读取像素 print(img.item(78, 100, 0)) print(img.item(78, 100, 1)) print(img.item(78, 100, 2)) #Numpy修改像素 img.itemset((78, 100, 0), 100) img.itemset((78, 100, 1), 100) img.itemset((78, 100, 2), 100) print(img.item(78, 100, 0)) print(img.item(78, 100, 1)) print(img.item(78, 100, 2))

输出结果如下所示,原始图像BGR像素值为88、84、196,修改后的像素值为100、100、100。

88 84 196 100 100 100

五.OpenCV创建图像

由于在OpenCV2中没有CreateImage函数,如果需要创建图像,则需要使用Numpy库函数实现。如下述代码,调用np.zeros()函数创建空图像,创建的新图像使用Numpy数组的属性来表示图像的尺寸和通道信息,其中参数img.shape表示原始图像的形状,np.uint8表示类型。

emptyImage = np.zeros(img.shape, np.uint8)

例如img.shape为(500, 300, 3),它表示500×300像素的图像,3表示这是一个RGB图像。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 img = cv2.imread("Lena.png") #创建空图像 emptyImage = np.zeros(img.shape, np.uint8) #显示图像 cv2.imshow("Demo", emptyImage) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()

显示结果如图2-6所示,这是一幅新创建的“空白”图像。

六.OpenCV复制图像

复制原有图像来获取一幅新图像,可以调用copy()函数实现。

emptyImage2 = img.copy()

下述代码实现了图像的创建和复制功能。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图片 img = cv2.imread("Lena.png") #创建空图像 emptyImage = np.zeros(img.shape, np.uint8) #复制图像 emptyImage2 = img.copy() #显示图像 cv2.imshow("Demo1", img) cv2.imshow("Demo2", emptyImage) cv2.imshow("Demo3", emptyImage2) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()

最终输出结果如图2-7所示,Demo1表示原始图像,Demo2表示创建的空白图像,Demo3表示复制的图像。

七.OpenCV保存图像

在OpenCV中,输出图像到文件使用的函数为imwrite(),其函数原型如下:

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

– filename表示要保存的路径及文件名

– img表示图像矩阵

– params表示特定格式保存的参数编码,默认值为空。对于JPEG图片,该参数(cv2.IMWRITE_JPEG_QUALITY)表示图像的质量,用0-100的整数表示,默认值为95。对于PNG图片,该参数(cv2.IMWRITE_PNG_COMPRESSION)表示的是压缩级别,从0到9,压缩级别越高,图像尺寸越小,默认级别为3。对于PPM、PGM、PBM图片,该参数表示一个二进制格式的标志(cv2.IMWRITE_PXM_BINARY)[2]。注意,该类型为Long,必须转换成int。

下面是一个调用imwrite()函数输出图像到指定的文件的代码。

# -*- coding:utf-8 -*- # By:Eastmount import cv2 import numpy as np #读取图像 img = cv2.imread("Lena.png") #显示图像 cv2.imshow("Demo", img) #保存图像 cv2.imwrite("dst1.jpg", img, [int(cv2.IMWRITE_JPEG_QUALITY), 5]) cv2.imwrite("dst2.jpg", img, [int(cv2.IMWRITE_JPEG_QUALITY), 100]) cv2.imwrite("dst3.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 0]) cv2.imwrite("dst4.png", img, [int(cv2.IMWRITE_PNG_COMPRESSION), 9]) #等待显示 cv2.waitKey(0) cv2.destroyAllWindows()

原始图像“Lena.jpg”为222KB,调用imwrite()函数输出保存的图像共四张,如图2-8所示,其中“dst1.jpg”被压缩,大小为4.90KB,“dst2.jpg”图像大小为99.1KB,“dst3.png”大小为499KB,“dst4.png”大小为193KB。

八.总结

写到这里,这篇文章就介绍结束。本文详细介绍了OpenCV图像处理的基础用法,包括图像读取、显示、像素处理、创建、复制、写入和保存。通过这篇文章,初学者将学会基本的图像处理操作,代码比较简单,但希望大家一定要自己动手实现所有代码和案例,只有不断实践才能提升。

感谢在求学路上的同行者,不负遇见,勿忘初心。

感恩能与大家在华为云遇见!

希望能与大家一起在华为云社区共同成长,原文地址:https://blog.csdn.net/Eastmount/article/details/122654530

(By:娜璋之家 Eastmount 2022-02-28 夜于武汉)

参考文献:

[1] 冈萨雷斯. 数字图像处理(第3版)[M]. 北京:电子工业出版社, 2013.

[2] 阮秋琦. 数字图像处理学(第3版)[M]. 北京:电子工业出版社,2008.

[3] Eastmount. [Python图像处理] 一.图像处理基础知识及OpenCV入门函数[EB/OL]. (2018-08-16). https://blog.csdn.net/Eastmount/article/details/81748802.

[4] 杨秀璋, 颜娜. Python网络数据爬取及分析从入门到精通(分析篇)[M]. 北京:北京航天航空大学出版社, 2018.

[5] Eastmount. [Python图像处理] 二.OpenCV+Numpy库读取与修改像素[EB/OL]. (2018-08-28). https://blog.csdn.net/eastmount/article/details/82120114.

OpenCV Python

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Linux系统常用命令,指令详解及案例
下一篇:Java面向对象知识点拆分(二)
相关文章