该系列文章是讲解Python OpenCV图像处理知识,前期主要讲解图像入门、OpenCV基础用法,中期讲解图像处理的各种算法,包括图像锐化算子、图像增强技术、图像分割等,后期结合深度学习研究图像识别、图像分类应用。希望文章对您有所帮助,如果有不足之处,还请海涵~
该系列在github所有源代码:
- https://github.com/eastmountyxz/ ImageProcessing-Python
前一篇文章介绍了OpenCV和Numpy图像处理基础知识,包括读取像素和修改像素,以及几何图形绘制。这篇文章主要讲解Python调用OpenCV获取图像属性,截取感兴趣ROI区域,处理图像通道。知识点如下:
- 一.获取图像属性
- 二.获取感兴趣ROI区域
- 三.图像通道处理
- 四.图像类型转换
一.获取图像属性
图像最常见的属性包括三个:图像形状(shape)、像素大小(size)和图像类型(dtype)。
1.形状-shape 通过shape关键字获取图像的形状,返回包含行数、列数、通道数的元祖。其中灰度图像返回行数和列数,彩色图像返回行数、列数和通道数。如下图所示:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy
#读取图片
img = cv2.imread("yxz.png", cv2.IMREAD_UNCHANGED)
#获取图像形状
print(img.shape)
#显示图像
cv2.imshow("Demo", img)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果如下图所示:(445L, 670L, 3L),该图共445行、670列像素,3个通道。
2.像素数目-size 通过size关键字获取图像的像素数目,其中灰度图像返回行数 * 列数,彩色图像返回行数 * 列数 * 通道数。代码如下:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy
#读取图片
img = cv2.imread("yxz.png", cv2.IMREAD_UNCHANGED)
#获取图像形状
print(img.shape)
#获取像素数目
print(img.size)
输出结果:
- (445L, 670L, 3L)
- 894450
3.图像类型-dtype
通过dtype关键字获取图像的数据类型,通常返回uint8。代码如下:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy
#读取图片
img = cv2.imread("yxz.png", cv2.IMREAD_UNCHANGED)
#获取图像形状
print(img.shape)
#获取像素数目
print(img.size)
#获取图像类型
print(img.dtype)
输出结果:
- (445L, 670L, 3L)
- 894450
- uint8
二.获取感兴趣ROI区域
ROI(Region of Interest)表示感兴趣区域,是指从被处理图像以方框、圆形、椭圆、不规则多边形等方式勾勒出需要处理的区域。可以通过各种算子(Operator)和函数求得感兴趣ROI区域,被广泛应用于热点地图、人脸识别、图像分割等领域。如图获取Lena图的脸部轮廓。
通过像素矩阵可以直接获取ROI区域,如img[200:400, 200:400]。
代码如下:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#定义200*100矩阵 3对应BGR
face = np.ones((200, 100, 3))
#显示原始图像
cv2.imshow("Demo", img)
#显示ROI区域
face = img[200:400, 200:300]
cv2.imshow("face", face)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果如下图所示:
下面将提取的ROI图像进行融合实验,代码如下:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
#定义300*100矩阵 3对应BGR
face = np.ones((200, 200, 3))
#显示原始图像
cv2.imshow("Demo", img)
#显示ROI区域
face = img[100:300, 150:350]
img[0:200,0:200] = face
cv2.imshow("face", img)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
将提取的头部融合至图像左上角部分,如下图所示:
如果想将两张图像进行融合,只需再读取一张图像即可,方法原理类似。代码如下:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("yxz.jpg", cv2.IMREAD_UNCHANGED)
test = cv2.imread("na.jpg", cv2.IMREAD_UNCHANGED)
#定义300*100矩阵 3对应BGR
face = np.ones((200, 200, 3))
#显示原始图像
cv2.imshow("Demo", img)
#显示ROI区域
face = img[100:300, 150:350]
test[400:600,400:600] = face
cv2.imshow("Pic", test)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果如下图所示:
三.图像通道处理
OpenCV通过split()函数和merge()函数实现对图像通道的处理,包括通道分离和通道合并。
1.通道拆分-split OpenCV读取的彩色图像由B、G、R三原色组成,可以通过下面代码获取不同的通道。
- b = img[:, :, 0]
- g = img[:, :, 1]
- r = img[:, :, 2]
也可以使用split()函数拆分通道,下面是拆分不同通道再显示的代码。
- mv = split(m[, mv]) – m表示输入的多通道数组 – mv表示输出的数组或vector容器
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("Lena.png")
#拆分通道
b, g, r = cv2.split(img)
#显示原始图像
cv2.imshow("B", b)
cv2.imshow("G", g)
cv2.imshow("R", r)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
显示结果如图所示,它展示了B、G、R三个通道的颜色分量。
也可以获取不同通道颜色,核心代码为:
- b = cv2.split(a)[0]
- g = cv2.split(a)[1]
- r = cv2.split(a)[2]
2.通道合并-merge
该函数是split()函数的逆向操作,将多个数组合成一个通道的数组,从而实现图像通道的合并,其函数原型如下:
- dst = merge(mv[, dst]) – mv表示输入的需要合并的数组,所有矩阵必须有相同的大小和深度 – dst表示输出的具有与mv[0]相同大小和深度的数组
核心代码如下:
- m = cv2.merge([b, g, r])
# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("Lena.png")
#拆分通道
b, g, r = cv2.split(img)
#合并通道
m = cv2.merge([b, g, r])
cv2.imshow("Merge", m)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果如下,它将拆分的B、G、R三个通道的颜色分量进行了合并,接着显示合并后的图像。
注意,如果是合并[r,g,b]三通道,则显示如下所示,因OpenCV是按照BGR进行读取的。
- b, g, r = cv2.split(img)
- m = cv2.merge([r, g, b])
- cv2.imshow(“Merge”, m)
同时,可以提取图像的不同颜色,提取B颜色通道,G、B通道设置为0,则显示蓝色。代码如下所示:
代码语言:javascript复制# -*- coding:utf-8 -*-
import cv2
import numpy as np
#读取图片
img = cv2.imread("test.jpg", cv2.IMREAD_UNCHANGED)
rows, cols, chn = img.shape
#拆分通道
b = cv2.split(img)[0]
g = np.zeros((rows,cols),dtype=img.dtype)
r = np.zeros((rows,cols),dtype=img.dtype)
#合并通道
m = cv2.merge([b, g, r])
cv2.imshow("Merge", m)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
蓝色通道输出结果如下所示:
绿色通道核心代码及输出结果如下所示:
- rows, cols, chn = img.shape
- b = np.zeros((rows,cols), dtype=img.dtype)
- g = cv2.split(img)[1]
- r = np.zeros((rows,cols), dtype=img.dtype)
- m = cv2.merge([b, g, r])
红色通道修改方法与上面类似。
四.图像类型转换
在日常生活中,我们看到的大多数彩色图像都是RGB类型,但是在图像处理过程中,常常需要用到灰度图像、二值图像、HSV、HSI等颜色。图像类型转换是指将一种类型转换为另一种类型,比如彩色图像转换为灰度图像、BGR图像转换为RGB图像。OpenCV提供了200多种不同类型之间的转换,其中最常用的包括3类,如下:
- cv2.COLOR_BGR2GRAY
- cv2.COLOR_BGR2RGB
- cv2.COLOR_GRAY2BGR
OpenCV提供了cvtColor()函数实现这些功能。其函数原型如下所示:
- dst = cv2.cvtColor(src, code[, dst[, dstCn]]) – src表示输入图像,需要进行颜色空间变换的原图像 – dst表示输出图像,其大小和深度与src一致 – code表示转换的代码或标识 – dstCn表示目标图像通道数,其值为0时,则有src和code决定
该函数的作用是将一个图像从一个颜色空间转换到另一个颜色空间,其中,RGB是指Red、Green和Blue,一副图像由这三个通道(channel)构成;Gray表示只有灰度值一个通道;HSV包含Hue(色调)、Saturation(饱和度)和Value(亮度)三个通道。在OpenCV中,常见的颜色空间转换标识包括:
- CV_BGR2BGRA
- CV_RGB2GRAY
- CV_GRAY2RGB
- CV_BGR2HSV
- CV_BGR2XYZ
- CV_BGR2HLS
下面是调用cvtColor()函数将图像进行灰度化处理的代码。
代码语言:javascript复制#encoding:utf-8
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取图片
src = cv2.imread('Lena.png')
#图像类型转换
result = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
#显示图像
cv2.imshow("src", src)
cv2.imshow("result", result)
#等待显示
cv2.waitKey(0)
cv2.destroyAllWindows()
输出结果如图所示,它将左边的彩色图像转换为右边的灰度图像,更多灰度转化的算法参考后续文章。
同样,可以调用 :
- grayImage = cv2.cvtColor(src, cv2.COLOR_BGR2HSV)
核心代码将彩色图像转换为HSV颜色空间,如图所示。
下面代码对比了九种常见的颜色空间,包括BGR、RGB、GRAY、HSV、YCrCb、HLS、XYZ、LAB和YUV,并循环显示处理后的图像。
代码语言:javascript复制# -*- coding: utf-8 -*-
# By: Eastmount CSDN 2021-01-26
import cv2
import numpy as np
import matplotlib.pyplot as plt
#读取原始图像
img_BGR = cv2.imread('na.png')
#BGR转换为RGB
img_RGB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2RGB)
#灰度化处理
img_GRAY = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2GRAY)
#BGR转HSV
img_HSV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HSV)
#BGR转YCrCb
img_YCrCb = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2YCrCb)
#BGR转HLS
img_HLS = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2HLS)
#BGR转XYZ
img_XYZ = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2XYZ)
#BGR转LAB
img_LAB = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2LAB)
#BGR转YUV
img_YUV = cv2.cvtColor(img_BGR, cv2.COLOR_BGR2YUV)
#调用matplotlib显示处理结果
titles = ['BGR', 'RGB', 'GRAY', 'HSV', 'YCrCb', 'HLS', 'XYZ', 'LAB', 'YUV']
images = [img_BGR, img_RGB, img_GRAY, img_HSV, img_YCrCb,
img_HLS, img_XYZ, img_LAB, img_YUV]
for i in range(9):
plt.subplot(3, 3, i 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
其运行结果如图所示:
五.总结
写到这里,这篇毒基础性文章就介绍结束了。希望文章对大家有所帮助,如果有错误或不足之处,还请海涵。本文首发于CSDN专栏,为了帮助更多同学故在公众号同步更新,一起加油!
- 一.获取图像属性
- 二.获取感兴趣ROI区域
- 三.图像通道处理
- 四.图像类型转换
参考文献:
- [1] 罗子江. Python中的图像处理[M]. 科学出版社,2020.
- [2] https://blog.csdn.net/eastmount/category_9278090.html
- [3] 冈萨雷斯. 数字图像处理(第3版)[M]. 电子工业出版社,2013.
- [4] 阮秋琦. 数字图像处理学(第3版)[M]. 电子工业出版社,2008.
- [5]毛星云,冷雪飞. OpenCV3编程入门[M]. 电子工业出版社,2015.
- [6]张铮. 数字图像处理与机器视觉——Visual C 与Matlab实现.
- [6]网易云课堂_高登教育. Python OpenCV图像处理