Opencv_100问_第二章 (6-10)

6. 减色处理

减色处理就是将图片的256 ^ 3个色调变成 4 ^ 3个色调,也就是将原来每个通道256个颜色级分成四个区间压缩到4个颜色级,这四个灰度级是给出的.分别是32, 96, 160,224.

pix = 32  (0 <= pix < 64)  
pix = 96  (64 <= pix < 128)
pix = 160 (128 <= pix < 192)
pix = 224 (192 <= pix < 256)

可以得到一个公式就是

pix = (int)(pix/64)*64 + 32

代码部分:

# @Time   : 2022/6/9 13:46
# @Author : Fioman
# @Phone  : 13149920693
# @Tips   : Talk is Cheap,Show me the code! ^_^^_^
from settings import *


# Dicrease color
def dicrease_color(image):
    """
    对图像进行减色处理
    :param image:
    :return:
    """
    out = image.copy()
    out = out // 64 * 64 + 32
    return out

if __name__ == '__main__':
    imagePath = os.path.join(OPENCV_100_Q_PATH,"gray_01.bmp")
    imageOriginal = cv.imread(imagePath,cv.IMREAD_COLOR)
    imageDicrease = dicrease_color(imageOriginal)
    cv.imshow("ImageOriginal",imageOriginal)
    cv.imshow("ImageDicrease",imageDicrease)
    cv.waitKey(0)

7. 平均池化(Average Pool)

将图片按照固定大小网格分割,网格内的像素值取网格内所有像素的平均值.
我们将这种把图片使用均等大小网格分割,并求网格内代表值的操作叫做池化(Pooling).
池化操作是 卷积神经网络(Convolutional Neural Network)中重要的图像处理方式.平均池化按照下式定义:


请把大小为128 * 128 的图片使用 8 * 8 的网格做平均池化,平均池化是把该区域内所有的像素值全部改为平局值

# @Time   : 2022/6/9 14:10
# @Author : Fioman
# @Phone  : 13149920693
# @Tips   : Talk is Cheap,Show me the code! ^_^^_^

from settings import *


def average_pooling(image, G=8):
    out = image.copy()

    if len(image.shape) == 3:
        H, W, C = image.shape
    else:
        H, W = image.shape[:2]
        C = []

    newW = int(W / G)
    newH = int(H / G)

    for y in range(newH):
        for x in range(newW):
            if C != []:
                for c in range(C):
                    out[G * y:G * (y + 1), G * x:G * (x + 1), c] = 
                    			np.mean(out[G * y, G * (y + 1), G * x:G * (x + 1), c]).astype(np.uint8)
            else:
                out[G * y:G * (y + 1), G * x:G * (x + 1)] = 
                		np.mean(out[G * y:G * (y + 1), G * x:G * (x + 1)]).astype(np.uint8)
    return out


if __name__ == '__main__':
    imagePath = os.path.join(OPENCV_100_Q_PATH, "gray_01.bmp")
    imageOriginal = cv.imread(imagePath, cv.IMREAD_GRAYSCALE)
    averPoolImage = average_pooling(imageOriginal, 8)
    cv.imshow("Original", imageOriginal)
    cv.imshow("AverPoolImage", averPoolImage)
    cv.waitKey(0)

8. 最大池化(Max Pooling)

网格内的值不取平均值,而是取网格内的最大值进行池化操作

# @Time   : 2022/6/9 15:56
# @Author : Fioman
# @Phone  : 13149920693
# @Tips   : Talk is Cheap,Show me the code! ^_^^_^
from settings import *


def max_pooling(image, G=8):
    # Max Pooling
    out = image.copy()
    if len(image.shape) == 3:
        H, W, C = image.shape
    else:
        H, W = image.shape[:2]
        C = None

    hNums = int(H / G)
    wNums = int(W / G)

    for y in range(hNums):
        for x in range(wNums):
            if C is not None:
                for c in range(C):
                    out[G * y:G * (y + 1), G * x:G * (x + 1), c] = 
                    	np.max(out[G * y:G * (y + 1), G * x:G * (x + 1)], c)
            else:
                out[G * y:G * (y + 1), G * x:G * (x + 1)] = 
                		np.max(out[G * y:G * (y + 1), G * x:G * (x + 1)])

    return out


if __name__ == '__main__':
    imagePath = os.path.join(OPENCV_100_Q_PATH, "gray_01.bmp")
    imageOrginal = cv.imread(imagePath, cv.IMREAD_GRAYSCALE)
    maxPool = max_pooling(imageOrginal, 8)
    cv.imshow("Orginal", imageOrginal)
    cv.imshow("MaxPool", maxPool)
    cv.waitKey(0)

9. 高斯滤波(Gaussian Filter)

高斯滤波(Gaussian Filter)是线性滤波中的一种.高斯滤波主要用来平滑(模糊)图像,高斯滤波也是一种低通滤波器.

高斯滤波器的思想:

图像上的每个像素点的值,由其本身和邻域内的其他的像素点的值经过加权平均后得到.只是这个用来加权的核,是根据高斯分布求的.其中中心点是这个像素点本身,整个核服从高斯分布.

高斯函数:

一维高斯函数: G(x)sigma的取值有极大的关系,sigma取值越大,图像越平滑,sigma取值越小,图像越尖锐.


要理解高斯模糊,首先要明白一点,高斯公式是用来计算核权重的值的,并且这个中心点凸起的部分就是要计算的像素点.现在假定一组像素点,另sigma=1.5:


将像素坐标带入到高斯公式中,得到占用的权重为:

这里计算出来的结果为该相对位置的权重,而这个权重和像素值的值无关,是根据相对位置套用高斯公式去计算的.这个值计算之后,要根据归一化处理,就是使得权重的和是1,方法就是让上面的值除以它们的和,最终使得它们的和为1.


这里就得到了高斯卷积核,然后再跟像素值做卷积即可:

扩展到二维


高斯滤波模板的生成:
通过二维高斯函数进行计算,假如我们一个高斯模板的长宽均为5,方差为0.5,那么首先,我们是在卷积核模板上建立一个坐标系,其原点就是高斯模板的中心点,如下图:



高斯滤波器的模板: 两种形式,一个是小数形式,一个是整数形式

  • 小数形式的模板: 就是直接计算得到的值,然后将值除以它们之和.
  • 整数形式的模板: 需要进行归一化处理,将模板的左上角的值归一化为1.整数模板需要加一个系数,系数为模板系数和的倒数.

sigma的意义和选取:

高斯分布中的sigma代表的是标准差.标准差代表着离散程度,也表示高斯分布那个钟摆图像的宽度. sigma越小,表示离散程度越大,分布比较集中,中间部分所占用的比重远远高于其他的部分. 而sigma越大,表示离散程度越小,分布比较分散,中间部分占用比重和其他的部分占用的比重差不多.

高斯滤波代码实现:

# @Time   : 2022/6/10 10:35
# @Author : Fioman
# @Phone  : 13149920693
# @Tips   : Talk is Cheap,Show me the code! ^_^^_^
from settings import *


def gaussian_filter(image, kSize=3, sigma=1.3):
    """
    高斯滤波实现
    :param image:
    :param kSize:
    :param sigma:
    :return:
    """
    if len(image.shape) == 3:
        H, W, C = image.shape
    else:
        image = np.expand_dims(image, axis=-1)
        H, W, C = image.shape

    ## Zero Padding
    pad = kSize // 2
    out = np.zeros((H + pad * 2, W + pad * 2, C), dtype=np.float32)
    out[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)

    ## preprare Kernel
    K = np.zeros((kSize, kSize), dtype=np.float32)

    for x in range(-pad, -pad + kSize):
        for y in range(-pad, -pad + kSize):
            K[y + pad, x + pad] = np.exp(-(x ** 2 + y ** 2) / (2 * (sigma ** 2)))

    K /= (2 * np.pi * sigma * sigma)
    K /= K.sum()

    temp = out.copy()

    # filter
    for y in range(H):
        for x in range(W):
            for c in range(C):
                out[pad + y, pad + x, c] = np.sum(K * temp[y:y + kSize, x:x + kSize, c])

    out = np.clip(out, 0, 255)
    out = out[pad:pad + H, pad:pad + W].astype(np.uint8)
    return out


if __name__ == '__main__':
    imagePath = os.path.join(OPENCV_100_Q_PATH, "gray_01.bmp")
    imageOriginal = cv.imread(imagePath, cv.IMREAD_GRAYSCALE)
    gaussianFilter = gaussian_filter(imageOriginal, 3, 1.2)
    cv.imshow("Original", imageOriginal)
    cv.imshow("GaussianFilter",gaussianFilter)
    cv.waitKey(0)

10. 中值滤波

中值滤波也是一种可以使得图像平滑的滤波器.采用滤波核范围内的像素的中值进行滤波.边缘填充使用Zero Padding

代码实现:

# @Time   : 2022/6/10 10:54
# @Author : Fioman
# @Phone  : 13149920693
# @Tips   : Talk is Cheap,Show me the code! ^_^^_^

from settings import *


def median_filter(image, kSize=3):
    """
    中值滤波
    :param image: 滤波的图片
    :param kSize: 滤波核大小
    :return:
    """
    if len(image.shape) == 3:
        H, W, C = image.shape
    else:
        image = np.expand_dims(image, axis=-1)
        H, W, C = image.shape

    pad = kSize // 2
    imagePadding = np.zeros((H + 2 * pad, W + 2 * pad, C), dtype=np.float32)
    imagePadding[pad:pad + H, pad:pad + W] = image.copy().astype(np.float32)

    temp = imagePadding.copy()

    for y in range(H):
        for x in range(W):
            for c in range(C):
                imagePadding[pad + y, pad + x, c] = np.median(temp[y:y + kSize, x:x + kSize, c])

    imagePadding = imagePadding[pad:pad + H, pad:pad + W].astype(np.uint8)
    return imagePadding

if __name__ == '__main__':
    imagePath = os.path.join(OPENCV_100_Q_PATH,"gray_01.bmp")
    imageOriginal = cv.imread(imagePath,cv.IMREAD_GRAYSCALE)
    medianBlured = median_filter(imageOriginal,3)
    cv.imshow("Original",imageOriginal)
    cv.imshow("MedianBlured",medianBlured)
    cv.waitKey(0)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值