使用Python的自定义种子轮廓检测 – OpenCV
本文讨论我们如何通过单击图像来动态检测轮廓,并为图像的不同部分分配不同的颜色。轮廓是用于形状分析和对象检测和识别的非常有用的工具。该程序使用 OpenCV、Numpy 和 Matplotlib 库。它还使用内置的 OpenCV 分水岭算法来检测轮廓。
要求
- Python和 OpenCV 必须安装在本地机器上。
- 安装 Jupyter Notebook 以便于调试。
- 这里使用 Matplotlib 的 colormap 来获取不同的颜色。在下面给出的示例中,我们将使用 tab10。您可以选择不同的颜色图。有关不同颜色的信息,请参阅此站点。
解释
- 运行程序。
- 单击要制作轮廓的图像。
- 通过按从零到九的数字为图像的不同部分选择不同的颜色。 (一种颜色一个数字)
下面是实现。
Python3
# Import modules
import cv2
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
# Upload the image in the same directory and then run the code
# If image not found you may get an error
# Reading Image
road = cv2.imread('road_image.jpg')
# Making Copy of Image
road_copy = np.copy(road)
# Creating two black image of same size as original image
marker_image = np.zeros(road.shape[:2], dtype=np.int32)
segments = np.zeros(road.shape, dtype=np.uint8)
# Function to return tuple of colors
def create_rgb(i):
x = np.array(cm.tab10(i))[:3]*255
return tuple(x)
# Storing Colors
colors = []
# One color for each single digit
for i in range(10):
colors.append(create_rgb(i))
# Global Variables
# Color Choices
# Number of markers
no_markers = 10
# Current markers
current_marker = 1
# Flag
marks_updated = False
# CALLBACK FUNCTION
def mouse_callback(event, x, y, flags, param):
global marks_updated
if event == cv2.EVENT_LBUTTONDOWN:
# TRACKING FOR MARKERS
cv2.circle(marker_image, (x, y), 5, (current_marker), -1)
# DISPLAY ON USER IMAGE
cv2.circle(road_copy, (x, y), 5, colors[current_marker], -1)
marks_updated = True
# Naming the window and setting call back funtion to it
cv2.namedWindow('Road Image')
cv2.setMouseCallback('Road Image', mouse_callback)
while True:
# Show the 2 windows
cv2.imshow('WaterShed Segments', segments)
cv2.imshow('Road Image', road_copy)
# Close everything if Esc is pressed
k = cv2.waitKey(1)
if k == 27:
break
# Clear all colors and start over if 'c' is pressed
elif k == ord('c'):
road_copy = road.copy()
marker_image = np.zeros(road.shape[0:2], dtype=np.int32)
segments = np.zeros(road.shape, dtype=np.uint8)
# If a number 0-9 is chosen index the color
elif k > 0 and chr(k).isdigit():
# chr converts to printable digit
current_marker = int(chr(k))
# If we clicked somewhere, call the watershed
# algorithm on our chosen markers
if marks_updated:
marker_image_copy = marker_image.copy()
cv2.watershed(road, marker_image_copy)
segments = np.zeros(road.shape, dtype=np.uint8)
for color_ind in range(no_markers):
# COLORING SEGMENTS
segments[marker_image_copy == (color_ind)] = colors[color_ind]
marks_updated = False
# Destroy all the windows at the end
cv2.destroyAllWindows()
输出:
此代码将打开两个窗口。一张是原图,一张是黑色的。单击原始图像将在其上创建小圆圈,轮廓将显示在黑色图像上。 (按 0-9 之间的数字来更改颜色并生成不同的等高线图。)