首页 > 解决方案 > 循环遍历像素图像以找到该像素与任意值的最接近的值

问题描述

问题陈述:在yolo中成功获得物体周围的边界框后,我想将背景与物体本身分开。

我的解决方案:我有一个 RGB-D 相机,它返回深度图以及图像(图像被提供给 yolo obv),使用深度图,我做了一个简单的函数来获取深度(四舍五入)和多少像素具有相同的价值

def GetAllDepthsSortedMeters(depth_image_ocv):
    _depth = depth_image_ocv[np.isfinite(depth_image_ocv)]
    _depth= -np.sort(-depth_image_ocv)[:int(len(_depth)/2)]
    _depth=  np.round(_depth,1)
    unique, counts = np.unique(_depth, return_counts=True)
    return dict(zip(counts, unique))

并绘制它们,我注意到有主峰,其余的位于它们周围,经过一些过滤后,我每次都能成功地获得这些峰。

    #get the values of depths and their number of occurences
    counts,values = GetKeysAndValues(_depths)
    #find the peaks of depths in those values
    peaks = find_peaks_cwt(counts, widths=np.ones(counts.shape)*2)-1

使用这些峰值,我能够通过检查该值接近的峰值来从背景中分割出所需的对象,并为每个峰值(及其周围的像素)制作一个蒙版。

def GetAcceptedMasks(h,w,depth_map,depths_of_accepted_peaks,accepted_masks):
    prev=None
    prev_index=None

    for pos in product(range(h), range(w)):
        pixel = depth_map.item(pos)
        if ( (prev is not None) and (round(prev,1) == round(pixel,1)) ):
                accepted_masks[prev_index][pos[0],pos[1]]= 255
        else:
            _temp_array    = abs(depths_of_accepted_peaks-pixel)
            _min           = np.amin(_temp_array)
            _ind           = np.where( _temp_array == _min )[0][0]
            accepted_masks[_ind][pos[0],pos[1]]= 255
            prev_index = _ind
            prev = pixel

    return accepted_masks

将图像通过 YOLOv3 并应用过滤和深度分割后,它需要 0.8 秒,这远非最佳,这主要是上述功能的结果,任何帮助都会很棒。谢谢你

这是我最后得到的面具

Mask1-Of-Closest-Depth

Mask2-Of-2nd-Closest-Depth

Mask3-Of-3rd-Closest-Depth

编辑:距离示例:

[0.60000002 1.29999995 1.89999998]

使用 imshow 显示时 的深度图示例:深度图示例

标签: pythonnumpyopencv

解决方案


这是一种方法。

  • 使浮点数组的高度和宽度与您的图像相同,并且最终尺寸等于您要识别的唯一深度的数量

  • 在每个像素位置,计算到三个所需深度中的每一个的距离并存储在最终维度中

  • 用于np.argmin(..., axis=2)选择三个中最接近的深度

我不是在计算机上进行测试,您的图像不是您的实际图像,而是带有窗口装饰和标题栏以及不同值的图片,但是像这样:

import cv2

# Load the image as greyscale float - so we can store positive and negative distances
im = cv2.imread('depth.png', cv2.IMREAD_GRAYSCALE).astype(np.float)

# Make list of the desired depths
depths = [255, 181, 125]

# Make array with distance to each depth
d2each = np.zeros(((im.shape[0],im.shape[1],len(depths)), dtype=np.float)
for i in range(len(depths)):
    d2each[...,i] = np.abs(im - depths[i])

# Now let Numpy choose nearest of three distances
mask = np.argmin(d2each, axis=2)

另一种方法是对距离进行范围测试。如上加载图像:

# Make mask of pixels matching first distance 
d0 = np.logical_and(im>100, im<150)

# Make mask of pixels matching second distance 
d1 = np.logical_and(im>180, im<210)

# Make mask of pixels matching third distance 
d2 = im >= 210

这些掩码是合乎逻辑的(即真/假),但如果你想让它们变成黑白,只需将它们乘以 255 并使用mask0 = d0.astype(np.uint8)


另一种方法可能是使用K-means 聚类


推荐阅读