【图像处理100题】Q1-Q10学习记录(待完善)

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 结果分析

【图像处理100题】Q1-Q10学习记录(待完善)【图像处理100题】Q1-Q10学习记录(待完善)
原图像(左),通道变换后图像(右)

【图像处理100题】Q1-Q10学习记录(待完善)

(未经过转换读出来的图像矩阵“第一条”数据)

【图像处理100题】Q1-Q10学习记录(待完善)

 (经过通道转换后的“第一条”数据)

 可见第三维度的数据与第一维度的数据发生了交换,也就是原来的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 结果分析

【图像处理100题】Q1-Q10学习记录(待完善)
灰度化后的图像
【图像处理100题】Q1-Q10学习记录(待完善)
灰度矩阵

可与三通道的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 结果分析

【图像处理100题】Q1-Q10学习记录(待完善)
二值化后图像

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博客_大津阈值分割

上一篇:Thymeleaf常用语法


下一篇:阿里研究员谷朴:API 设计最佳实践的思考