图象带状噪声去除

对指定图像的复原与增强
在这里插入图片描述

原图像 1-1
实验流程如下:
根据观察不难得出图像中存在脉冲噪声,故而应用中值滤波器进行滤波,去除脉冲噪声。
对于脉冲噪声的滤除不限于滤波方法,笔者曾尝试过其他思路,但是由于效果较中值而言略显粗糙,仅作为附加方案在下文叙述。

而对于图像中的亮线,采取截短做Fourier Transform进行频域滤波的方法,尝试进行复原。
关于该方法做如下说明:
根据亮线的形态及对于空间波的认知来说,我们可以认为这些亮线是由某一频率的空间波构成,也就是说,我们可能在频域上进行滤除。但是这里要提出一个问题:现有的FT是否可以处理构成亮线的空间波频率?
众所周知,Fourier Transform是我们了解频域信息的重要手段,但是该方法仍不是完美的,我们须注意到,Fourier Transform所得到的频域信息不包含原图像的空间信息(关于这一点,FT的移不变就是很好的例证),强调的是全局性的频率信息。FT将图像近似等效的分解为一系列周期的、在图像中均匀的空间波的加和,所以对任意分量的幅度的改动都势必影响整个图像,由于空间波的连续性,我们无法仅指定一个区域内的幅度发生改变。综上,我们需要对FT进行优化:加入空间信息并获得频谱。
幸运的是,虽然我们难以在精巧的FT上引入空间信息,但是我们可以对图像进行改动,也就是将图像截取后进行FT,此时我们对频域的处理就不会影响截取区域以外的位置,间接的实现空间信息的引入。
在这里插入图片描述

截短FT结果 1-2

关于脉冲噪声处理的其他方案:
对于脉冲噪声来说,中值滤波有这较好的效果,但是也不可避免的对图像造成了模糊效果。在细究滤波过程可以发现,中值滤波实际上存在许多不必要的操作:即使是非噪声点依旧以中值替换!所以我们以这一点进行优化:能否确定图像中噪点位置?
根据脉冲噪声的特性,其与邻域内的像素点有着极其显著的差值,或者说有着与正常像素明显的边缘,因此可以尝试采用边缘检测对噪点进行判断。这里注意,边缘检测得出的不仅是噪点,也包括正常图像的边缘,尽管边缘不应该被处理,但是相对于中值来说已经缩减相当大的误处理范围了,所以这里将图像边缘一并进行去噪处理
在我们得到噪点位置之后,我们需要知道在这一点原图像的像素值。根据信息论我们可以做出如下假设:存在某一邻域上的线性组合,使得该点的像素值可以被表示。基于此假设,我们可以利用邻域内其他像素点进行推测。由于笔者水平有限,这里采用自适应窗和非线性拟合的效果会更好。
实验效果见实验结果 附

在查阅相关材料后,发现可以通过腐蚀处理亮线,大致流程如下:
腐蚀操作首先需要确定待腐蚀边界,因此,仍然对图像进行边缘检测

在这里插入图片描述

边缘检测 1-3
后依旧边缘信息将图像分成若干联通区域
在这里插入图片描述在这里插入图片描述

连通集 1-4
取面积最大的两块连通集作为图像掩码,并将该掩码取反,使包括待处理区域布尔值为真

在这里插入图片描述

图像掩码 1-5

根据观察可知待去除部分为矩形,假定一行中半数像素的掩码为真,即判定为待处理区域。确定处理区域后,进行腐蚀操作,即可修复亮线

1.程序代码

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import tool as tk # 原码见文末


def showimg(name, scr):
    length = len(scr)
    for i in range(length):
        cv.imshow(name[i], scr[i])


def w(name, src):
    cv.imwrite('../img/'+name+'.jpg', src)


def different(img1, img2):
    cv.imshow('different', np.array((img1 - img2), dtype=np.uint8))
    cv.waitKey(0)


def solution1(img):
    recover = np.array(img, dtype=np.uint8)
    mask = np.empty_like(recover, dtype=np.uint8)
    time = 3
    for i in range(time):
        mask = tk.detectedge(recover, 80)
        recover = tk.interpolation(recover, mask, method='bilinear')
    name = ['img', 'mask', 'res']
    showimg(name, [img, mask, recover])
    cv.waitKey(0)
    cv.destroyAllWindows()


def solution2(img):
    img  = cv.cvtColor(img, cv.COLOR_RGB2GRAY)
    length, width = img.shape
    slice_length, slice_width = 40, width
    mask = np.ones((slice_length, slice_width))
    for i in range(slice_length):
        if i in range(np.int(slice_length / 2) - 1, np.int(slice_length / 2) + 2):
            continue
        mask[i, np.int(slice_width / 2)] = 0
    res = tk.ppf(img, slice_length, mask, begin=5, size=1)
    res = tk.score(res, method='mid')
    img_back = np.array(res, dtype=np.uint8)
    eq_img_back = cv.equalizeHist(img_back)
    tk.histogram([img_back, eq_img_back])
    cv.imshow('res' ,eq_img_back)
    cv.waitKey(0)
    cv.destroyAllWindows()

def get_area(edge):
    vis = np.zeros_like(edge, dtype=np.bool)
    area_mark = np.zeros_like(edge, dtype=np.int)
    height, width = edge.shape
    area_kind, area = (1, [0])
    move = np.array([[0, 1], [0, -1], [1, 0], [-1, 0]], dtype=np.int)
    check = lambda x, y: x >= 0 and y>= 0 and x < height and y < width and not vis[x, y] and edge[x, y]==0
    for x in range(height):
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值