Q1-通道交换
1.1 先导知识
1. cv2的imread()读取是按BGR顺序排列的;
2. 单通道的灰色图像的表示方法是二维灰度矩阵:高度*宽度;
3. 三通道的彩色图像的表示方法是三维BGR/RGB矩阵:高度*宽度*通道;
4. 为了方便处理可以将三通道彩色图像矩阵分通道表示,即分为三个二维矩阵。
1.2 实现代码
import cv2
def BGR2RGB(img):
b = img[:,:,0].copy() #第一个通道b
g = img[:,:,1].copy() #第二个通道g
r = img[:,:,2].copy() #第三个通道r
img[:,:,0] = r
img[:,:,1] = g
img[:,:,2] = b
return img
img = cv2.imread('imori.jpg')
print(img)
print('\n')
img_trans = BGR2RGB(img)
print(img_trans)
cv2.imwrite('answer_1.jpg',img_trans)
cv2.imshow('result',img_trans)
cv2.waitKey(0)
cv2.destroyAllWindow()
1.3 结果分析
原图像(左),通道变换后图像(右)
(未经过转换读出来的图像矩阵“第一条”数据)
(经过通道转换后的“第一条”数据)
可见第三维度的数据与第一维度的数据发生了交换,也就是原来的BGR变成了RGB。
Q2-灰度化
2.1 先导知识
1. 计算公式:Y = 0.2126*R + 0.7152*G + 0.0722*B;
2. 为了方便处理,将图像分通道表示(经常会用到);
3. 注意最后计算出来的结果是数值矩阵,我们要将其转换为可以作为图像来处理的数据格式unit8。
2.2 代码实现
def BGR2GREY(img):
b = img[:, :, 0].copy()
g = img[:, :, 1].copy()
r = img[:, :, 2].copy()
#灰度转换
out = 0.2126*r + 0.7152*g + 0.0722*b
#将out转换成能作为图像矩阵来处理的数据格式
out = out.astype(np.uint8)
return out
2.3 结果分析
可与三通道的BGR矩阵对比着来看,灰度矩阵是二维矩阵,每个元素代表的是该像素点的灰度值。
Q3-二值化
3.1 先导知识
1. 二值化的意思就是对灰度化的图像设置一个灰度值阈值,当像素点灰度值大于这个阈值时,将该点灰度值改为255,小于阈值时,则改成0。也就是说,将灰度值二极化,最终呈现出来的就是一副黑白图像;
2. 灰度值为0——白,灰度值为255——黑。
3.2 代码实现
def binarization(img, th = 128):
lens = len(img)
for i in range(lens-1):
for j in range(lens-1):
if img[i,j] < th:
img[i,j] = 0
else:
img[i,j] = 255
return img
'''另一种简单方法:
def binarization(img, th = 128):
img[img < th] = 0
img[img >= th] = 255'''
3.3 结果分析
Q4-Otsu阈值分割算法(最大类间方差法)
4.1 先导知识
Otsu算法原理:通过统计学的方法来选取一个阈值,使前景色和背景色尽可能地分开。
最优分割判断依据:最大类间方差(intra-class variance or the variance within the class)
设整个图像灰度平均值为M。现在任意选取一个灰度值 t,则可以将这个直方图分成前后两部分。我们称这两部分分别为 A 和 B。对应的就是前景色和背景色。这两部分各自的平均值成为 MA 和 MB。A 部分里的像素数占总像素数的比例记作 PA,B部分里的像素数占总像素数的比例记作 PB。
Nobuyuki Otsu给出的类间方差定义为:
ICV=PA∗(MA−M)^2+PB∗(MB−M)^2
等价公式(推导见参考资料):
ICV=PA*PB*(MA-MB)^2
遍历每一个可能的灰度值阈值,找到使类间方差最大的灰度阈值,则为目标最优分割阈值。
4.2 代码实现
#otsu阈值分割算法(最大类间方差法)
def otsu_thresh(img):
max_vari = -1 #初始化最大类间方差
max_th = 0 #初始化最佳阈值
for th in range(1,254):
m0 = img[img <= th].mean()
m1 = img[img > th].mean()
w0 = img[img <= th].size
w1 = img[img > th].size
vari = w0*w1/((w0+w1)**2)*((m0-m1)**2)
if vari > max_vari:
max_th = th
max_vari = vari
img_otsu = binarization(img, max_th)
return img_otsu, max_th
4.3 结果分析
参考资料
Q1 CV2模块使用(详细教程)_Zhangfei Wang-CSDN博客_cv2
Q2 Opencv: numpy中uint8类型存储图像_宁静致远*的博客-CSDN博客_np.unit8
Q4 灰度图像的自动阈值分割(Otsu 法)_Ivan 的专栏-CSDN博客_otsu阈值分割算法;
大津阈值分割算法(OTSU处理图像)_我的博客-CSDN博客_大津阈值分割