通过python opencv从图像中提取模式

2024-05-13 04:52:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有很多这样的照片。 the source image

从图中我们可以看到,有两种建筑,第一种是用纯色填充的,第二种是用斜线填充的

我用绿色标记第一种,用红色标记第二种

two kinds of buildings

我想我可以用彩色面具来提取第一种风格的建筑,但是第二种呢

我知道我可以通过训练一个图像分割模型来达到目标,但是有可能使用纯图像处理方法来获得它吗


Tags: 方法标记模型图像风格图像处理照片彩色
1条回答
网友
1楼 · 发布于 2024-05-13 04:52:26

我将根据颜色对图像进行阈值分割,然后使用FindOntours获得每个单独的建筑。然后我将它们按大小分为“大建筑”或“小建筑”,这取决于它们是大于还是小于“截止”值

截止值=2000

enter image description here

截止值=4000

enter image description here

截止值=6000

enter image description here

这是我使用的代码。您需要按“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);

编辑:

下面是一些代码,用于查找“细线”建筑。这种按特定颜色分割的方法有点僵硬,尤其是对于这些建筑,因为它们没有单一的颜色

enter image description here

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);

相关问题 更多 >