Question_11_20

本文详细介绍了多种图像处理滤波器,包括均值滤波、运动滤波、MAX-MIN滤波器、差分滤波器、Sobel滤波器、Prewitt滤波器、Laplacian滤波器、Emboss滤波器和LOG滤波器。通过实例代码展示了这些滤波器的效果,并解释了它们在边缘检测和特征提取中的应用。此外,还提到了直方图在分析图像像素分布中的作用。
摘要由CSDN通过智能技术生成

Question:模板

这是一个Question的模块框架

代码:

print("这是一个Question的模块框架")

Question11:均值滤波

均值滤波就是将区域内像素值的均值代替新的中央像素的值(实际上高斯滤波是一种带权值的均值滤波,规定了每个位置上像素值对结果的重要性,而此处的均值则是认为每个位置的重要性一样):
在这里插入图片描述
效果如下:
在这里插入图片描述

代码:

import numpy as np
import cv2

# 均值滤波
def meanFilter(img,size):
    padding=size//2
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((H+2*padding,W+2*padding,C))
    tmp[padding:padding+H,padding:padding+W]=img
    
    out=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out[h,w,c]=np.mean(tmp[h:h+size,w:w+size,c])
    out=out.clip(0,255).astype(np.uint8)
    return out 


img=cv2.imread("imori_noise.jpg")
out=meanFilter(img,3)
cv2.imshow("",out)
cv2.waitKey(0)

Question12:Motion Filter

顾名思义,这是一个运动滤波器,效果见图:
在这里插入图片描述
效果图有一个从左上角到右下角的运动效果。
本效果的Motion Filter如下所示:
在这里插入图片描述
也是从左上角到右下角,那么举一反三,如果是从左到右,则应当是第二行全为1/3,其余全为0。

代码:

import cv2
import numpy as np

# 获取核
def getMotionKernel():
    kernel=np.array([[1/3, 0,   0],
                     [0,   1/3, 0],
                     [0,   0,   1/3]])
    return kernel

# MotionFilter操作
def MotionFilter(img,kernel):
    size=kernel.shape[1]
    padding=size//2
    
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((H+2*padding,W+2*padding,C))
    tmp[padding:H+padding,padding:W+padding]=img
    
    out=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out[h,w,c]=np.sum(kernel*tmp[h:h+size,w:w+size,c])
    out=out.clip(0,255).astype(np.uint8)
    
    return out


img=cv2.imread("imori.jpg")
K=getMotionKernel()
out=MotionFilter(img,K)
cv2.imshow("",out)
cv2.waitKey(0)

对于3*3的核,Motion只有三个方向:0°,45°,90°。如果要使用其他更多的角度怎么办?扩大核尺寸
在这里插入图片描述
可见,随着核尺寸的变大,可表示的方向越来越多,只要保持线上像素值之和=1即可。

Question13:MAX-MIN滤波器

该滤波器是将区域内像素(最大值与最小值)的差值作为新的中央像素的值。实际上该滤波器加剧了像素的差异,造成的效果就是图像的边缘更加显著,而图像平滑区域减弱了。效果如下:
在这里插入图片描述
可以看出,实际上这就是一个边缘检测的滤波器。而边缘是一个图像的特征,这种边缘检测得到边缘的过程也是特征提取。

代码:

import numpy as np
import cv2


# MAX-MIN式边缘检测
def Max_Min_Filter(img,size):
    padding=size//2
    
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((H+2*padding,W+2*padding,C))
    tmp[padding:H+padding,padding:W+padding]=img
    
    out=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out[h,w,c]=np.max(tmp[h:h+size,w:w+size,c])-np.min(tmp[h:h+size,w:w+size,c])
    out=out.clip(0,255).astype(np.uint8)
    return out


img=cv2.imread("imori.jpg")
out=Max_Min_Filter(img,3)
cv2.imshow("",out)
cv2.waitKey(0)

Question14:差分滤波器

差分实际上就是做差。比如现在有一个差分滤波器:
在这里插入图片描述
则做运算时是这样的:
在这里插入图片描述
因为为0的乘积仍为0,实际上相应位乘积再求和,在这里表现为(-1)*20+(1)*150=130,就是上下像素做差,所以对图像运算后表现出来的效果也是突出了图像中纵向的边缘纹理
在这里插入图片描述

代码:

import numpy as np
import cv2


# 获取水平差分核垂直差分的卷积核
def getKernel():
    kh=np.array([[ 0, 0, 0],
                 [-1, 1, 0],
                 [ 0, 0, 0]])
    kv=np.array([[ 0, -1, 0],
                 [ 0, 1, 0],
                 [ 0, 0, 0]])
    
    return kh,kv


# 对图像进行不同方向的差分
def DifferentialFilter(img,kh,kv):
    size=kh.shape[1]
    padding=size//2
    
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((H+2*padding,W+2*padding,C))
    tmp[padding:H+padding,padding:W+padding]=img
    
    out_h=np.zeros(img.shape)
    out_v=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out_h[h,w,c]=np.sum(kh*tmp[h:h+size,w:w+size,c])
                out_v[h,w,c]=np.sum(kv*tmp[h:h+size,w:w+size,c])
        
    out_h=out_h.clip(0,255).astype(np.uint8)
    out_v=out_v.clip(0,255).astype(np.uint8)
    return out_h,out_v

img=cv2.imread("imori.jpg")
kh,kv=getKernel()
out_h,out_v=DifferentialFilter(img,kh,kv)
cv2.imshow("水平差分滤波",out_h)
cv2.imshow("垂直差分滤波",out_v)
cv2.waitKey(0)

Question15:Sobel滤波器

这是一个典型的边缘检测滤波器:
在这里插入图片描述
效果如下:
在这里插入图片描述

代码:

import numpy as np
import cv2


# 获取不同方向的卷积核
def getKernel():
    kh=np.array([[ 1,  2,  1],
                 [ 0,  0,  0],
                 [-1, -2, -1]])
    
    kv=np.array([[ 1,  0, -1],
                 [ 2,  0, -2],
                 [ 1,  0, -1]])
    
    return kh,kv


# 对图像进行sobel滤波
def DifferentialFilter(img,kh,kv):
    size=kh.shape[1]
    padding=size//2
    
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((H+2*padding,W+2*padding,C))
    tmp[padding:H+padding,padding:W+padding]=img
    
    out_h=np.zeros(img.shape)
    out_v=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out_h[h,w,c]=np.sum(kh*tmp[h:h+size,w:w+size,c])
                out_v[h,w,c]=np.sum(kv*tmp[h:h+size,w:w+size,c])
        
    out_h=out_h.clip(0,255).astype(np.uint8)
    out_v=out_v.clip(0,255).astype(np.uint8)
    return out_h,out_v


img=cv2.imread("imori.jpg")
kh,kv=getKernel()
out_h,out_v=DifferentialFilter(img,kh,kv)
cv2.imshow("水平sobel边缘检测滤波",out_h)
cv2.imshow("垂直sobel边缘检测滤波",out_v)
cv2.waitKey(0)

Question16:Prewitt滤波器

这也是一个典型的边缘检测滤波器:
在这里插入图片描述
效果如下:
在这里插入图片描述

代码:

import numpy as np
import cv2


def getKernel():
    kh=np.array([[-1, -1, -1],
                 [ 0,  0,  0],
                 [ 1,  1,  1]])
    
    kv=np.array([[-1,  0,  1],
                 [-1,  0,  1],
                 [-1,  0,  1]])
    
    return kh,kv


def DifferentialFilter(img,kh,kv):
    size=kh.shape[1]
    padding=size//2
    
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((H+2*padding,W+2*padding,C))
    tmp[padding:H+padding,padding:W+padding]=img
    
    out_h=np.zeros(img.shape)
    out_v=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out_h[h,w,c]=np.sum(kh*tmp[h:h+size,w:w+size,c])
                out_v[h,w,c]=np.sum(kv*tmp[h:h+size,w:w+size,c])
        
    out_h=out_h.clip(0,255).astype(np.uint8)
    out_v=out_v.clip(0,255).astype(np.uint8)
    return out_h,out_v


img=cv2.imread("imori.jpg")
kh,kv=getKernel()
out_h,out_v=DifferentialFilter(img,kh,kv)
cv2.imshow("水平Prewitt边缘检测滤波",out_h)
cv2.imshow("垂直Prewitt边缘检测滤波",out_v)
cv2.waitKey(0)

Question17:Laplacian滤波器

Laplacian滤波器实际上是一个使用二次微分的边缘检测滤波器。
二次微分如下图所示:你可以理解为是一个二次做差的过程
在这里插入图片描述
那么在图像中二次微分如下图:
在这里插入图片描述
现有一幅图,对图进行水平方向上的二次微分过程:

  • 第一次微分
    Δ I 1 ( x , y ) = I ( x + 1 , y ) − I ( x , y ) ( x + 1 ) − x = I ( x + 1 , y ) − I ( x , y ) ΔI_1(x,y)=\frac{I(x+1,y)-I(x,y)}{(x+1)-x}=I(x+1,y)-I(x,y) ΔI1(x,y)=(x+1)xI(x+1,y)I(x,y)=I(x+1,y)I(x,y)
    Δ I 2 ( x , y ) = I ( x , y ) − I ( x − 1 , y ) x − ( x − 1 ) = I ( x , y ) − I ( x − 1 , y ) ΔI_2(x,y)=\frac{I(x,y)-I(x-1,y)}{x-(x-1)}=I(x,y)-I(x-1,y) ΔI2(x,y)=x(x1)I(x,y)I(x1,y)=I(x,y)I(x1,y)
  • 第二次微分
    Δ Δ I ( x , y ) = Δ I 1 ( x , y ) − Δ I 2 ( x , y ) ( x + 1 ) − x = I ( x + 1 , y ) − I ( x , y ) ΔΔI(x,y)=\frac{ΔI_1(x,y)-ΔI_2(x,y)}{(x+1)-x}=I(x+1,y)-I(x,y) ΔΔI(x,y)=(x+1)xΔI1(x,y)ΔI2(x,y)=I(x+1,y)I(x,y)
    = I ( x + 1 , y ) − 2   I ( x , y ) + I ( x − 1 , y ) =I(x+1,y) - 2\ I(x,y) + I(x-1,y) =I(x+1,y)2 I(x,y)+I(x1,y)

同理,对垂直方向上的二次微分结果:
Δ Δ I ( x , y ) = I ( x , y + 1 ) − 2   I ( x , y ) + I ( x , y − 1 ) ΔΔI(x,y)=I(x,y+1) - 2\ I(x,y) + I(x,y-1) ΔΔI(x,y)=I(x,y+1)2 I(x,y)+I(x,y1)

两个方向上的二次微分相加:
Δ Δ I = I ( x + 1 , y ) + I ( x − 1 , y ) − 4   I ( x , y ) + I ( x , y + 1 ) + I ( x , y − 1 ) ΔΔI=I(x+1,y)+ I(x-1,y)- 4\ I(x,y) +I(x,y+1) + I(x,y-1) ΔΔI=I(x+1,y)+I(x1,y)4 I(x,y)+I(x,y+1)+I(x,y1)
用卷积核表示该式则为:
在这里插入图片描述
效果如下:

这是作者的效果图,作者将RGB彩图转换为灰度图后进行了滤波。一下给出我的代码,我没有将彩色图转为灰度图,下过如下:
在这里插入图片描述

代码:

import numpy as np
import cv2

def getLaplacian():
    k=np.array([[0, 1, 0],
                [1,-4, 1],
                [0, 1, 0]])
    return k


def laplacianFilter(img,k):
    size=k.shape[0]
    padding=size//2
    H,W=img.shape[0:2]
    C=1 if len(img.shape)==2 else 3
    
    tmp=np.zeros((2*padding+H,2*padding+W,C))
    tmp[padding:padding+H,padding:padding+W]=img
    
    out=np.zeros(img.shape)
    
    for h in range(H):
        for w in range(W):
            for c in range(C):
                out[h,w,c]=np.sum(k*tmp[h:h+size,w:w+size,c])
    out=out.clip(0,255).astype(np.uint8)
    return out


img=cv2.imread("imori.jpg")
k=getLaplacian()
out=laplacianFilter(img,k)
cv2.imshow("",out)
cv2.waitKey(0)

Question18:Emboss滤波器

一个典型的边缘检测滤波器,卷积核如下:
在这里插入图片描述
效果如下:
在这里插入图片描述

代码:

import numpy as np
import cv2


def getEmbossKernal():
    return np.array([[-2,-1, 0],
                     [-1, 1, 1],
                     [ 0, 1, 2]])



def EmbossFilter(img,k):
    size=k.shape[0]
    padding=size//2
    
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) # 将彩色RGB转换为Gray灰度图
    H,W=gray.shape
    
    tmp=np.zeros((2*padding+H,2*padding+W),dtype=np.float)
    tmp[padding:padding+H,padding:padding+W]=gray.copy()
    out=np.zeros(img.shape)

    # filtering
    for y in range(H):
        for x in range(W):
            out[y,x] = np.sum(k * (tmp[y: y + size, x: x + size]))
            
    out=out.clip(0,255).astype(np.uint8)
    return out


img=cv2.imread("imori.jpg")
k=getEmbossKernal()
out=EmbossFilter(img,k)
cv2.imshow("",out)
cv2.waitKey(0)

Question19:LOG滤波器

LoG即高斯-拉普拉斯(Laplacian of Gaussian)的缩写,使用高斯滤波器使图像平滑化之后再使用拉普拉斯滤波器使图像的轮廓更加清晰。

为了防止拉普拉斯滤波器计算二次微分会使得图像噪声更加明显,所以我们首先使用高斯滤波器来抑制噪声。
在这里插入图片描述
依次为:原图–对原图进行高斯滤波–对原图进行高斯-拉普拉斯滤波

代码:

import cv2
import numpy as np

def getLogKernal(size,s):
    pad=size//3
    
    kernal=np.zeros((size,size))
    for x in range(size):
        for y in range(size):
            xa,ya=x-1,y-1
            kernal[x,y]=(xa**2+ya**2-s**2)*np.exp(-(xa**2+ya**2)/(2*s**2))/(2*np.pi*s**6)
    kernal=kernal/np.sum(kernal)
    return kernal

def LogFilter(img,k):
    size=k.shape[0]
    padding=size//2
    
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    H,W=gray.shape
    
    tmp=np.zeros((2*padding+H,2*padding+W),dtype=np.float)
    tmp[padding:padding+H,padding:padding+W]=gray.copy()
    out=np.zeros(img.shape)

    # filtering
    for y in range(H):
        for x in range(W):
            out[y,x] = np.sum(k * (tmp[y: y + size, x: x + size]))
            
    out=out.clip(0,255).astype(np.uint8)
    return out


img=cv2.imread("../imori_noise.jpg")
K=getLogKernal(3,1.3)
out=LogFilter(img,K)
cv2.imshow("LOG",out)
cv2.waitKey(0)

Question20:直方图

直方图反映一个图片中像素值分布的情况。
在这里插入图片描述
从上图中可以看出,图中像素值大小大量分布在中等亮度,说明该图亮度适中,如果大量集中在左侧,则图亮度偏低

代码(自己写的):

import cv2
import numpy as np

# 统计每个亮度等级的像素个数
def hist(gray):
    his=np.zeros(255)
    W,H=gray.shape
    for w in range(W):
        for h in range(H):
            value=gray[w,h]
            his[value]+=1
    return list(his)

img=cv2.imread("../imori.jpg")
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
his=hist(gray)

import matplotlib.pyplot as plt
plt.bar(range(len(his)), his) # 绘制柱状图
plt.show()

代码(matplotlib封装的直方图绘制函数):

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

# Read image
img = cv2.imread("imori_dark.jpg").astype(np.float)

# Display histogram
plt.hist(img.ravel(), bins=255, rwidth=0.8, range=(0, 255))
plt.show()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是一个对称矩阵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值