当前位置: 首页 > news >正文

OpenCV-Python图形图像处理:split通道拆分和数组矩阵访问通道

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░

一、引言

在OpenCV中,图像装载后以矩阵保存,对于灰度图矩阵为二维矩阵,对于彩色图像则为三维矩阵。彩色图像又分为BGR格式和BGRA格式,BGR格式对于像素的蓝、绿、红三个通道,BGRA格式蓝、绿、红三个颜色通道加一个代表透明度的阿尔法通道。有时出于处理需要,需要针对图像矩阵的单个通道进行处理,这时就需要进行图像单通道数据的访问。

二、使用split拆分图像通道

OpenCV提供了专门的通道拆分的函数split,调用语法如下:
split(img, mv=None)
其中的参数为输入图像矩阵,mv是可选的拆分后结果,一般不需要,因为该函数返回的就是拆分的结果。
返回值为一个列表对象,对象的元素个数为输入图像的通道数,每个元素为一个二维矩阵,内容为每个通道的数据。如BGRA格式的图像,则返回4个元素,每个元素分别对应B、G、R、A四个通道的数据。

示例代码:

>>> import cv2
>>> img = cv2.imread(r'f:\pic\ring.png',cv2.IMREAD_UNCHANGED)
>>> img.shape
(742, 1156, 4)
>>> ret = cv2.split(img)
>>> len(ret)
4
>>> B,G,R,A = ret
>>> B
array([[28, 28, 28, ..., 29, 29, 29],
       [28, 28, 28, ..., 29, 29, 29],
       [28, 28, 28, ..., 29, 29, 29],
       ...,
       [35, 35, 35, ..., 35, 35, 35],
       [35, 35, 35, ..., 35, 35, 35],
       [35, 35, 35, ..., 35, 35, 35]], dtype=uint8)
>>> B.shape
(742, 1156)

拆分的通道可以通过merge将其合并成一个图像矩阵,例如对上面拆分的4个通道的BGR通道进行合并,可以执行如下代码:

>>> imgBGR = cv2.merge((B,G,R))
>>> imgBGR.shape
(742, 1156, 3)

三、使用矩阵进行通道数据访问

由于图像在OpenCV中为矩阵,就可以直接使用numpy的矩阵索引来进行矩阵数据的访问。例如要针对输入图像img分别获取BGR通道的数据,可以执行如下代码:

    imgBlueC0 = img[:,:,0]
    imgBlueC1 = img[:, :, 1]
    imgBlueC2 = img[:, :, 2]

四、关于通道拆分的建议

  1. 通道拆分和合并操作对应图像来说处理开销比较大,建议仅在必要时才进行
  2. 对于通道拆分,numpy矩阵索引性能要优于OpenCV,图像越大,numpy矩阵索引性能越优

五、一个通道拆分对比的例子

针对如下图像(文件名:手握蓝球.JPG):
在这里插入图片描述
我们使用两种通道拆分方式分别拆分,然后对比一下拆分结果:

import cv2
import numpy as np

from opencvPublic import preparePreviewImg,previewImgList,previewImg,cmpMatrix,readImgFile

def main():
    imgFName = r'f:\pic\手握蓝球.JPG'

    img = readImgFile(imgFName, False) #自定义读入图片文件的函数,readImgFile(filename,bConvertGray=False,bConvertBinImg=False,bConvertKernal = False)
    imgBlue,imgGreen,imgRed = cv2.split(img)
    imgBlueAnd = cv2.bitwise_and(img,255)
    imgBlueC0 = img[:,:,0]
    imgBlueC1 = img[:, :, 1]
    imgBlueC2 = img[:, :, 2]

    preparePreviewImg(img, imgFName + ': 原图')

    preparePreviewImg(imgBlue, '原图split后B通道')
    preparePreviewImg(imgGreen,  '原图split后G通道')
    preparePreviewImg(imgRed, '原图split后R通道')
    preparePreviewImg(imgBlueAnd, 'imgBlueAnd')
    preparePreviewImg(imgBlueC0, '原图0号通道(B通道)')
    preparePreviewImg(imgBlueC1, '原图1号通道(G通道)')
    preparePreviewImg(imgBlueC2, '原图2号通道(R通道)')

    retB = cmpMatrix(imgBlue, imgBlueC0)
    retG = cmpMatrix(imgGreen, imgBlueC1)
    retR = cmpMatrix(imgRed, imgBlueC2)
    print(f"split拆分图像3通道与图像矩阵数字3通道访问图像比对结果如下:{(retB,retG,retR)}")


    previewImgList()
    cv2.waitKey(5000)

main()

上述代码中从opencvPublic模块导入的函数请参考《https://blog.csdn.net/LaoYuanPython/article/details/111351901:OpenCV-Python图形图像处理:自用的一些工具函数功能及调用语法介绍》的介绍。

执行程序后,运行后显示的图像如下:
在这里插入图片描述
系统输出的文本信息如下:

split拆分图像3通道与图像矩阵数字3通道访问图像比对结果如下:(True, True, True)

从以上结果可以看到,两种拆分方式的通道数据完全相同。另外由于拆分后的通道数据被作为灰度图像对待,因此显示的图像为灰度图。上图中imgBlueAnd 对应图像为彩色图像位于255标量后的结果图像,因为值保留了蓝色通道的值,其他通道的值被置为0,因此显示为整体蓝色的图像。

六、小结

本文介绍了OpenCV图像通道拆分的两种方式,可以看到,OpenCV的split函数和numpy的矩阵索引两种拆分方式得到的结果数据是相同的,但numpy矩阵索引方式性能更好。因此图像通道的拆分非必要不执行,如果要执行,尽量采用numpy矩阵操作。

写博不易,敬请支持:

昨天到今天休假两天,既要处理家里事情,又要处理单位事情,还要写测试代码和博文。写博不易,敬请支持!
如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

更多OpenCV-Python的介绍请参考专栏《OpenCV-Python图形图像处理 》
专栏网址:https://blog.csdn.net/laoyuanpython/category_9979286.html

关于老猿的付费专栏

  1. 付费专栏《https://blog.csdn.net/laoyuanpython/category_9607725.html 使用PyQt开发图形界面Python应用》专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《 https://blog.csdn.net/LaoYuanPython/article/details/107580932 使用PyQt开发图形界面Python应用专栏目录》;
  2. 付费专栏《https://blog.csdn.net/laoyuanpython/category_10232926.html moviepy音视频开发专栏 )详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/107574583 moviepy音视频开发专栏文章目录》;
  3. 付费专栏《https://blog.csdn.net/laoyuanpython/category_10581071.html OpenCV-Python初学者疑难问题集》为《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《https://blog.csdn.net/LaoYuanPython/article/details/109713407 OpenCV-Python初学者疑难问题集专栏目录 》。

前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《https://blog.csdn.net/laoyuanpython/category_9979286.html OpenCV-Python图形图像处理 》的学习使用。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《https://blog.csdn.net/laoyuanpython/category_9831699.html 专栏:Python基础教程目录)从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学OpenCV!

☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython ░

相关文章:

  • Python图像处理:OpenCV HSV和标准表示法的区别以及转换
  • OpenCV-Python图像处理:用inRange刷选图像中指定颜色对象案例
  • PyQt事件信号实战:为QTableWidget提供键盘事件
  • OpenCV-Python图像处理:区分前景背景权重的图像融合案例
  • 2020年总结:平安辞旧岁,老牛自奋蹄!
  • OpenCV-Python图像处理:插值方法及使用resize函数进行图像缩放
  • Python3装饰器的隐秘角落
  • 一种利用Python库解决视频课程检测窗口是否活动的简单方法
  • 人工智能数学基础6:极限、极限运算、ε-δ语言、ε-N语言、级数和函数连续性
  • 人工智能数学基础专栏目录
  • 人工智能数学基础8:两个重要极限及夹逼定理
  • 人工智能数学基础9:集合相关概念
  • 人工智能数学基础10:域、函数及相关概念
  • 人工智能数学基础-线性代数1:向量及向量加减法与数乘
  • 人工智能数学基础-线性代数2:向量的点积、內积、数量积和外积
  • JS 中的深拷贝与浅拷贝
  • [Vue CLI 3] 配置解析之 css.extract
  • 【译】理解JavaScript:new 关键字
  • Django 博客开发教程 8 - 博客文章详情页
  • iOS 系统授权开发
  • Java教程_软件开发基础
  • Linux中的硬链接与软链接
  • Zsh 开发指南(第十四篇 文件读写)
  • 好的网址,关于.net 4.0 ,vs 2010
  • 简单基于spring的redis配置(单机和集群模式)
  • 那些年我们用过的显示性能指标
  • 如何在GitHub上创建个人博客
  • 使用iElevator.js模拟segmentfault的文章标题导航
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • ​VRRP 虚拟路由冗余协议(华为)
  • ​渐进式Web应用PWA的未来
  • $.proxy和$.extend
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (2015)JS ES6 必知的十个 特性
  • (4)事件处理——(7)简单事件(Simple events)
  • (C语言)逆序输出字符串
  • (day6) 319. 灯泡开关
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (五)网络优化与超参数选择--九五小庞
  • (转)人的集合论——移山之道
  • .NET Framework与.NET Framework SDK有什么不同?
  • .Net 中的反射(动态创建类型实例) - Part.4(转自http://www.tracefact.net/CLR-and-Framework/Reflection-Part4.aspx)...
  • .NET 中让 Task 支持带超时的异步等待
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • .net打印*三角形
  • .net反混淆脱壳工具de4dot的使用
  • .net解析传过来的xml_DOM4J解析XML文件
  • .net开发引用程序集提示没有强名称的解决办法
  • .php文件都打不开,打不开php文件怎么办
  • :O)修改linux硬件时间
  • @AutoConfigurationPackage的使用
  • [ SNOI 2013 ] Quare
  • [100天算法】-二叉树剪枝(day 48)
  • [3300万人的聊天室] 作为产品的上游公司该如何?