繁体   English   中英

如何在 OpenCV Python 中识别图像中的不同对象

[英]How to identify distinct objects in image in OpenCV Python

我正在尝试在 OpenCV 中识别图像中的单独对象。 到目前为止,我已经将图像打开到一个 NumPy 数组中并对其进行了阈值处理,因此它是二进制的。 这是它的样子:

原图

我正在尝试识别不同对象所在的 NumPy 数组索引,例如分割。 这是我想要实现的目标最终目标(我没有费心用不同的颜色为该图像中的每个对象着色,但您明白了)

本质上,我试图将每个被视为“对象”的像素簇标记为一个单独的类,并为每个类生成一个数组索引列表。 我曾尝试使用 OpenCV 的 connectedComponentsWithStats,但我不知道如何为该图像中每个对象的位置生成数组索引列表。 我怎样才能做到这一点?

您面临的是连接组件标签,因此您可以使用的最佳功能正是您提到的connectedComponentsWithStats

但是,它的使用在开始时可能会有些混乱。 在这里您可以找到一个工作示例。

import cv2
import numpy as np

# Load the image in grayscale
input_image = cv2.imread(r"satellite.png", cv2.IMREAD_GRAYSCALE)

# Threshold your image to make sure that is binary
thresh_type = cv2.THRESH_BINARY + cv2.THRESH_OTSU
_, binary_image = cv2.threshold(input_image, 0, 255, thresh_type)

# Perform connected component labeling
n_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(binary_image,
                                                                      connectivity=4)

# Create false color image
colors = np.random.randint(0, 255, size=(n_labels , 3), dtype=np.uint8)
colors[0] = [0, 0, 0]  # for cosmetic reason we want the background black
false_colors = colors[labels]

cv2.imshow('binary', binary_image)
cv2.imshow('false_colors', false_colors)
cv2.waitKey(0)

二进制图像:

二值图像

标记的图像(假彩色):

标记图像

centroids变量已经包含每个标记对象的质心 (x, y) 坐标。

false_colors_draw = false_colors.copy()
for centroid in centroids:
    cv2.drawMarker(false_colors_draw, (int(centroid[0]), int(centroid[1])),
                   color=(255, 255, 255), markerType=cv2.MARKER_CROSS)
cv2.imshow('false_colors_centroids', false_colors_draw)
cv2.waitKey(0)

质心:

质心图像

如您所见,它们非常多。 如果您只想保留较大的对象,您可以 i) 在开始时对二进制图像使用形态学操作或 ii) 使用已包含在stats的区域信息。

MIN_AREA = 50
false_colors_draw = false_colors.copy()
for i, centroid in enumerate(centroids[1:], start=1):
    area = stats[i, 4]
    if area > min_area:
        cv2.drawMarker(false_colors_draw, (int(centroid[0]), int(centroid[1])),
                       color=(255, 255, 255), markerType=cv2.MARKER_CROSS)

质心(按面积过滤):

质心图像过滤

使用cv2.findContourscv2.drawContours

在此处输入图片说明

编辑:代码

import cv2
import numpy as np
import random as rng

im = cv2.imread('YourImagePath\\test2.png')
gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray, 113, 255, 0)
contours, hierarchy = 
cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[-2:]
idx =0

for cnt in contours:
    idx += 1
    x,y,w,h = cv2.boundingRect(cnt)
    roi=im[y:y+h,x:x+w]
    color = (rng.randint(0, 256), rng.randint(0, 256), rng.randint(0, 256))
    #cv2.rectangle(im,(x,y),(x+w,y+h),color,2)
    cv2.drawContours(im,[cnt],0 ,color,-1)
cv2.imshow('img',im)
cv2.waitKey(0)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM