Python 图像处理 - 如何删除某些轮廓并将值与周围像素混合?

标签 python opencv image-processing computer-vision

我正在做一个带有深度图像的项目。但是我的深度相机有噪音和像素读取失败的问题。有一些点和轮廓(尤其是边缘)的值为零。如何忽略这个零值并将其与周围的值混合?
我试过 dilationerosion (变形图像处理),但我仍然无法获得正确的组合。它确实消除了一些噪音,但我只需要消除所有点的零

图像示例:

Depth Image

零值是最深的蓝色(我正在使用颜色图)

为了说明我想做什么,请引用这张糟糕的油漆图:

Illustration

我想摆脱黑点(例如黑色值为 0 或某个值),并将其与其周围混合。
是的,我可以使用 np.where 定位该地点或类似的功能,但我不知道如何混合它。也许要应用过滤器?我需要在流中执行此操作,因此我需要一个相当快的过程,也许 10-20 fps 就可以了。先感谢您!

更新:

除了inpaint还有别的方法吗?我已经寻找了各种修复,但我不需要像修复那样复杂。我只需要将它与简单的线条、曲线或形状和一维混合。我认为inpaint是一种矫枉过正。此外,我需要它们足够快以用于 10-20 fps 的视频流,甚至更好。

最佳答案

这是在 Python/OpenCV 中执行此操作的一种方法。

使用中值滤波来填补空缺。

  • 读取输入
  • 转换为灰色
  • 做口罩的阈值( Blob 是黑色的)
  • 反转面膜( Blob 为白色)
  • 从倒置掩模中找到最大的光斑轮廓周长,并使用该值的一半作为中值滤波器大小
  • 对图像应用中值滤波
  • 将掩码应用于输入
  • 将逆掩码应用于中值滤波图像
  • 将两者相加形成结果
  • 保存结果

  • 输入:

    enter image description here
    import cv2
    import numpy as np
    import math
    
    # read image
    img = cv2.imread('spots.png')
    
    # convert to gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # threshold 
    mask = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)[1]
    
    # erode mask to make black regions slightly larger
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
    mask = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
    
    
    # make mask 3 channel
    mask = cv2.merge([mask,mask,mask])
    
    # invert mask
    mask_inv = 255 - mask
    
    # get area of largest contour
    contours = cv2.findContours(mask_inv[:,:,0], cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    perimeter_max = 0
    for c in contours:
        perimeter = cv2.arcLength(c, True)
        if perimeter > perimeter_max:
            perimeter_max = perimeter
    
    # approx radius from largest area
    radius = int(perimeter_max/2) + 1
    if radius % 2 == 0:
        radius = radius + 1
    print(radius)
    
    # median filter input image
    median = cv2.medianBlur(img, radius)
    
    # apply mask to image
    img_masked = cv2.bitwise_and(img, mask)
    
    # apply inverse mask to median
    median_masked = cv2.bitwise_and(median, mask_inv)
    
    # add together
    result = cv2.add(img_masked,median_masked)
    
    # save results
    cv2.imwrite('spots_mask.png', mask)
    cv2.imwrite('spots_mask_inv.png', mask_inv)
    cv2.imwrite('spots_median.png', median)
    cv2.imwrite('spots_masked.png', img_masked)
    cv2.imwrite('spots_median_masked.png', median_masked)
    cv2.imwrite('spots_removed.png', result)
    
    cv2.imshow('mask', mask)
    cv2.imshow('mask_inv', mask_inv )
    cv2.imshow('median', median)
    cv2.imshow('img_masked', img_masked)
    cv2.imshow('median_masked', median_masked)
    cv2.imshow('result', result)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    阈值图像作为掩码:

    enter image description here

    倒置掩码:

    enter image description here

    中值滤波图像:

    enter image description here

    蒙版图像:

    enter image description here

    屏蔽中值滤波图像:

    enter image description here

    结果:

    enter image description here

    关于Python 图像处理 - 如何删除某些轮廓并将值与周围像素混合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61565277/

    相关文章:

    java - 允许数组中的线程不安全

    image-processing - 图像处理: How to get luminance weighting value?

    python - 是什么导致了这个程序的错误

    python - 是否有(已经)一种方法来比较 2 个模型实例,一个字段一个字段,看它们是否相等?

    python - 为什么opencv-python的cv2.bitwise_and函数在单个标量值上返回四个元素数组

    c++ - 将 PNG 类型资源转换为 cv::Mat 时的 CreateDIBSection ERROR_TAG_NOT_FOUND

    flutter - 如何在Flutter中裁剪图像?

    python - 在 Anaconda 中,如何在非 ROOT 环境下安装软件包?

    python - 优化此解决方案以查找公交网络中两个站点之间的最短路径

    opencv - 无法在 Ubuntu 上安装 cmake(构建错误)