基于opencv的自动祛斑算法 您所在的位置:网站首页 如何去除老照片斑点和划痕小妙招 基于opencv的自动祛斑算法

基于opencv的自动祛斑算法

2024-07-11 06:58| 来源: 网络整理| 查看: 265

首先我们先来看一下详细的逻辑思路: 灰度化对比度增强梯度极大值查找皮肤排除孤立点消除高斯模糊阈值处理区域表求和得到最终结果D根据结果D与梯度最大值查找的结果对图像A里的斑点进行泊松放出处理,得到自动祛斑的最终效果 概括来说就是一下三个主要步骤:

在这里插入图片描述

- 1.sobel算子————》找到斑点的可能区域 sobel算子的主要目的是为了检测边缘。图像边缘一般指图像的灰度变化率最大的位置。 先看看关键性代码:

src1 = cv2.cvtColor(src,cv2.COLOR_BGR2GRAY) x_gray = cv2.Sobel(src1,cv2.CV_32F,1,0) y_gray = cv2.Sobel(src1,cv2.CV_32F,0,1) x_gray = cv2.convertScaleAbs(x_gray) y_gray = cv2.convertScaleAbs(y_gray) dst = cv2.add(x_gray,y_gray,dtype=cv2.CV_16S) dst = cv2.convertScaleAbs(dst)

解析一下:

cv2.Sobel(src1,cv2.CV_32F,1,0,ksize=3): 1,src1:原灰度图 2,cv2.CV_32F:表示32位浮点数即32float 3,4,第三个和第四个参数分别是对X和Y方向的导数(dx,dy),对于图像而言就是差分,这里1,0表示对X求导。对X求导就是检测纵向上是否有边缘。 5,ksize是指核大小,可以省略,使用默认参数。cv2.convertScaleAbs(x_gray)函数是一个位深转化函数,可将任意类型的数据转化为CV_8UC1。经过cv2.Sobel()梯度增强,增强后的图像识别会出现大于255和小于0的值。

- 2.连通域分析————》确定斑点的位置 上面使用sobel算子计算边缘后,五官等区域也被是视为一个连通域,如果直接作为后续的处理,那显然不正确。这里我们设置一个面积的阈值来区别开斑点和其他区域。 关键性代码:

# 注意:输入的是二值图,高斯滤波后效果更好 num_labels,labels,stats,centers = cv2.connectedComponentsWithStats(binary, connectivity=8,ltype=cv2.CV_32S) # 参数说明: num_labels: 代表连通域的数量,包含背景 labels : 记录img中每个位置对应的label stats: 每个连通域的外接矩形和面积 x, y, w, h, area = stats[t] centers : 连通域的质心坐标

依据连通域面积的大小做阈值分割的标准:

for t in range(1, num_labels, 1): x, y, w, h, area = stats[t] if area>100: index = np.where(labels==t) labels[index[0], index[1]] = 0

通过遍历每个连通域,并根据连通域的面积(这里设置阈值100),将面积超过的连通域label设置为0,即为背景。

- 3.图像修复inpaint————》去除斑点 这里opencv提供了两种算法。 (1)第一种算法基于Alexandru Telea于2004年发表的“基于快速行进方法的图像修复技术”。它基于快速行进方法。考虑图像中要修复的区域。算法从该区域的边界开始,然后进入区域内,逐渐填充边界中的所有内容。它需要在邻近的像素周围的一个小邻域进行修复。该像素由邻居中所有已知像素的归一化加权和代替。选择权重是一个重要的问题。对于靠近该点的那些像素,靠近边界的法线和位于边界轮廓上的像素,给予更多的权重。一旦像素被修复,它将使用快速行进方法移动到下一个最近的像素。FMM确保首先修复已知像素附近的像素,这样它就像手动启发式操作一样工作。使用标志cv2.INPAINT_TELEA启用此算法。 (2)第二种算法基于Bertalmio,Marcelo,Andrea L. Bertozzi和Guillermo Sapiro于2001年撰写的“Navier-Stokes,流体动力学和图像和视频修补”一文。该算法基于流体动力学并利用偏微分方程。基本原则是heurisitic。它首先沿着已知区域的边缘行进到未知区域(因为边缘是连续的)。它继续等照片(连接具有相同强度的点的线,就像轮廓连接具有相同高度的点一样),同时在修复区域的边界处匹配渐变矢量。为此,使用来自流体动力学的一些方法。获得颜色后,填充颜色以减少该区域的最小差异。使用标志cv2.INPAINT_NS启用此算法。

# 方法 1: dst_TELEA = cv2.inpaint(img,mask,3,cv2.INPAINT_TELEA) # 方法2: dst_NS = cv2.inpaint(img,mask,3,cv2.INPAINT_NS)

下面我们看看最后的效果展示: 在这里插入图片描述

在这里插入图片描述

参考链接: https://blog.csdn.net/flyfor2013/article/details/107527395



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有