📜  使用Python的自定义种子轮廓检测 – OpenCV

📅  最后修改于: 2022-05-13 01:55:09.544000             🧑  作者: Mango

使用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 之间的数字来更改颜色并生成不同的等高线图。)

原图

处理后的图像