如何使用 OpenCV-Python 检测照片上的黑色形状轮廓

Mil*_*laa 5 python opencv numpy image-processing computer-vision

我正在尝试检测这样的照片上的黑色形状。

在此输入图像描述

到目前为止,我已经有了带有形状的图片,但仍然有很多线条和噪音,因此我无法使用 findContours() 因为它也标记了线条。您能给我一些建议或帮助我完成这项任务吗?我将非常感谢您的帮助!

原图

在此输入图像描述

二值图像

在此输入图像描述

import cv2
import numpy as np
import imutils

def color_seg(choice):
    if choice == 'blue':
        lower_hue = np.array([100,30,30])
        upper_hue = np.array([150,148,255])
    elif choice == 'white':
        lower_hue = np.array([0,0,0])
        upper_hue = np.array([0,0,255])
    elif choice == 'black':
        lower_hue = np.array([0,0,0])
        upper_hue = np.array([50,50,100])
    return lower_hue, upper_hue


# Take each frame
frame = cv2.imread('11.jpg')
#frame = cv2.imread('images/road_1.jpg')

frame = imutils.resize(frame, height = 500)
chosen_color = 'black'


# Convert BGR to HSV
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

# define range of a color in HSV
lower_hue, upper_hue = color_seg(chosen_color)


# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower_hue, upper_hue)


kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(mask,kernel,iterations = 10)
erosion = cv2.filter2D(mask,-1,kernel)
erosion = cv2.GaussianBlur(mask,(5,5),cv2.BORDER_DEFAULT)




cv2.imshow('frame',frame)
cv2.imshow('mask',mask)

cv2.waitKey(0)
Run Code Online (Sandbox Code Playgroud)

nat*_*ncy 3

你走在正确的轨道上。获得二值图像后,您需要执行形态学操作以滤除噪声并隔离对象。之后,我们可以找到轮廓,然后使用轮廓近似和轮廓区域进行过滤。我们将检测到的区域绘制到空白掩模上,然后按位与原始图像一起绘制。步骤如下:

二值图像

在此输入图像描述

形态学运算

在此输入图像描述

检测到的区域呈绿色

在此输入图像描述

按位运算后的隔离结果

在此输入图像描述

代码

import numpy as np
import cv2

# Color threshold
image = cv2.imread('1.jpg')
original = image.copy()
blank = np.zeros(image.shape, dtype=np.uint8)
blur = cv2.GaussianBlur(image, (7,7), 0)
hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 0])
upper = np.array([179, 93, 97])
mask = cv2.inRange(hsv, lower, upper)

# Morph operations
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
opening = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel, iterations=1)
close = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel, iterations=2)

# Find contours and filter using contour approximation + contour area
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.04 * peri, True)
    area = cv2.contourArea(c)
    if len(approx) > 3 and area > 1000:
        cv2.drawContours(image, [c], -1, (36,255,12), -1)
        cv2.drawContours(blank, [c], -1, (255,255,255), -1)

# Bitwise-and for result
blank = cv2.cvtColor(blank, cv2.COLOR_BGR2GRAY)
result = cv2.bitwise_and(original,original,mask=blank)
result[blank==0] = (255,255,255)

cv2.imshow('mask', mask)
cv2.imshow('opening', opening)
cv2.imshow('close', close)
cv2.imshow('result', result)
cv2.imshow('image', image)
cv2.waitKey()
Run Code Online (Sandbox Code Playgroud)