我根据颜色对图像进行阈值处理,然后使用 findContours 来获取每个单独的建筑物。然后我将它们按大小分类为“大建筑”或“小建筑”,具体取决于它们是大于还是小于“截止”值。
截止值 = 2000
截止值 = 4000
截止值 = 6000
这是我使用的代码。您需要按“q”移动经过第一个窗口(用于单击图像以获取颜色)。您可以通过修改截止变量来更改建筑物的分割。
import cv2
import numpy as np
# get pixel value under mouse
def clicky(event, x, y, flags, params):
if event == cv2.EVENT_LBUTTONUP:
global img;
print(img[y][x]);
# load image
img = cv2.imread("town.png");
# find values
cv2.namedWindow("Original");
cv2.setMouseCallback("Original", clicky);
while True:
cv2.imshow("Original", img);
if cv2.waitKey(1) == ord('q'):
break;
# threshold values
# [232 232 238]
mask = cv2.inRange(img, (232, 232, 238), (232, 232, 238));
# erode to get some seperation
kernel = np.ones((3,3),np.uint8)
mask = cv2.erode(mask,kernel,iterations = 1);
# get contours
# Opencv 3.4, if using a different major version (4.0 or 2.0), remove the first underscore
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);
# filter by size
cutoff = 6000; # change this to change how they are classified
big_contours = [];
small_contours = [];
for contour in contours:
area = cv2.contourArea(contour);
if area > cutoff:
big_contours.append(contour);
else:
small_contours.append(contour);
# draw contours on mask
colored_mask = np.zeros_like(img);
cv2.drawContours(colored_mask, big_contours, -1, (155, 200, 0), -1);
cv2.drawContours(colored_mask, small_contours, -1, (0, 155, 200), -1);
# show
cv2.imshow("town", img);
cv2.imshow("mask", mask);
cv2.imshow("colored_mask", colored_mask);
cv2.waitKey(0);
编辑:
这里有一些用于查找“细线”建筑物的代码。不过,这种按特定颜色进行分割的方法有点笨拙,尤其是对于这些建筑物,因为它们没有单一的颜色。
import cv2
import numpy as np
# get pixel value under mouse
def clicky(event, x, y, flags, params):
if event == cv2.EVENT_LBUTTONUP:
global img;
print(img[y][x]);
# load image
img = cv2.imread("town.png");
# find color values
cv2.namedWindow("Original");
cv2.setMouseCallback("Original", clicky);
while True:
cv2.imshow("Original", img);
if cv2.waitKey(1) == ord('q'):
break;
# set color values
colors = [];
colors.append((227, 228, 228));
colors.append((248, 251, 251));
colors.append((229, 241, 238));
colors.append((240, 242, 242));
colors.append((234, 236, 238));
# threshold values
mask = np.zeros_like(img[:,:,0]);
for color in colors:
next_mask = cv2.inRange(img, color, color);
mask = cv2.bitwise_or(mask, next_mask);
# dilate and erode
kernel = np.ones((3,3),np.uint8);
mask = cv2.dilate(mask, kernel, iterations = 5);
mask = cv2.erode(mask, kernel, iterations = 5);
# colored
img[mask == 255] = (155, 200, 0);
# show
cv2.imshow("town", img);
cv2.imshow("mask", mask);
cv2.waitKey(0);