我想通过彩色遮罩为照片的大约非连续区域生成边界框-在这种情况下,该区域是包含植被的绿色带-以便可以裁剪该区域以传递给图像分类功能。
使用GDAL,可以很容易地使用地理空间栅格来完成对具有相似特征(https://www.gdal.org/gdal_polygonize.html)的Geotiff区域进行多边形处理的操作。但是在这种情况下,我正在尝试对照片进行处理。我还没有找到纯栅格的解决方案。
例如,拍一张像这样的照片:
使用openCV和numpy掩盖为绿色区域:
try:
hsv=cv.cvtColor(image,cv.COLOR_BGR2HSV)
except:
print("File may be corrupt")
return(0,0)
# Define lower and uppper limits of what we call "brown"
brown_lo=np.array([18,0,0])
brown_hi=np.array([28,255,255])
green_lo=np.array([29,0,0])
green_hi=np.array([88,255,255])
# Mask image to only select browns
mask_brown=cv.inRange(hsv,brown_lo,brown_hi)
mask_green=cv.inRange(hsv,green_lo,green_hi)
hsv[mask_brown>0]=(18,255,255)
hsv[mask_green>0]=(53,255,255)
image2=cv.cvtColor(hsv,cv.COLOR_HSV2BGR)
cv.imwrite(QUERIES + 'queries/mask.jpg', image2)
我想为此处指示的区域生成拳击箱或多边形:
有什么想法怎么做?
我尝试使用openCV轮廓和凸包算法,但它们并不能真正带我到任何地方:
threshold = val
# Detect edges using Canny
canny_output = cv.Canny(src_gray, threshold, threshold * 2)
# Find contours
_, contours, _ = cv.findContours(canny_output, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
# Find the convex hull object for each contour
hull_list = []
for i in range(len(contours)):
hull = cv.convexHull(contours[i])
hull_list.append(hull)
# Draw contours + hull results
drawing = np.zeros((canny_output.shape[0], canny_output.shape[1], 3), dtype=np.uint8)
for i in range(len(contours)):
color = (rng.randint(0,256), rng.randint(0,256), rng.randint(0,256))
cv.drawContours(drawing, contours, i, color)
cv.drawContours(drawing, hull_list, i, color)
# Show in a window
cv.imshow('Contours', drawing)
答案 0 :(得分:1)
因此,当您尝试使用轮廓线时它不起作用时,我尝试采用聚类的方式。我从K-means开始,这是开始IMO的最佳位置。这是代码:
import cv2
import numpy as np
from sklearn.cluster import KMeans, MeanShift
import matplotlib.pyplot as plt
def centroid_histogram(clt):
numlabels = np.arange(0, len(np.unique(clt.labels_)) + 1)
(hist, _) = np.histogram(clt.labels_, bins=numlabels)
hist = hist.astype("float")
hist /= hist.sum()
return hist
def plot_colors(hist, centroids):
bar = np.zeros((50, 300, 3), dtype="uint8")
startX = 0
for (percent, color) in zip(hist, centroids):
endX = startX + (percent * 300)
cv2.rectangle(bar, (int(startX), 0), (int(endX), 50),
color.astype("uint8").tolist(), -1)
startX = endX
return bar
image1 = cv2.imread('mean_shift.jpg')
image1 = cv2.cvtColor(image1, cv2.COLOR_BGR2RGB)
image = image1.reshape((image1.shape[0] * image1.shape[1], 3))
#clt = MeanShift(bandwidth=2, bin_seeding=True)
clt = KMeans(n_clusters=3)
clt.fit(image)
hist = centroid_histogram(clt)
bar = plot_colors(hist, clt.cluster_centers_)
plt.figure()
plt.axis("off")
plt.imshow(bar)
plt.show()
使用3个群集中心,我得到以下结果:
并使用6个群集中心:
基本上可以显示图像中这些颜色的比例。
帮助我做到这一点的链接:
https://www.pyimagesearch.com/2014/05/26/opencv-python-k-means-color-clustering/和
https://github.com/log0/build-your-own-meanshift/blob/master/Meanshift%20Image%20Segmentation.ipynb
现在,我在这里看到了几个问题:
您可能不知道所有图像中的簇数。在这种情况下,您应该查看Mean-Shift。与K-Means算法不同,meanshift不需要预先指定簇数。簇的数量由算法根据数据确定。
我在这些问题中使用了SLIC。它是基于K均值的算法的子集,非常有效。您也可以尝试一下,因为它在scikit中可用,它是python IMO中用于机器学习的goto库。在同一方向上,您也可以尝试this。
希望我能为您提供一些帮助!干杯!