一、邻域运算
邻域运算:在每个图象位置(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;