Python 从图像中提取特定部分

Python 从图像中提取特定部分,python,numpy,opencv,Python,Numpy,Opencv,所以我一直在试验OpenCV,并用python从图像中提取特定部分 我的测试图像是: 从这张图片中,我想画出土壤堆周围的等高线,如下所示: (注:这是在油漆中完成的) 我试过以下几件事: 读取图像并将其转换为灰度 形态变换和阈值设置如下: 但我不知道下一步该怎么办?如何提取图像的上述部分 import cv2 img = cv2.imread('Feature Extraction/soil_stockpile_test_image.png', cv2.IMREAD_GRAYSCALE)

所以我一直在试验OpenCV,并用python从图像中提取特定部分

我的测试图像是:

从这张图片中,我想画出土壤堆周围的等高线,如下所示:

(注:这是在油漆中完成的)

我试过以下几件事:

  • 读取图像并将其转换为灰度
  • 形态变换和阈值设置如下:
  • 但我不知道下一步该怎么办?如何提取图像的上述部分

    import cv2
    
    img = cv2.imread('Feature Extraction/soil_stockpile_test_image.png', 
    cv2.IMREAD_GRAYSCALE)
    blur = cv2.GaussianBlur(img, (1, 1), 2)
    h, w = img.shape[:2]
    
    # Morphological gradient
    
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
    gradient = cv2.morphologyEx(blur, cv2.MORPH_GRADIENT, kernel)
    cv2.imshow('Morphological gradient', gradient)
    
    #Contours
    thresh = cv2.threshold(img,150, 255,cv2.THRESH_BINARY_INV)[1]
    cnts, h = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    cv2.imshow('thresh', thresh)
    
    多谢各位

    编辑1:

    正如@eldesgraciado所建议的,我尝试了直方图反投影法。它有点工作,但它仍然显示图像中一些不需要的部分。我只想在结果中显示库存

    以下是代码和生成的图像:

    # Original Image
    orig_img = cv2.imread('Feature Extraction/soil_stockpile_test_image.png')
    roi = cv2.imread('Feature Extraction/roi_soil.png')
    
    # HSV Image
    hsv_img = cv2.cvtColor(orig_img, cv2.COLOR_BGR2HSV)
    hsv_roi = cv2.cvtColor(roi, cv2.COLOR_BGR2HSV)
    
    # Region of Interest
    roi_hist = cv2.calcHist([hsv_roi], [0, 1], None, [180, 256], [0, 180, 0, 256])
    mask = cv2.calcBackProject([hsv_img], [0, 1], roi_hist, [0, 180, 0, 256], 1)
    
    
    # Remove Noise
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
    mask = cv2.filter2D(mask, -1, kernel)
    _, mask = cv2.threshold(mask, 210, 255, cv2.THRESH_BINARY)
    
    # Merge and perform bitwise operation
    mask = cv2.merge((mask, mask, mask))
    result = cv2.bitwise_and(orig_img, mask)
    
    #cv2.imshow('HSV Image', hsv_img)
    #cv2.imshow('Region of Interest', roi)
    #cv2.imshow('Mask', mask)
    cv2.imshow('Result', result)
    
    结果:

    编辑2:

    使用grab cut算法后,使用以下代码,这是我得到的结果:

    # Grab Cut Mask
    img = cv2.imread('Feature Extraction/soil_stockpile_test_image.png')
    
    # These params have been hardcoded. Need to be changed for every image.
    top_left_x = 300
    top_left_y = 150
    bottom_right_x = 600
    bottom_right_y = 350
    Green_color = (0, 255, 0)
    
    # Draw the rectangle
    output = cv2.rectangle(img,
                    (top_left_x, top_left_y),
                    (bottom_right_x, bottom_right_y),
                    color=Green_color, thickness=3)
    
    #cv2.imwrite('Output_Image_with_Rectangle.jpg', output)
    #cv2.imshow('Output Image with Rectangle', output)
    
    # Grab Cut Mask
    mask = np.zeros(img.shape[:2],np.uint8)
    
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    
    rect = (top_left_x, top_left_y, bottom_right_x, bottom_right_y)
    cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
    
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    new_img = img*mask2[:,:,np.newaxis]
    
    cv2.imwrite('Grab_Cut_img.jpg', new_img)
    plt.imshow(new_img),plt.colorbar(),plt.show()
    

    但还是有一些黑色的部分。我可以调整这个抓取剪切图像的大小吗?还有,我该怎么做? 此外,在图像中,您可以看到仍然有一些背景。如何抑制这种情况


    我真的需要你的帮助。谢谢。

    你试过了吗?@eldesgraciado是的,我试过了。请选择编辑1。但我不确定这是正确的还是我没有使用正确的参数。另外,在结果图像中,我如何绘制一条曲线来表示这是我想要的图像的一部分?@eldesgraciado我使用了抓取切割算法,结果可以在问题的编辑2中看到。但面具中仍然有一些背景。“我该怎么做?你试过了吗?”埃尔德斯格拉齐亚多:是的,我试过了。请选择编辑1。但我不确定这是正确的还是我没有使用正确的参数。另外,在结果图像中,我如何绘制一条曲线来表示这是我想要的图像的一部分?@eldesgraciado我使用了抓取切割算法,结果可以在问题的编辑2中看到。但面具中仍然有一些背景。我该怎么做?