[Python图像处理] 三.获取图像属性、兴趣ROI区域及通道处理

2021-12-02 21:07:25 浏览数 (1)

该系列文章是讲解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容器
代码语言:javascript复制
# -*- 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])
代码语言:javascript复制
# -*- 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图像处理

0 人点赞