概述
什么是数字图像?
我们可以用一个二维函数 f ( x , y ) f(x,y) f(x,y)来定义一张图像,其中 ( x , y ) (x,y) (x,y)是空间坐标,任意一对空间坐标 ( x , y ) (x,y) (x,y)处的幅值 f f f称为图像在该点的强度或灰度。特别地,当 x , y x,y x,y和灰度值 f f f都是有限的离散值时,我们称该图像为数字图像。
比特平面
数字图像中每一个像素点的灰度值通常用8bits来存储,所以一共有256个灰度级。需要注意的是,我们一般用无符号八位整型来存储灰度值,在numpy中的数据类型为uint8,无符号数的最高位不代表符号,一个n位的无符号数的表示范围为 0∼2????−1 ,为了更好地理解无符号数,我们需要知道什么是有符号数,这里介绍两种有符号数的表示方式:
a) 原码
在机器中,数的正负号是无法识别的,我们一般规定“0”代表正数,“1”代表负数,并约定二进制数的最高位为符号数,即将符号位放在有效数字的前面组成有符号数。原码就是一种有符号数的表示方式,原码的最高位为符号位,n位的原码表示范围为 −2????−1+1∼2????−1−1 ,例如8位的原码表示范围为 −127∼127 ,0110 0011表示99,1110 0011表示-99。
b) 补码
计算机中有符号数大多都是以补码的形式存储,因为原码不好做减法,而补码做减法却很方便。一个n位的补码表示范围为 −2????−1∼2????−1−1 ,补码的最高位同样为符号位,正的补码与原码相同,对于负数来说,我们先用原码表示除这个负数,然后对符号位外的每位取反,最后加1就可以得到该数的补码。例如补码的0110 0011同样表示99,要表示-99我们需要先写出-99的原码,即1110 0011,除符号位之外每位取反:1001 1100,最后加1: 1001 1101就是-99的补码。
颜色组成
- 彩色图
我们通常用R(红)、G(绿)、B(蓝)三个通道来表示一张彩色图像,也就是说,一张彩色图像由三个函数
R
(
x
,
y
)
R(x, y)
R(x,y)、
G
(
x
,
y
)
G(x, y)
G(x,y)和
B
(
x
,
y
)
B(x, y)
B(x,y)组成。如果每个通道的灰度值用8bits来存储,那一张彩色图像总共可以表示$2^{8+8+8}=16777216 $种颜色,这就是经常所说的“24位真彩色” 。
- 灰度图
彩色图像是由R、G、B三通道组成的图片,灰度图(如图(a))就是单通道图片。彩色图像可以通过著名的心理学公式转换为灰度图:
G r a y = 0.299 × R + 0.587 × G + 0.114 × B Gray = 0.299times R + 0.587 times G + 0.114 times B Gray=0.299×R+0.587×G+0.114×B
OpenCV基本操作
1.读取图片
import cv2
import numpy as np
img = cv2.imread('images/doge.png')
img.shape
#输出结果:(446, 1678, 3)
默认是彩色图片,图片路径中不能包含中文,读出的数据结构是numpy数组。446是三维数组的第一个维度,对应图片的高;1678是三维数组的第二个维度,对应图片的宽;3对应图片的通道数,这里是彩色图片所以为3。其中读取方式还有以下两种:
含义 | 数字表示 |
---|---|
加载一张灰度图 | 0 |
加载图像,包括它的Alphat通道 | -1 |
gray = cv2.imread('images/doge.png', 0) # 第二个参数为0读取为灰度图片,
gray.shape#输出结果(446, 1678)
2.显示图片
- cv2.imshow(‘窗口名’,‘numpy数组’)
cv2.imshow('origin', img) # 显示彩色图,第一个参数是窗口名,第二个参数是图像所对应的numpy数组
cv2.imshow('gray', gray) # 显示灰度图
cv2.waitKey(0)
cv2.destroyAllWindows() # 关闭窗口,默认删除所有窗口
cv2.waitKey里面的参数为等等时间,单位为毫秒,参数为0或负数为按任意键继续。
3.保存图片
- cv2.imwrite(‘文件名’, numpy数组)
需要注意文件名要带后缀名,比如jpg,png等等。
4.灰度转换及改变通道顺序
转换为灰度图
其目的是把三通道(彩色图)转换为单通道图像(灰度图),可以通过通过著名的心理学公式转换为灰度图。对于灰度图来说,0对应黑色,255对应白色,灰度值越大对应颜色越白(亮),越小颜色越黑(暗)。
- cv2.cvtColor(img, flag)
flag | 解释 |
---|---|
cv2.COLOR_GRAY2RGB | 单通道转三通道 |
cv2.COLOR_BGR2GRAY | 彩色转灰度图 |
cv2.COLOR_BGR2RGB | BGR转RGB |
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('origin', rgb)
cv2.waitKey(0)
cv2.destroyAllWindows()
运行结果:
可以知道,由三通道转为为单通道,按任意键即可关闭窗口。
改变通道顺序
因为历史原因,OpenCV读取和显示的图片通道顺序为B、G、R,而其他包如matplotlib和Pillow通道顺序为RGB,所以如果我们想用OpenCV读取图片再用matplotlib或Pillow显示的话,需要将BGR转化为RGB。将BGR转为RGB主要有下面两种方式:
- 使用opencv自带的方法
import matplotlib.pyplot as plt
rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)#cv2.COLOR_BGR2RGB
plt.subplot(1,2,1)
plt.imshow(rgb)
plt.subplot(1,2,2)
plt.imshow(img)
运行结果:
其左边为已经转换成RGB在利用matplotlib绘图,右边是BGR顺序,可以发现图片轮廓没有什么差别,颜色有明显的区别。
-使用numpy
# 方法一:
rgb1 = img[:, :, ::-1] # ::-1代表倒序,BGR倒序后就为RGB
# 方法二:
rgb2 = img[:, :, [2, 1, 0]] # 利用索引将B和R调换位置
cv2.imshow('rgb1', rgb1)
cv2.imshow('rgb2', rgb2)
cv2.waitKey(0)
cv2.destroyAllWindows()
笔者在学习时经常会对img输出的数组产生疑惑,比如哪个是通道哪个是图片的形状等等,接下来请看下面的图片:
红色方框总共有446个,下面看一个简答的例子,总的来说,里面的二维数组可以看成是3个通道的侧面积。
5.通道分离
把彩色图像分离出R、G、B3个通道,方便后续对三个通道分别进行其他的操作
- cv2.split(img)
img:待分离通道的图像
B,G,R=cv2.split(img)
cv2.imshow('blue',B)
cv2.imshow('green',G)
cv2.imshow('red',R)
cv2.waitKey(0)
cv2.destroyAllWindows()
#思考:为什么不是蓝色、绿色、红色的三张图片
6.通道合并
通道分离修改后,把三个通道合并成彩色图像
- cv2.merge([])
B,G,R=cv2.split(img)
B[:]=0
R[:]=0
Img_merge=cv2.merge([B,G,R])
cv2.imshow('merge',Img_merge)
cv2.waitKey(0)
cv2.destroyAllWindows()
同时可以发现,如果只绘制单通道的一张图片,那么是灰度图,如果想看单通道所显示的颜色,需要把另外两个通道px赋值为0在绘制
最后
以上就是笑点低老师为你收集整理的【OpenCV】学习笔记1-图像基础知识以及OpenCV基本操作的全部内容,希望文章能够帮你解决【OpenCV】学习笔记1-图像基础知识以及OpenCV基本操作所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复