一、图像通道
二值图
二值图就是图像的像素点只有0或255,整个图像呈现出只有黑白两种效果。
单通道图:
俗称灰度图,每个像素点只能有一个值表示颜色,他的像素值在 0-255 之间,0 是黑色,255 是白色,中间值是一些不同等级的灰色
三通道图
每个像素点都有 3 个值表示,例如 RGB 图片即为三通道图片,是通过对红(R)、绿(G)、蓝(B)三个颜色通道之间的叠加来得到各式各样的颜色。
三通道图就是平常所见的彩色图。
灰度转化
- 目的
- 将三通道图像(彩色图)转化为单通道图(灰度图)。
公式
- 3 -->1:GRAY = B * 0.114 + G * 0.387 + R * 0.299
- 1 -->3:R = B = G = GRAY;A=0
函数:
cv.cvtColor(img, flag)
参数说明:
三通道转单通道 代码示例:
参数1:待转化图像
参数2:flag 是转换模式,
cv2.COLOR_RGB2GRAY:彩色转灰度
cv2.COLOR_GRAY2RGB:单通道转多通道
#导入 opencv
import cv2
#读入原始图像,使用 cv2.IMREAD_UNCHANGED
img = cv2.imread("girl.jpg", cv2.IMREAD_UNCHANGED)
#查看原始图像
shape = img.shape
print(shape)
#判断通道数是否为 3 或 4 通道
if shape[2] == 3 or shape[2] == 4:
#将彩色图转化为三通道图
img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
cv2.imshow("gray_img", img_gray)
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果演示:
(253, 251, 3)
单通道转三通道灰度图 代码示例:
#导入 opencv
import cv2
#读入原始图像,使用 cv2.IMREAD_UNCHANGED
img = cv2.imread("gray_img.jpg", cv2.IMREAD_UNCHANGED)
#查看原始图像
shape = img.shape
print(shape)
img_color = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
print(img_color.shape) #查看转换后图像通道
cv2.imshow('color_img', img_color)
cv2.imshow("image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
output:
(253, 251)
(253, 251, 3)
通道分离
目的:
将彩色图像,分成 b、g、r ,3 个单通道图像。方便对 BGR 三个通道分别进行操作。
函数:
cv2.split(img)
下面程序将使用 opencv 加载一张彩色图,然后将其 R ,G, B 三通道分离并显示。
代码3: 图像通道分离
代码示例:
- 参数1:待分离通道的图像
- 参数说明:
#导入 opencv
import cv2
src = cv2.imread("split.jpg")
cv2.imshow("before", src)
#调用通道分离
b, g, r = cv2.split(src)
#三通道分别显示
cv2.imshow("blue", b)
cv2.imshow("green", g)
cv2.imshow("red", r)
cv2.waitKey(0)
cv2.destroyAllWindows()
output:
#导入 opencv
import cv2
import numpy as np
image = cv2.imread("split.jpg", 1)
cv2.imshow("src", image)
cv2.waitKey(0)
B, G, R = cv2.split(image) #分离出图片的 BGR 颜色通道
zeros = np.zeros(image.shape[:2], dtype="uint8") #创建与 imgae 大小相同的零矩阵
cv2.imshow("BLUE", cv2.merge([B, zeros, zeros])) #显示 (B, 0, 0)图像
cv2.imshow("GREEN", cv2.merge([zeros, G, zeros])) #显示 (0, G, 0)图像
cv2.imshow("RED", cv2.merge([zeros, zeros, R]))
cv2.waitKey(0)
cv2.destroyAllWindows()
output:
通道合并
- 目的:
通过分离为 B,G,R 后,单独对通道进行修改,最后将修改后的三通道合并为彩色图像。
函数:
cv2.merge(list)
参数说明:
参数1:待合并的通道数,以 list 的形式输入
代码4:图像通道合并
下面代码将使用 R,G,B 三通道合并:
#导入 opencv
import cv2
src = cv2.imread("split.jpg", 1)
cv2.imshow("before", src)
#调用通道分离
b, g, r = cv2.split(src)
#将 blue 通道数值修改为 0
b[:] = 0
#合并修改后的通道
img_merge = cv2.merge([b, g, r])
cv2.imshow('merge', img_merge)
cv2.waitKey(0)
cv2.destroyAllWindows()
output:
可以发现拿掉绿(b)通道后,图片发黄
相应的去掉蓝(g)通道,图片发红
去掉红(r)通道,图片发蓝
代码5:通道分离与合并小结
#导入 opencv
import cv2
src = cv2.imread("split.jpg", 1)
cv2.imshow("before", src)
cv2.waitKey(0)
#调用通道分离
b, g, r = cv2.split(src)
cv2.imshow("blue", b)
cv2.imshow("green", g)
cv2.imshow("red", r)
#通道合并
img_merge = cv2.merge([b, g, r])
cv2.imshow('merge', img_merge)
cv2.waitKey(0)
#修改某个通道
src[:,:,2] = 100
cv2.imshow('single', src)
cv2.waitKey(0)
cv2.destroyAllWindows()
二、图像色彩空间
色彩空间
- RGB 色彩空间:RGB 色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及他们之间相互叠加来得到各式各样的颜色,RGB 即代表红、绿、蓝三个颜色的通道,这个标准几乎包括了人类实力所能感知的所有颜色,是运用最广的颜色系统之一。
- HSV 色彩空间:HSV(Hue,Saturation,Value)是根据颜色的直观特性有 A. R. Smith 在 1978 年创建的一种颜色空间,也称六角锥体模型。这个模型中颜色的参数分别是:色调(H),饱和度(S),明度(V)。
HSV 原理图
- H 通道:hue、色调/色彩,这个通道代表颜色
- S 通道:Saturation,饱和度,饱和度越高,色彩越纯
- V 通道:Value,明暗,数值越高,越明亮
RGB 与 BGR 转化
import cv2
import matplotlib.pyplot as plt
img = cv2.imread("girl.jpg", cv2.IMREAD_COLOR)
cv2.imshow("OPENCV_win", img)
#用 opencv 自带的方法转格式
img_cv_method = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#用 numpy 转
img_numpy_method = img[:,:,::-1] #从 BGR 转为 RGB
#用 Matplot 画图
plt.subplot(1, 2, 1) #在 1 号位置绘图
plt.imshow(img_cv_method)
plt.subplot(1, 2, 2) # 在 2 号位置绘图
plt.imshow(img_numpy_method)
plt.savefig("./plt.png")
plt.show()
#保存图片
cv2.imwrite("opencv.png", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
两种 BGR 转 RGB 方式对比,图像完全相同
代码:RGB 与 HSV 转化
import cv2
#色彩空间转换函数
def color_space_demo(image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
cv2.imshow('hsv', hsv)
src = cv2.imread('girl.jpg')
cv2.imshow('before', src)
#调用color_space_demo
color_space_demo(src)
cv2.waitKey(0)
cv2.destroyAllWindows()
三、图像直方图
直方图绘制
- 目的
直方图是对图像像素的统计分布,它统计了每个像素(0 到 255)的数量。
- 函数
cv2.calcHist(images, channels, mask, histSize, ranges)
- 参数说明
参数1:待统计图像,需用中括号括起来
参数2:待计算的通道
参数3:Mask,这里没有使用,所以用 None
参数4:histSize,表示直方图分成多少份
参数5:表示直方图中各个像素的值,[0.0, 255.0] 表示直方图能表示像素值从 0.0 到 255.0 的像素。直方图是对图像像素的统计分布,他统计了每个像素(0 到 255)的数量。
from matplotlib import pyplot as plt
import cv2
import numpy as np
img = cv2.imread("girl.jpg")
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
plt.imshow(img_gray, cmap=plt.cm.gray)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
plt.figure()
plt.title("Grayscale Histogram")
plt.xlabel("Bins")
plt.ylabel("# of Pixels")
plt.plot(hist)
plt.xlim([0, 256])
plt.show()
图像经过灰度转化,是偏暗的,从直方图可以看出,更接近0
三通道直方图
from matplotlib import pyplot as plt
import cv2
girl = cv2.imread("girl.jpg")
cv2.imshow("girl",girl)
color = ("b", "g", "r")
#使用 for 循环遍历 color 列表,enumerate 枚举返回索引和值
for i, color in enumerate(color):
hist = cv2.calcHist([girl], [i], None, [256], [0, 256])
plt.title("girl")
plt.xlabel("Bins")
plt.ylabel("num of perlex")
plt.plot(hist)
plt.xlim([0, 260])
plt.show()
cv2.waitKey(0)
cv2.destroyAllWindows()
直方图均衡化
- 目的
图像的直方图是对图像对比度效果上的一种处理,旨在使得图像整体效果均匀,黑与白之间的各个像素级之间的电更均匀一点
- 函数
cv2.equalizeHist(img)
- 参数1:待均衡化图像
- 步骤
- 统计直方图中每个灰度级出现的次数
- 计算累计归一化直方图
- 重新计算像素点的像素值
import cv2
img = cv2.imread('dark.jpg', 0)
cv2.imshow("dark",img)
cv2.waitKey(0)
#调用cv2.equalizeHist 函数进行直方图均衡化
img_equal = cv2.equalizeHist(img)
cv2.imshow("img_equal", img_equal)
cv2.waitKey(0)
cv2.destroyAllWindows()
均衡化之后发现,没那么暗了
彩色直方图均衡化
import cv2
import numpy as np
img = cv2.imread('dark.jpg', 1)
cv2.imshow("src",img)
#彩色图像均衡化,需要分解通道 对每一个通道均衡化
(b, g, r) = cv2.split(img)
bH = cv2.equalizeHist(b)
gH = cv2.equalizeHist(g)
rH = cv2.equalizeHist(r)
#合并每一个通道
result = cv2.merge((bH, gH, rH))
cv2.imshow("dst", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
可以发现图片效果明显变化
总结:
核心知识:
- 二值图、灰度图、彩色图的区别
- 三通道与单通道转化
- RGB 和 HSV 之间的转化
- 直方图的意义
- 灰度和彩色图直方图绘制
- 灰度和彩色图像直方图均衡化
欢迎关注公众号!