所以我一直在尝试OpenCV,并使用python从图像中提取特定部分。
我的测试图像是:
从这张图片开始,我想在那堆土壤周围绘制轮廓,如下所示:
(注意:这是在Paint中完成的)
我尝试了以下操作:
但是我不确定下一步该怎么做?如何提取图像的上述部分?
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 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()
但是那里仍然有一些黑色的部分。我可以调整抓图图像的大小吗?另外,我该怎么做? 另外,在图像中,您可以看到仍然有一些背景。我该如何抑制?
我真的需要你的帮助。谢谢。