彩色图像RGB三通道问题探究

之前做图像问题研究时经常会提到RGB通道,这次做一个小研究,对最底层的东西深究一二……

直接上全部代码吧,一点点来:


   
   
     
     
     
     
  1. # -*- coding: utf-8 -*-
  2. import cv2
  3. img=cv2.imread( "0017.png")
  4. print(img)
  5. print(img.shape)
  6. b=img[:,:, 0]
  7. g=img[:,:, 1]
  8. r=img[:,:, 2]
  9. print(b)
  10. b,g,r=cv2. split(img) #拆分通道
  11. cv2.imshow( 'original',img)
  12. cv2.imshow( 'B',b)
  13. cv2.imshow( 'G',g)
  14. cv2.imshow( 'R',r)
  15. m1=cv2.merge([b,g,r]) #按照bgr合并通道
  16. m2=cv2.merge([r,g,b]) #按照rgb合并通道
  17. cv2.imshow( 'BGR',m1)
  18. cv2.imshow( 'RGB',m2)
  19. cv2.waitKey() #等待键盘输入,不调用此方法则显示的图像将会一闪而逝
  20. cv2.destroyAllWindows() #销毁所有窗口
  21. print(b)
  22. print(b.shape)

从头开始,我们用到了cv2模块,及opencv的python版本,在anaconda中安装即可,注意不能直接使用conda install cv2命令,会提示找不到模块,可以使用conda install --channel https://conda.anaconda.org/menpo opencv命令,亲测可以顺利安装,当然你也可以使用Anaconda Navigator安装,也很方便;

一开始遇到两个问题,由于我的路径带有斜杠,然后就报错了:

解决方式有两种:1.在路径前加上‘r’;(r是保持字符串原始值的意思,就是说不对其中的符号进行转义。因为windows下的目录字符串中通常有斜杠"\",而斜杠在Python的字符串中有转义的作用。---转自网络)

2.将单斜杠改为双斜杠;还有的博文说使用单反斜杠最佳,linux和windows通吃,大家可以试一下

然后运行又报错了:

运行第四行(空行不算,从import cv2开始计算)代码print(img.shape)出错了,没有shape属性,那肯定是img有问题,先输出一下img(第三行代码):

哎呦,显示none,查了一下原来是我的路径中有中文,emmm,这是一个古老的问题……

将照片放到程序所在的文件夹,直接引用了名称,然后运行第三行和第四行代码,没问题了:

可以看到print(img)后输出的是一连串的数字,又查了下imread()的返回值,说的比较杂,大概就是像素值吧,从形式上来看应该是每个像素三通道的值,这个在后边会有体现,再看下print(img.shape):

是个三元组,对比下照片的信息:

显而易见,输出的是(高度,宽度,通道数)

5~8行代码是简单提取了三个通道,这种用法一开始不大理解,搜了些资料,云里雾里,img[x,x,x]到底是个啥,咱们一究到底,增加了几行测试代码:


   
   
     
     
     
     
  1. q=img[ 0,:,:]
  2. # print(b)
  3. print(q)
  4. print(img[ 0,:,:].size)
  5. print(img[ 0,:,:].shape)

看下结果:

有没有发现点什么,看下输出的q是不是上边输出img的第一部分,大小为1650,形状是550*3,考一下大家的空间想象能力,三张550*483的图像叠加在一块,也就是三个单通道合一块,宽为550像素,也就是一行有550个像素,共483行,三个通道共有550*483*3个像素,我们现在取的是第一行(准确地说是第0行),也就是550*3个像素,每个像素由一个三元组表示,比如[51 52 56],这正对应着三个通道,也就是说每个像素都有rgb三个通道,这样大小也就是550*3=1650。

ok,继续往下走,第八行的代码输出b,看下效果:

对比一下输出的img,可以看出,b正是img第一列的大集合,以此类推可以看出g和r为img第二列和第三列的集合,倒数第二行代码也输出了b(在运行此行时注释了第八行),结果显示和第八行的是一样的,都是拆分了img的rgb通道,这里的一个大问题就是rgb通道的顺序,正确的应该是gbr,这个查了下文档,说法不一,有点甚至都没有说明,大家看下第二块代码就能看到,尝试了各种方法去测试,但这有问题,比如我拆分img后依次赋值给bgr,然后再融合,那即使正确的通道顺序为rgb也没啥用,相当于将r赋给了b,这样结果也没有说服力,不过我看到有的博主已经做了很多实验,使用plt调用时默认的rgb,如果直接融合bgr会出问题,这一点大家可以去查一下,现在就默认正确的通道顺序是bgr吧……(这一块说的有点乱,核心思想就是探究正确的通道顺序到底是rgb还是bgr)

 

看下最后的效果:

 大家可以看到,如果通道搞错的话是和原图不一样的,但也挺好看。。至于RGB三张单通道的图很多盆友会问为啥不是红色绿色和蓝色的,emmm,这一点大家可以去百度一下,讲的很清楚,我大致截个图吧:

所以每个单通道都是一张灰度图……

最后一行代码输出一下b通道的形状,大家应该能想到,是一个矩形~~

ok,大致就是这些了,总的来说RGB三通道就是一个三维空间的结合,图像中的每一个像素点都是三个通道合力所致,这对图像的研究是最基本的,相信以后还会有新的发现。

ps.对两部分代码最好分开运行,避免不必要的干扰,运行一部分时先注释掉另一部分,用ctrl+1即可快速多行注释,注释块的话用ctrl+4即可。


小小滴更新一点,大家可能发现了matlab中也有imread()方法,那和cv2的有啥区别呢,前者读入的通道顺序是RGB,而后者是BGR,有兴趣的同学可以试验一下。

你可能感兴趣的:(图像处理算法及OpenCV)