opencvpython:语音气泡形状的闭合轮廓逼近

2024-05-14 22:22:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个像演讲泡泡的形状。我只想检测这个形状的椭圆,就像图中绿色环绕的那个。在

enter image description hereenter image description here

我试过用封闭的形态,但是气泡的某些部分也被移除了。我用的是一个矩阵为20,20的内核。形状变得更加矩形。也许我得把内核矩阵改成这样:

0 1 0
1 1 1
0 1 0

我也试着画一个凸壳,但也没有效果。内凸壳是不可能的。下面是我绘制凸面外壳的代码:

^{pr2}$

我用参数cv2.RETR_EXTERNALcv2.CHAIN_APPROX_NONE检索轮廓


Tags: 代码绘制矩阵外壳cv2内核气泡形态
1条回答
网友
1楼 · 发布于 2024-05-14 22:22:34

这是我能得到的最好的: Ballon ellipse

这不是最聪明的办法。我在这里所做的实际上很简单,尽管代码很冗长。在

首先,我得到了灰色图像,并添加了大量的模糊,然后用同样的方法,应用阈值并找到轮廓。然后取最大的轮廓,找到一个椭圆,这个椭圆与这个轮廓相吻合fitEllipse。这是全部在getEllipse函数中。在

在第一轮中,椭圆将倾斜,因为尾巴挡住了去路。所以,我用这个不太好的椭圆来处理原始图像,然后再试一次。在

函数grayelipse通过椭圆过滤图像。所以,我用椭圆从第一个尝试得到处理原始图像,并突出显示第一个椭圆内的点。我用这个图像作为第二轮的输入。在

通过重复这个过程,我第二次得到的最后一个椭圆的倾斜程度要小得多。在

代码如下:

import cv2
import numpy as np


def getEllipse(imgray):


    ret, thresh = cv2.threshold(imgray, 20, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
    _, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

    maxArea = 0
    best = None
    for contour in contours:
        area = cv2.contourArea(contour)
        if area > maxArea :
            maxArea = area
            best = contour

    ellipse = cv2.fitEllipse(best)
    el = np.zeros(imgray.shape)
    cv2.ellipse(el, ellipse,(255,255,255),-1)

    return el

def grayEllipse(el, img):
    el = np.dstack((el,el,el))
    el = el*img
    el = el/(255)
    el = el.astype('uint8')
    imgray = cv2.cvtColor(el, cv2.COLOR_BGR2LAB)[...,0]
    return imgray


image = cv2.imread("./baloon.png", cv2.IMREAD_COLOR)
img = image.copy()
imgray = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)[...,0]
imgray = cv2.GaussianBlur(imgray, (79,79), 0)
el = getEllipse(imgray)
imgray = grayEllipse(el, img.copy())
imgray = cv2.GaussianBlur(imgray, (11,11), 0)
el = getEllipse(imgray)
imgray = grayEllipse(el, img.copy())

ret, thresh = cv2.threshold(imgray, 20, 255, cv2.THRESH_BINARY|cv2.THRESH_OTSU)
_, contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)

maxArea = 0
best = None
for contour in contours:
    area = cv2.contourArea(contour)
    if area > maxArea :
        maxArea = area
        best = contour

ellipse = cv2.fitEllipse(best)
cv2.ellipse(image, ellipse, (0,255,0),3)

while True:
  cv2.imshow("result", image)
  k = cv2.waitKey(30) & 0xff
  if k == 27:
      break

相关问题 更多 >

    热门问题