python - 仅获取图像中的外部轮廓
问题描述
我有这段代码,它在我的图像中绘制轮廓,但我只需要外部轮廓:
import cv2
import numpy as np
camino= "C:/Users/Usuario/Documents/Deteccion de Objetos/123.jpg"
img = cv2.imread("C:/Users/Usuario/Documents/Deteccion de Objetos/123.jpg")
grises= cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
bordes= cv2.Canny(grises, 100, 250)
ctns = cv2.findContours(bordes, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
ctns = ctns[0] if len(ctns)==2 else ctns[1]
for c in ctns:
cv2.drawContours(img,[c], -1,(0,0,255),2)
print ('Numero de contornos es ', len(ctns))
texto= 'Contornos encontrados ' + str(len(ctns))
cv2.putText(img, texto, (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.7,
(255, 0, 0), 1)
cv2.imshow('Bordes', bordes)
cv2.imshow('Imagen', img)
cv2.waitKey(0)
cv2.destroyAllWindows().
在这种情况下,我只需要为每个实体检测 10 个轮廓 1,但它检测到 450 个轮廓。
解决方案
这是一种使用阈值处理+形态学运算+轮廓过滤的方法
首先我们转换为灰度,然后转换为二值图像的 Otsu 阈值(左),然后使用轮廓区域过滤去除虚线(右)
从这里我们执行 morph close 以删除文本然后反转图像(左)。我们找到轮廓并将所有小于阈值的轮廓填充为黑色(右)
接下来我们再次反转并使用大矩形内核执行变形打开以去除小边缘和尖峰
最后我们找到轮廓来得到我们的结果
import cv2
image = cv2.imread('1.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (5,5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Remove dotted lines
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 5000:
cv2.drawContours(thresh, [c], -1, (0,0,0), -1)
# Fill contours
close_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
close = 255 - cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, close_kernel, iterations=6)
cnts = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
area = cv2.contourArea(c)
if area < 15000:
cv2.drawContours(close, [c], -1, (0,0,0), -1)
# Smooth contours
close = 255 - close
open_kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (20,20))
opening = cv2.morphologyEx(close, cv2.MORPH_OPEN, open_kernel, iterations=3)
# Find contours and draw result
cnts = cv2.findContours(opening, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
cv2.drawContours(image, [c], -1, (36,255,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('opening', opening)
cv2.imshow('image', image)
cv2.waitKey()
推荐阅读
- c# - 如何解决 .net 标准中的命名空间“System.Configuration”错误中不存在类型或命名空间名称“ConfigurationManager”?
- python - 我想找到一个特定的数据(python、pandas、seaborn)
- reactjs - 对象数组映射无效反应
- javascript - HTML 和 CSS 插入符号下拉菜单
- azure - Azure Search Graph Search-AzGraph 与 Azure Resource Graph Explorer 的意外搜索结果
- javascript - 从 tbody puppeteer 页面评估获取 td dataname href
- swift - 到达整点后将日期重置为下一小时
- algorithm - 如何在 r 轮中为 n 人解决纸牌游戏中的组合(仅一次遭遇)
- python - 创建一个函数来打印指数而不使用**
- python - 在 python 中,有没有办法在您创建变量时自动记录信息?