从图像中提取特定部分

时间:2020-05-19 05:34:27

标签: python numpy opencv

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

我的测试图像是:

enter image description here

从这张图片开始,我想在那堆土壤周围绘制轮廓,如下所示:

(注意:这是在Paint中完成的)

enter image description here

我尝试了以下操作:

  1. 读取图像并将其转换为灰度
  2. 形态转换和阈值如下:

但是我不确定下一步该怎么做?如何提取图像的上述部分?

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)

结果:

enter image description here

编辑2:

使用抓取剪切算法后,通过以下代码,这是我获得的结果:

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

enter image description here

但是那里仍然有一些黑色的部分。我可以调整抓图图像的大小吗?另外,我该怎么做? 另外,在图像中,您可以看到仍然有一些背景。我该如何抑制?

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

0 个答案:

没有答案
相关问题