【问题标题】:How do I detect and remove blurred background from image如何从图像中检测和去除模糊背景
【发布时间】:2017-07-12 09:17:50
【问题描述】:

我有一张背景模糊的图像。我需要做的是去除模糊的背景,只保留锐利的前景物体。他们有什么方法可以使用 openCV 做到这一点吗? 图像将类似于下面的图像。我需要检测并减去模糊的背景。

【问题讨论】:

  • 我很确定边缘检测和循环遍历边缘和图像内的像素并在新图像中设置这些像素!

标签: opencv image-processing blur background-subtraction


【解决方案1】:

这是一个先验的艰巨任务,因为平坦区域(例如衬衫)与模糊区域具有相同的外观(即低梯度活动)。可以尝试一些分割方法并对每个区域的边缘强度进行评分,但这并不简单。

对于穷人的解决方案,这是我尝试过的:

  • 使用边缘检测器并进行二值化,以封闭感兴趣的区域;

  • 执行连通分量分析并选择最大的blob(模糊区域);

  • 填充斑点以获得实心蒙版。

【讨论】:

  • 感谢您的回复,我会看看我能从这里得到什么。
【解决方案2】:

您可以从一个简单的精明边缘检测器开始,它已经为您提供了关于如何解决问题的提示

从那里开始,您应该寻找合适的迭代来将边缘的像素映射到新图像。

【讨论】:

    【解决方案3】:

    这个问题已经有一段时间了,我是从另一个问题那里得到的指示。我想我会用一些代码来回答,只是为了把一些实现放在前面答案的想法后面。

    从 Canny 边缘检测开始寻找前景:

    放大图像以连接精巧的线条。使用 findContours 并选择最大的一个来创建蒙版。

    遮罩上有孔,因为轮廓碰到图像的边缘。我们可以通过反转遮罩并再次使用 findContours 来填充小孔。这次我们将过滤掉非常大的轮廓,并将剩余的轮廓绘制到蒙版上。

    现在我们只需要使用蒙版来裁剪我们的图像。

    这是代码

    import cv2
    import numpy as np
    
    # load image
    img = cv2.imread("foreground.jpg");
    
    # grayscale
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);
    
    # canny
    canned = cv2.Canny(gray, 100, 200);
    
    # dilate to close holes in lines
    kernel = np.ones((5,5),np.uint8)
    mask = cv2.dilate(canned, kernel, iterations = 1);
    
    # find contours
    # Opencv 3.4, if using a different major version (4.0 or 2.0), remove the first underscore
    _, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
    
    # find big contours
    biggest_cntr = None;
    biggest_area = 0;
    for contour in contours:
        area = cv2.contourArea(contour);
        if area > biggest_area:
            biggest_area = area;
            biggest_cntr = contour;
    
    # draw contours
    crop_mask = np.zeros_like(mask);
    cv2.drawContours(crop_mask, [biggest_cntr], -1, (255), -1);
    
    # fill in holes
    # inverted
    inverted = cv2.bitwise_not(crop_mask);
    
    # contours again
    _, contours, _ = cv2.findContours(inverted, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
    
    # find small contours
    small_cntrs = [];
    for contour in contours:
        area = cv2.contourArea(contour);
        if area < 20000:
            print(area);
            small_cntrs.append(contour);
    
    # draw on mask
    cv2.drawContours(crop_mask, small_cntrs, -1, (255), -1);
    
    # opening + median blur to smooth jaggies
    crop_mask = cv2.erode(crop_mask, kernel, iterations = 1);
    crop_mask = cv2.dilate(crop_mask, kernel, iterations = 1);
    crop_mask = cv2.medianBlur(crop_mask, 5);
    
    # crop image
    crop = np.zeros_like(img);
    crop[crop_mask == 255] = img[crop_mask == 255];
    
    # show
    cv2.imshow("original", img);
    cv2.imshow("gray", gray);
    cv2.imshow("canny", canned);
    cv2.imshow("mask", crop_mask);
    cv2.imshow("cropped", crop);
    cv2.waitKey(0);
    

    【讨论】:

      猜你喜欢
      • 2021-05-12
      • 2019-03-20
      • 2017-03-19
      • 2015-05-06
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      相关资源
      最近更新 更多