邻域运算

一、邻域运算

邻域运算:在每个图象位置(x,y)进行基于领域的函数计算。常见的函数有:
平滑/去噪
梯度/锐化
边缘、显著点、纹理
模式检测;
具体的滤波/卷积算法有:
均值滤波:既没有去除点,也破坏了图像细节反而使图像变得模糊
中值滤波:卷积域内的像素值从小到大排序,取中间值作为卷积输出,能去除椒盐噪声
高斯滤波:模拟人眼观注中心区域,离中心越远越模糊,有效去除高斯噪声
梯度Prewitt滤波/卷积:水平梯度/垂直边缘、垂直梯度/水平边缘
梯度Sobel滤波/卷积:同上,也都是检验垂直边缘和水平边缘的滤波器

二、python

均值滤波:使用元素的领域内像素的平均值代替该元素,可明显的降低图像灰度的尖锐变换。它的一种重要应用是模糊处理:得到感兴趣的区域的粗略表示,将次要的/小的元素与背景融合,使得主要的/较大的元素变得易于检测
以下图为例:
在这里插入图片描述代码:

from skimage import data,color
import matplotlib.pyplot as plt
import cv2
from skimage.morphology import disk

import skimage.filters.rank as sfr
img2 = cv.imread("./11.jpg", cv.IMREAD_GRAYSCALE)
img=color.rgb2gray(img2)
dst =sfr.mean(img, disk(5))
plt.figure('filters',figsize=(8,8)) 
plt.subplot(121) 
plt.title('origin image') 
plt.imshow(img,plt.cm.gray) 
plt.subplot(122) 
plt.title('filted image') 
plt.imshow(dst,plt.cm.gray)
plt.show()

均值滤波:
在这里插入图片描述中值滤波:
在这里插入图片描述代码:

import numpy as np
import cv2
from PIL import Image
import scipy.signal as signal
import matplotlib.pyplot as plt

# 创建一个500*500的矩阵
input_images = np.zeros((500, 500))
filename = "./11.jpg"
# convert将当前图像转换为灰度模式,并且返回新的图像。
# 将图片在重新定义的矩阵中再显示,不然可能会只显示部分。
img = Image.open(filename).resize((500, 500)).convert('L')
plt.subplot(221)
plt.title('ori')
plt.imshow(img)
# 图像的尺寸,按照像素数计算。它的返回值为宽度和高度的二元组(width, height)。
width = img.size[0]
height = img.size[1]
threshold = 20
# 可以改写代码使其成为二值化,此代码可理解为反向二值化
for h in range(height):
    for w in range(width):
        # getpixel直接获得(h,w)处的像素直接返回这个点三个通道的像素值
        # 返回给定位置的像素值。如果图像为多通道,则返回一个元组(r,g,b,阈值)。
        # 如果改成(w,h)出现的图像会倒转
        if img.getpixel((w, h)) < threshold:

            input_images[h, w] = 1
        else:
            input_images[h, w] = 0
plt.subplot(222)
plt.title('bio')
plt.imshow(input_images)

data = signal.medfilt2d(np.array(img), kernel_size=3)  # 二维中值滤波
for h in range(0, height):
    for w in range(0, width):
        if data[h][w] < 20:
            input_images[h, w] = 0
        else:
            input_images[h, w] = 1

plt.subplot(223)
plt.title('3*3')
plt.imshow(input_images)

data = signal.medfilt2d(np.array(img), kernel_size=7)  # 二维中值滤波
for h in range(0, height):
    for w in range(0, width):
        if data[h][w] < 20:
            input_images[h, w] = 0
        else:
            input_images[h, w] = 1
plt.subplot(224)
plt.title('7*7')
plt.imshow(input_images)
plt.show()

高斯滤波:
在这里插入图片描述
代码:

import cv2
import matplotlib.pyplot as plt
img=cv2.imread('./11.jpg')
 
#(3, 3)表示高斯滤波器的长和宽都为3,1.3表示滤波器的标准差
 
out=cv2.GaussianBlur(img,(3,3),1.3)

plt.imshow(out)
plt.show()

梯度Prewitt滤波/卷积:
在这里插入图片描述梯度Sobel滤波/卷积:

在这里插入图片描述
Prewitt和sobel算子代码:

import matplotlib.pyplot as plt
import cv2
import numpy as np
import math

# 卷积
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('11.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('11.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('11.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)

三、matlab

在这里插入图片描述
在这里插入图片描述
代码:
prewittee.m:


function prewittee(FILENAME)
%prewittee(FILENAME) takes a gray scale image with filename FILENAME.

% Read the image.
Im = im2double(imread(FILENAME));
% Show the image in a new window.
figure;imshow(Im, [min(min(Im)) max(max(Im))]);title('Original Image');
disp('Original image is read and displayed successfully.');

%
% Generate the corresponding binary edge image of the given image Im.
T = double(max(max(Im)))*0.2;
direction = 'all';
g = myprewittedge(Im,T,direction);
% Show the image in a new window.
figure;imshow(g, [0 1]);title('Binary Edge Image 1');
disp('The corresponding binary edge image is computed and displayed successfully.');

%
% Generate the corresponding binary edge image of the given image Im
% without specifying the threshold
direction = 'all';
f = myprewittedge(Im,[],direction);
% Show the image in a new window.
figure;imshow(f, [0 1]);title('Binary Edge Image 2');
disp('The corresponding binary edge image is computed and displayed successfully.');

myprewittedge.m:

% myprewittedge computes a binary edge image from the given image.
%
%   g = myprewittedge(Im,T,direction) computes the binary edge image from the
%   input image Im.
%   
% The function myprewittedge, with the format g=myprewittedge(Im,T,direction), 
% computes the binary edge image from the input image Im. This function takes 
% an intensity image Im as its input, and returns a binary image g of the 
% same size as Im (mxn), with 1's where the function finds edges in Im and 0's 
% elsewhere. This function finds edges using the Prewitt approximation to the 
% derivatives with the assumption that input image values outside the bounds 
% are zero and all calculations are done using double-precision floating 
% point. The function returns g with size mxn. The image g contains edges at 
% those points where the absolute filter response is above or equal to the 
% threshold T.
%   
%       Input parameters:
%       Im = An intensity gray scale image.
%       T = Threshold for generating the binary output image. If you do not
%       specify T, or if T is empty ([ ]), myprewittedge(Im,[],direction) 
%       chooses the value automatically according to the Algorithm 1 (refer
%       to the assignment descripton).
%       direction = A string for specifying whether to look for
%       'horizontal' edges, 'vertical' edges, positive 45 degree 'pos45'
%       edges, negative 45 degree 'neg45' edges or 'all' edges.
function g = myprewittedge(Im,T,direction)
  if isempty(T)
    T = (max(max(Im)) + min(min(Im))) / 2;
    for i = 1:10
    G1 = Im .* (Im > T);
    G2 = Im .* (Im < T);
    m1 = mean(G1(G1~=0));
    m2 = mean(G2(G2~=0));
    T = (m1 + m2) / 2;
    end
  end  
  [m, n] = size(Im);
%   temp = Im;
  prewittNum = 0;
  for j = 2:m-1
    for k = 2:n-1
      prewittNum = abs(Im(j-1,k+1)-Im(j+1,k+1)+Im(j-1,k)-Im(j+1,k)+Im(j-1,k-1)-Im(j+1,k-1))+abs(Im(j-1,k+1)+Im(j,k+1)+Im(j+1,k+1)-Im(j-1,k-1)-Im(j,k-1)-Im(j+1,k-1));
      if (prewittNum > T)
        temp(j,k) = 255;
        else
        temp(j,k) = 0;
        end
     end
   end
   g = temp;
  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值