天天看點

opencv——圖像濾波_雙邊濾波

1、2D卷積

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


"""
使用自定義卷積核進行圖像2D卷積操作
    函數原型:
        filter2D(src, ddepth, kernel[, dst[, anchor[, delta[, borderType]]]]) -> dst
        函數傳回值:dst:2d卷積操作後的結果

        函數解析:
            ddepth:指定輸出圖像深度,-1表示與src深度保持一緻
            kernel:卷積核心大小, 需大于零,可以不同,如核大小(4,5)
            anchor:錨點;預設值Point(-1,-1)表示錨位于核心中央
            delta:在将它們存儲在dst中之前,将delta可選值添加到已過濾的像素中,預設為None
            borderType:邊框模式用于圖像外部的像素, 預設邊緣像素拷貝
"""

import cv2 as cv
import numpy as np

img = cv.imread('./test.png')

# 自定義的一些卷積核
kernel = np.ones((5, 5), np.float32) / 25

kernel_user_1 = np.array([[0, 0, 1, 0, 0],
                          [0, 0, 1, 0, 0],
                          [1, 1, 1, 1, 1],
                          [0, 0, 1, 0, 0],
                          [0, 0, 1, 0, 0]]) / 9

kernel_user_2 = np.array([[1, 0, 0, 0, 1],
                          [0, 1, 0, 1, 0],
                          [0, 0, 1, 0, 0],
                          [0, 1, 0, 1, 0],
                          [1, 0, 0, 0, 1]]) / 9

kernel_user_3 = np.array([[0, 0, 0, 0, 0],
                          [0, 1, 1, 1, 0],
                          [0, 1, 1, 1, 0],
                          [0, 1, 1, 1, 0],
                          [0, 0, 0, 0, 0]]) / 9

kernel_user_4 = np.array([[1, 1, 1, 1, 1],
                          [1, 0, 0, 0, 1],
                          [1, 0, 0, 0, 1],
                          [1, 0, 0, 0, 1],
                          [1, 1, 1, 1, 1]]) / 16

dst = cv.filter2D(img, -1, kernel)
dst1 = cv.filter2D(img, -1, kernel_user_1)
dst2 = cv.filter2D(img, -1, kernel_user_2)
dst3 = cv.filter2D(img, -1, kernel_user_3)
dst4 = cv.filter2D(img, -1, kernel_user_4)

h1 = np.hstack((img, dst, dst1))
h2 = np.hstack((dst2, dst3, dst4))
cv.imshow('show', np.vstack((h1, h2)))

cv.waitKey(0)
cv.destroyAllWindows()

# 了解提高
small = np.array(range(10, 55, 5), np.uint8).reshape(3, -1)
print(small)
print('*' * 60)

small_filter = cv.filter2D(small, -1, (np.ones((3, 3), np.float32) / (3 * 3)))
print(small_filter)
           
opencv——圖像濾波_雙邊濾波

2、雙邊濾波

#!/usr/bin/env python3
# -*- coding: utf-8 -*-


"""
    雙邊濾波器可以很好的儲存圖像邊緣細節并濾除掉低頻分量的噪音,
    但是雙邊濾波器的效率不是太高,花費的時間相較于其他濾波器而言也比較長。
    函數原型:
        bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]]) -> dst
        重點參數解析:
            d:表示在過濾過程中每個像素鄰域的直徑範圍。如果該值是非正數,則将由sigmaSpace計算
            sigmaColor:顔色空間過濾器的sigma值,值越大表示有越寬廣的顔色混合到一起
            sigmaSpace: 坐标空間中濾波器的sigma值,如果該值較大,則意味着越遠的像素将互相影響
            borderType:邊框模式用于圖像外部的像素, 預設邊緣像素拷貝
"""

import cv2 as cv
import numpy as np

# img_path = './images/Fig4.11(a).jpg'
# img_path = './images/Fig5.08(b).jpg'
# img_path = './images/Fig0519(a)(florida_satellite_original).tif'
img_path = 'noisy2.png'

img = cv.imread(img_path)


def nothing(x):
    pass


cv.namedWindow('image')

# 建立滑動條
cv.createTrackbar('d', 'image', 0, 100, nothing)
cv.createTrackbar('sigmaColor', 'image', 0, 200, nothing)
cv.createTrackbar('sigmaSpace', 'image', 0, 200, nothing)

cv.imshow('img', img)
cv.imshow('image', img)

while True:
    k = cv.waitKey(25) & 0XFF
    if chr(k) == 'q':
        break
    if chr(k) == 'k':
        d = cv.getTrackbarPos('d', 'image')
        sigmaColor = cv.getTrackbarPos('sigmaColor', 'image')
        sigmaSpace = cv.getTrackbarPos('sigmaSpace', 'image')
        b_filter = cv.bilateralFilter(img, d, sigmaColor, sigmaSpace)
        ret, thresh = cv.threshold(b_filter, 127, 255, cv.THRESH_BINARY)
        sava_name = ''.join(('outputs/', 'b_filter', str(d), '_', str(sigmaColor), '_', str(sigmaColor)))
        cv.imshow('image', np.hstack((b_filter, thresh)))
        cv.imwrite(sava_name + '.jpg', b_filter)
        cv.imwrite(sava_name + '_thr.jpg', thresh)

cv.destroyAllWindows()
           
opencv——圖像濾波_雙邊濾波