【问题标题】:How to improve edge detection and remove background from an image?如何改善边缘检测并从图像中去除背景?
【发布时间】:2019-03-20 02:04:39
【问题描述】:

我正在使用下面的代码删除图像的背景并仅突出显示我的感兴趣区域 (ROI),但是,该算法在某些图像中的行为方式错误,丢弃了污点 (ROI) 并删除了背景。

import numpy as np
import cv2

#Read the image and perform threshold
img = cv2.imread('photo.bmp')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blur = cv2.medianBlur(gray,5)
_,thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

#Search for contours and select the biggest one
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)

#Create a new mask for the result image
h, w = img.shape[:2]
mask = np.zeros((h, w), np.uint8)

#Draw the contour on the new mask and perform the bitwise operation
cv2.drawContours(mask, [cnt],-1, 255, -1)
res = cv2.bitwise_and(img, img, mask=mask)

#Display the result
cv2.imwrite('photo.png', res)
#cv2.imshow('img', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

【问题讨论】:

    标签: python image opencv image-processing opencv3.0


    【解决方案1】:

    我不知道我是否理解正确,因为当我运行您的代码时,我没有得到您发布的输出(退出)。如果您只想获得痣,则无法通过简单的阈值处理来完成,因为痣太靠近边界,而且如果您仔细查看图像,您会发现它有某种框架。然而,有一种简单的方法可以对这个图像执行此操作,但在其他情况下它可能不起作用。您可以在图像上绘制假边框并将 ROI 与其他噪声区域分开。然后为您希望显示的轮廓设置一个阈值。干杯!

    例子:

    #Import all necessery libraries
    import numpy as np
    import cv2
    
    #Read the image and perform threshold and get its height and weight
    img = cv2.imread('moles.png')
    h, w = img.shape[:2]
    
    # Transform to gray colorspace and blur the image.
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    blur = cv2.GaussianBlur(gray,(5,5),0)
    
    # Make a fake rectangle arround the image that will seperate the main contour.
    cv2.rectangle(blur, (0,0), (w,h), (255,255,255), 10)
    
    # Perform Otsu threshold.
    _,thresh = cv2.threshold(blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)
    
    # Create a mask for bitwise operation
    mask = np.zeros((h, w), np.uint8)
    
    # Search for contours and iterate over contours. Make threshold for size to
    # eliminate others.
    _, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
    
    for i in contours:
        cnt = cv2.contourArea(i)
        if 1000000 >cnt > 100000:
            cv2.drawContours(mask, [i],-1, 255, -1)
    
    
    # Perform the bitwise operation.
    res = cv2.bitwise_and(img, img, mask=mask)
    
    # Display the result.
    cv2.imwrite('mole_res.jpg', res)
    cv2.imshow('img', res)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果:

    【讨论】:

    • 我明白,它奏效了。只有 ROI 未到达边缘的图像不会返回污点,如何使该算法同时为到达边缘的图像和未到达的图像服务?
    • 不能从我的头顶说。你试过用其他图像吗?如果它失败了,你应该提出一个新问题,并给出一些代码失败的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 2021-01-04
    • 2011-09-26
    • 2016-09-11
    相关资源
    最近更新 更多