Python图像处理-如何删除某些轮廓并将值与周围像素混合? [英] Python Image Processing - How to remove certain contour and blend the value with surrounding pixels?

查看:824
本文介绍了Python图像处理-如何删除某些轮廓并将值与周围像素混合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm doing a project with depth image. But I have problems with noise and failed pixel reading with my depth camera. There are some spots and contours (especially edges) that have zero value. How to just ignore this zero value and blend it with surrounding values? I have tried dilation and erosion (morph image processing), but I still can't get the right combination. It indeed removed some of the noise, but I just need to get rid of zeros at all points

图片示例:

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

The zero value is the darkest blue (I'm using colormap)

为说明我想做的事,请参阅这张较差的绘画图纸:

To illustrate what I want to do, please refer to this poor paint drawing:

我要消除黑点(例如,黑值为0或特定值),并将其与周围混合。
是的,我可以使用 np.where 或类似功能来定位该地点,但是我不知道如何将其融合。也许要应用一个过滤器?我需要在流中执行此操作,因此我需要一个相当快的过程,也许会以10-20 fps的速度执行。

I want to get rid the black spot (for example black value is 0 or certain value), and blend it with its surround. Yes, I'm able to localized the spot using np.where or the similar function, but I have no idea how to blend it. Maybe a filter to be applied? I need to do this in a stream, so I need a fairly fast process, maybe 10-20 fps will do. Thank you in advance!

更新:

还有其他方法吗?修补?我一直在寻找各种喷绘,但是我不需要像喷绘这样的复杂技术。我只需要将其与简单的直线,曲线或形状以及1D混合即可。我认为上漆太过分了。此外,我需要它们足够快以用于10-20 fps的视频流,甚至更好。

Is there a way other than inpaint? I've looked for various inpaints, but I don't need as sophisticated as impainting. I just need to blend it with simple line, curve, or shape and 1D. I think inpaint is an overkill. Besides, I need them to be fast enough to be used for video stream 10-20 fps, or even better.

推荐答案

此处是在Python / OpenCV中做到这一点的一种方法。

Here is one way to do that in Python/OpenCV.

使用中值过滤来填补漏洞。


  • 读取输入

  • 转换为灰色

  • 阈值以制作蒙版(斑点为黑色)

  • 反转遮罩(斑点为白色)

  • 从反转遮罩中找到最大的斑点轮廓周长,并将该值的一半用作中值滤镜大小

  • 对图像应用中值滤波

  • 对输入内容应用掩码

  • 对中值滤波图像应用反掩码

  • 将两者加在一起形成结果

  • 保存结果

  • Read the input
  • Convert to gray
  • Threshold to make a mask (spots are black)
  • Invert the mask (spots are white)
  • Find the largest spot contour perimeter from the inverted mask and use half of that value as a median filter size
  • Apply median filtering to the image
  • Apply the mask to the input
  • Apply the inverse mask to the median filtered image
  • Add the two together to form the result
  • Save the results

输入:

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()



阈值图像作为掩码:


Threshold image as mask:

反面罩:

< a href = https://i.stack.imgur.com/lqB4K.png rel = noreferrer>

已过滤图像的中位数:

蒙版图像:

屏蔽的中值滤波图像:

结果:

这篇关于Python图像处理-如何删除某些轮廓并将值与周围像素混合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆