1. 程式人生 > >【計算機視覺】卷積、均值濾波、高斯濾波、Sobel運算元、Prewitt運算元(Python實現)

【計算機視覺】卷積、均值濾波、高斯濾波、Sobel運算元、Prewitt運算元(Python實現)

1.環境的搭建


  • Python 3.6
  • OpenCV
Open Source Computer Vision Library.OpenCV於1999年由Intel建立,如今由Willow Garage提供支援。OpenCV是一個基於BSD許可(開源)發行的跨平臺計算機視覺庫,可以執行在Linux、Windows、MacOS作業系統上。它輕量級而且高效——由一系列 C 函式和少量C++類構成,同時提供了Python、Ruby、MATLAB等語言的介面,實現了影象處理和計算機視覺方面的很多通用演算法。最新版本是3.1 ,2016年1月29日釋出。

OpenCV 安裝命令

pip install opencv-python

覺得有用就點顆星吧

2.卷積的實現

卷積的概念自行百度吧

# 卷積
def imgConvolve(image, kernel):
    '''
    :param image: 圖片矩陣
    :param kernel: 濾波視窗
    :return:卷積後的矩陣
    '''
    img_h = int(image.shape[0])
    img_w = int(image.shape[1])
    kernel_h = int(kernel.shape[0])
    kernel_w = int(kernel.shape[1
]) # padding padding_h = int((kernel_h - 1) / 2) padding_w = int((kernel_w - 1) / 2) convolve_h = int(img_h + 2 * padding_h) convolve_W = int(img_w + 2 * padding_w) # 分配空間 img_padding = np.zeros((convolve_h, convolve_W)) # 中心填充圖片 img_padding[padding_h:padding_h + img_h, padding_w:padding_w + img_w] = image[:, :] # 卷積結果
image_convolve = np.zeros(image.shape) # 卷積 for i in range(padding_h, padding_h + img_h): for j in range(padding_w, padding_w + img_w): image_convolve[i - padding_h][j - padding_w] = int( np.sum(img_padding[i - padding_h:i + padding_h+1, j - padding_w:j + padding_w+1]*kernel)) return image_convolve

3.均值濾波的實現

均值濾波實際上也就是卷積和的平均,卷積和/濾波大小

原圖

這裡寫圖片描述

# 均值濾波
def imgAverageFilter(image, kernel):
    '''
    :param image: 圖片矩陣
    :param kernel: 濾波視窗
    :return:均值濾波後的矩陣
    '''
    return imgConvolve(image, kernel) * (1.0 / kernel.size)
3x3均值濾波效果圖

這裡寫圖片描述

5x5均值濾波效果圖

這裡寫圖片描述

4.高斯濾波的實現


  • 1.根據σ獲得高斯濾波器的模板
  • 2.然後使用該模板對影象進行卷積
σ是標準差。要想得到一個高斯濾波器的模板,可以對高斯函式進行離散化,得到的高斯函式值作為模板的係數。
原圖

這裡寫圖片描述

# 高斯濾波
def imgGaussian(sigma):
    '''
    :param sigma: σ標準差
    :return: 高斯濾波器的模板
    '''
    img_h = img_w = 2 * sigma + 1
    gaussian_mat = np.zeros((img_h, img_w))
    for x in range(-sigma, sigma + 1):
        for y in range(-sigma, sigma + 1):
            gaussian_mat[x + sigma][y + sigma] = np.exp(-0.5 * (x ** 2 + y ** 2) / (sigma ** 2))
    return gaussian_mat
sigma=1 效果圖

這裡寫圖片描述

sigma=2 效果圖

這裡寫圖片描述

sigma=3 效果圖

這裡寫圖片描述

5. Sobel運算元的實現

原圖

原圖

使用Sobel運算元作為模板,用來對影象進行邊緣檢測,水平 豎直邊緣

# sobel
sobel_1 = np.array([[-1, 0, 1],
                    [-2, 0, 2],
                    [-1, 0, 1]])

sobel_2 = np.array([[-1, -2, -1],
                    [0, 0, 0],
                    [1, 2, 1]])

其中sobel_1是對豎直方向的邊緣檢查,sobel_2是對水平方向的邊緣檢測

# Sobel Edge
def sobelEdge(image, sobel):
    '''
    :param image: 圖片矩陣
    :param sobel: 濾波視窗
    :return: Sobel處理後的矩陣
    '''
    return imgConvolve(image, sobel)
sobel_1 效果圖

這裡寫圖片描述

sobel_2 效果圖

6. Prewitt運算元的實現

使用分別使用Prewitt1運算元、Prewitt2運算元作為模板,用來對影象進行邊緣檢測,水平+豎直邊緣

# prewitt 運算元
prewitt_1 = np.array([[-1, 0, 1],
                      [-1, 0, 1],
                      [-1, 0, 1]])

prewitt_2 = np.array([[-1, -1, -1],
                      [0, 0, 0],
                      [1, 1, 1]])
# Prewitt Edge
def prewittEdge(image, prewitt_x, prewitt_y):
    '''
    :param image: 圖片矩陣
    :param prewitt_x: 豎直方向
    :param prewitt_y:  水平方向
    :return:處理後的矩陣
    '''
    img_X = imgConvolve(image, prewitt_x)
    img_Y = imgConvolve(image, prewitt_y)

    img_prediction = np.zeros(img_X.shape)
    for i in range(img_prediction.shape[0]):
        for j in range(img_prediction.shape[1]):
            img_prediction[i][j] = max(img_X[i][j], img_Y[i][j])
    return img_prediction
Prewitt效果圖

這裡寫圖片描述

7.完整程式碼(圖片+程式碼請看github)

# -*- coding: utf-8 -*-
import cv2
import numpy as np
import math

'''
# @Time    : 18-3-31 下午2:16
# @Author  : 羅傑                  
# @ID      : F1710w0249
# @File    : assignments.py
# @Desc    : 計算機視覺作業01
'''


# 卷積
def imgConvolve(image, kernel):
    '''
    :param image: 圖片矩陣
    :param kernel: 濾波視窗
    :return:卷積後的矩陣
    '''
    img_h = int(image.shape[0])
    img_w = int(image.shape[1])
    kernel_h = int(kernel.shape[0])
    kernel_w = int(kernel.shape[1])
    # padding
    padding_h = int((kernel_h - 1) / 2)
    padding_w = int((kernel_w - 1) / 2)

    convolve_h = int(img_h + 2 * padding_h)
    convolve_W = int(img_w + 2 * padding_w)

    # 分配空間
    img_padding = np.zeros((convolve_h, convolve_W))
    # 中心填充圖片
    img_padding[padding_h:padding_h + img_h, padding_w:padding_w + img_w] = image[:, :]
    # 卷積結果
    image_convolve = np.zeros(image.shape)
    # 卷積
    for i in range(padding_h, padding_h + img_h):
        for j in range(padding_w, padding_w + img_w):
            image_convolve[i - padding_h][j - padding_w] = int(
                np.sum(img_padding[i - padding_h:i + padding_h + 1, j - padding_w:j + padding_w + 1] * kernel))

    return image_convolve


# 均值濾波
def imgAverageFilter(image, kernel):
    '''
    :param image: 圖片矩陣
    :param kernel: 濾波視窗
    :return:均值濾波後的矩陣
    '''
    return imgConvolve(image, kernel) * (1.0 / kernel.size)


# 高斯濾波
def imgGaussian(sigma):
    '''
    :param sigma: σ標準差
    :return: 高斯濾波器的模板
    '''
    img_h = img_w = 2 * sigma + 1
    gaussian_mat = np.zeros((img_h, img_w))
    for x in range(-sigma, sigma + 1):
        for y in range(-sigma, sigma + 1):
            gaussian_mat[x + sigma][y + sigma] = np.exp(-0.5 * (x ** 2 + y ** 2) / (sigma ** 2))
    return gaussian_mat


# Sobel Edge
def sobelEdge(image, sobel):
    '''
    :param image: 圖片矩陣
    :param sobel: 濾波視窗
    :return:Sobel處理後的矩陣
    '''
    return imgConvolve(image, sobel)


# Prewitt Edge
def prewittEdge(image, prewitt_x, prewitt_y):
    '''
    :param image: 圖片矩陣
    :param prewitt_x: 豎直方向
    :param prewitt_y:  水平方向
    :return:處理後的矩陣
    '''
    img_X = imgConvolve(image, prewitt_x)
    img_Y = imgConvolve(image, prewitt_y)

    img_prediction = np.zeros(img_X.shape)
    for i in range(img_prediction.shape[0]):
        for j in range(img_prediction.shape[1]):
            img_prediction[i][j] = max(img_X[i][j], img_Y[i][j])
    return img_prediction


######################常量################################
# 濾波3x3
kernel_3x3 = np.ones((3, 3))
# 濾波5x5
kernel_5x5 = np.ones((5, 5))

# sobel 運算元
sobel_1 = np.array([[-1, 0, 1],
                    [-2, 0, 2],
                    [-1, 0, 1]])

sobel_2 = np.array([[-1, -2, -1],
                    [0, 0, 0],
                    [1, 2, 1]])
# prewitt 運算元
prewitt_1 = np.array([[-1, 0, 1],
                      [-1, 0, 1],
                      [-1, 0, 1]])

prewitt_2 = np.array([[-1, -1, -1],
                      [0, 0, 0],
                      [1, 1, 1]])

# ######################均值濾波################################
# 讀圖片
image = cv2.imread('balloonGrayNoisy.jpg', cv2.IMREAD_GRAYSCALE)
# 均值濾波
img_k3 = imgAverageFilter(image, kernel_3x3)

# 寫圖片
cv2.imwrite('average_3x3.jpg', img_k3)
# 均值濾波
img_k5 = imgAverageFilter(image, kernel_5x5)
# 寫圖片
cv2.imwrite('average_5x5.jpg', img_k5)

######################高斯濾波################################
image = cv2.imread('balloonGrayNoisy.jpg', cv2.IMREAD_GRAYSCALE)
img_gaus1 = imgAverageFilter(image, imgGaussian(1))
cv2.imwrite('gaussian1.jpg', img_gaus1)
img_gaus2 = imgAverageFilter(image, imgGaussian(2))
cv2.imwrite('gaussian2.jpg', img_gaus2)
img_gaus3 = imgAverageFilter(image, imgGaussian(3))
cv2.imwrite('gaussian3.jpg', img_gaus3)


######################Sobel運算元################################
image=cv2.imread('buildingGray.jpg',cv2.IMREAD_GRAYSCALE)
img_spbel1 = sobelEdge(image, sobel_1)
cv2.imwrite('sobel1.jpg',img_spbel1)
img_spbel2 = sobelEdge(image, sobel_2)
cv2.imwrite('sobel2.jpg',img_spbel2)

######################prewitt運算元################################
img_prewitt1 = prewittEdge(image, prewitt_1,prewitt_2)
cv2.imwrite('prewitt1.jpg',img_prewitt1)