之前做图像问题研究时经常会提到RGB通道,这次做一个小研究,对最底层的东西深究一二……
直接上全部代码吧,一点点来:
-
# -*- coding: utf-8 -*-
-
import cv2
-
-
img=cv2.imread(
"0017.png")
-
print(img)
-
print(img.shape)
-
b=img[:,:,
0]
-
g=img[:,:,
1]
-
r=img[:,:,
2]
-
print(b)
-
-
b,g,r=cv2.
split(img)
#拆分通道
-
cv2.imshow(
'original',img)
-
cv2.imshow(
'B',b)
-
cv2.imshow(
'G',g)
-
cv2.imshow(
'R',r)
-
m1=cv2.merge([b,g,r])
#按照bgr合并通道
-
m2=cv2.merge([r,g,b])
#按照rgb合并通道
-
cv2.imshow(
'BGR',m1)
-
cv2.imshow(
'RGB',m2)
-
cv2.waitKey()
#等待键盘输入,不调用此方法则显示的图像将会一闪而逝
-
cv2.destroyAllWindows()
#销毁所有窗口
-
print(b)
-
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]到底是个啥,咱们一究到底,增加了几行测试代码:
-
q=img[
0,:,:]
-
#
print(b)
-
print(q)
-
print(img[
0,:,:].size)
-
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,有兴趣的同学可以试验一下。