本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。
原文链接:使用OpenCV图像修复技术去除眩光
眩光是一种因过度和不受控制的亮度而引起的视觉感觉。眩光可能会使人丧失能力或只是让人感到不舒服。眩光是一种主观感受,对眩光的敏感度可能有很大差异。老年人通常对眩光更敏感,这是由于眼睛的老化特性。
首先,我们需要检测眩光存在的位置。我们可以使用全局二值化轻松识别它们,因为当眩光通常存在时,该像素值大于 180。使用它可以检测到眩光。因此,我们需要获取大于 180 的像素,然后进行移除部分。
下面的函数用于获取图像的蒙版,其中当像素大于 180 且低于其黑色时,像素为白色。我们将图像的实际眩光位置设为白色,而其他地方设为黑色。
def create_mask(image):
gray = cv2.cvtColor( image, cv2.COLOR_BGR2GRAY )
blurred = cv2.GaussianBlur( gray, (9,9), 0 )
_,thresh_img = cv2.threshold( blurred, 180, 255, cv2.THRESH_BINARY)
thresh_img = cv2.erode( thresh_img, None, iterations=2 )
thresh_img = cv2.dilate( thresh_img, None, iterations=4 )
# perform a connected component analysis on the thresholded image,
# then initialize a mask to store only the "large" components
labels = measure.label( thresh_img, neighbors=8, background=0 )
mask = np.zeros( thresh_img.shape, dtype="uint8" )
# loop over the unique components
for label in np.unique( labels ):
# if this is the background label, ignore it
if label == 0:
continue
# otherwise, construct the label mask and count the
# number of pixels
labelMask = np.zeros( thresh_img.shape, dtype="uint8" )
labelMask[labels == label] = 255
numPixels = cv2.countNonZero( labelMask )
# if the number of pixels in the component is sufficiently
# large, then add it to our mask of "large blobs"
if numPixels > 300:
mask = cv2.add( mask, labelMask )
return mask
我们在这个函数中所做的是,我们首先将图像转换为灰度,使用高斯矩阵(9x9)模糊图像以减少噪音。在全局阈值方法中将阈值设置为 180,将模糊图像转换为二进制图像,其中像素值高于 180 为白色,其他为黑色。我们可能会有小块噪音;为此,我们对二进制图像进行了一系列侵蚀和扩张。
经过这种膨胀、腐蚀之后,我们的图像可能会出现小噪音。为此,我们对阈值图像进行了连通分量分析。scikit-image 库的 measure.labels 方法用于连通分量分析。使用 np.zeros 方法创建一个新的黑色图像,其形状与二值图像完全相同。它被称为掩码。
我们开始循环遍历每个唯一标签。如果标签为零,那么我们知道我们正在检查背景区域,并且可以安全地忽略它。否则,我们只为当前区域构建一个掩码。然后计算 labelMask 中非零像素的数量。如果 numPixels 超过预定义的阈值(在本例中,总共300 个像素),那么我们认为该 blob“足够大”并将其添加到我们的掩码中。这种检测方法的灵感来自这里。作者在那里很好地解释了这种方法。
所以我们的面具会像下面这样:
我们发现了图像中的眩光/明亮之处。我们可以使用各种方法去除这些斑点。
修复方法:
CLAHE 方法
OpenCV的修复方法
在图像预处理中,用不同方法填充图像的某些区域称为修复。基本上,修复就是填补空白。
那么我们可以在 python OpenCV 中使用哪些方法来填充它呢?您可以使用Naiver-Stokes 方法或 Fast — Marching 方法进行填充。
Naiver-Stokes 方法
可以使用偏微分方程更新区域的图像强度,并且可以通过图像拉普拉斯算子计算图像的平滑度(拉普拉斯算子是图像的二阶空间导数的二维各向同性度量。图像的拉普拉斯算子突出显示强度变化迅速的区域,因此经常用于边缘检测(参见零交叉边缘检测器)。拉普拉斯算子通常应用于首先用近似高斯平滑滤波器进行平滑的图像,以降低其对噪声的敏感性,因此这里将一起描述这两个变体。运算符通常将单个灰度图像作为输入并产生另一个灰度图像作为输出)
拉普拉斯算子和偏微分方程可用于保留边缘并继续在平滑区域传播颜色信息。这是进行图像修复的方法之一。
https://www.math.ucla.edu/~bertozzi/papers/cvpr01.pdf
快速行进法
像素已知图像邻域的加权平均值用于修复图像平滑度。已知邻域像素和梯度用于估计要修复的像素的颜色。
https://www.semanticscholar.org/paper/An-Image-Inpainting-Technique-Based-on-the-Fast-Telea/67d0cb47d14150daff08980efbea9f1267d3a4e5
我们可以使用上述任何一种算法来修复。
如何在 OpenCV python 中使用:
dst = cv2.inpaint( src, inpaintMask,inpaintRadius,flags)
-
src → 输入的眩光图像
-
inpaintMask → 指示要修复的像素的二进制掩码。
-
dst → 输出图像
-
inpaintRadius → 要修复的像素周围的邻域。
-
flags → INPAINT_NS,(基于 Navier-Stokes 的方法) 或 INPAINT_TELEA (基于快速行进的方法)
当我们选择 inpaintRadius 时,如果要修复的区域很薄,则较小的值会产生更好的效果(更少模糊)。
让我们将其应用到我们的图像中:
参考链接:
https://dsp.stackexchange.com/questions/1215/how-to-remove-a-glare-clipped-brightness-from-an-image
matlab - How to Remove a Glare / Clipped Brightness from an Image? - Signal Processing Stack Exchange
https://dsp.stackexchange.com/questions/1215/how-to-remove-a-glare-clipped-brightness-from-an-image
THE END !
文章结束,感谢阅读。您的点赞,收藏,评论是我继续更新的动力。大家有推荐的公众号可以评论区留言,共同学习,一起进步。