【问题标题】:How can i delete largest contour in a skeleton image in python?如何在python中删除骨架图像中的最大轮廓?
【发布时间】:2013-04-27 04:24:13
【问题描述】:

我想删除这个轮骨架标志的圆周(标志的最外周),除了里面的东西。 我想了一个函数 findcontours() 并删除我找到的最大轮廓

这是输入图像:

骨架化:

但不幸的是,这是我的输出图像:

为什么它不只保留 2 个交叉的线段,而一个线段是由很多点组成的

from __future__ import division
import mahotas as mh
import pymorph as pm
import numpy as np

import os
import math

import cv2
from skimage import io
import scipy
from skimage import morphology

complete_path = 'DUPLInuova/ruote 7/e (11).jpg'

fork = mh.imread(complete_path)  
fork = fork[:,:,0]# extract one component, ex R 

#structuring elements
disk7 = pm.sedisk(3)#size 7x7: 7=3+1+3
disk5 = pm.sedisk(2)

#Just a simple thresholding with white background
bfork = fork < 150
bfork = mh.morph.dilate(bfork, disk7)

gray = cv2.imread(complete_path,0)
originale = gray
print("gray")
print(gray.shape)
cv2.imshow('graybin',gray)
cv2.waitKey()

ret,thresh = cv2.threshold(gray,127,255,cv2.THRESH_BINARY_INV) 
imgbnbin = thresh
print("shape imgbnbin")
print(imgbnbin.shape)
cv2.imshow('binaria',imgbnbin)
cv2.waitKey()
shape = list(gray.shape)
w = int( (shape[0]/100 )*5)
h = int((shape[1]/100)*5)
print(w)
print(h)
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(w,h)) #con 4,4 si vede tutta la stella e riconosce piccoli oggetti
from skimage.morphology import square

graydilate = np.array(imgbnbin, dtype=np.float64)
graydilate = morphology.binary_dilation(graydilate, square(w))
graydilate = morphology.binary_dilation(graydilate, square(w))

out = morphology.skeletonize(graydilate>0)
img = out.astype(float)
cv2.imshow('scikitimage',img)
cv2.waitKey()
img = img.astype(np.uint8)
cv2.imshow('scikitconvert',img)
cv2.waitKey()

contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
print(len(contours))

# calculating area for deleting little signs
Areacontours = list()
calcarea = 0.0
unicocnt = 0.0
for i in range (0, len(contours)):
    area = cv2.contourArea(contours[i])
    #print("area")
    print(area)
    if (area > 90 ): 
        if (calcarea<area):
            calcarea = area
            unicocnt = contours[i]

cnt = unicocnt
ara = cv2.contourArea(cnt)
print("cnt")
print(ara)

#delete largest contour
cv2.drawContours(img,[cnt],0,(0,255,0),1)
cv2.imshow('img del contour',img)
cv2.waitKey()

更新解决方案(和新问题):

如果我在这行代码之后制作了骨架化 img 的深层副本: img = img.astype(np.uint8) #骨架化程序后

我可以将 find_contour 与复制的图像一起使用,并将 draw_contour 应用于原始图像,仅此而已!

我的问题是:

为什么找到轮廓编辑我的图像而我不得不使用临时图像? 为什么 matplotlib 显示正确的结果而 cv2 imshow 不显示(它显示黑色图像)?

新部分代码:

import copy
imgcontour = copy.copy(img)

imgcnt = img
contours, hierarchy = cv2.findContours(imgcontour,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE )
print(len(contours))

cnt = contours[0]

cv2.drawContours(img,[cnt],0,(0,0,0),1)

cv2.imshow('imgcv2black',img)
cv2.waitKey()

plt.gray()
plt.subplot(121)
plt.imshow(img)
plt.show()

更新 FLOODFILE+DILATE:

floodfill-dilate 程序是否正确? 哪里错了?

a = np.ones((212,205), dtype=np.uint8)
#myMask = zeros(a.shape[0:2], dtype = uint8)

maskr = np.zeros(a.shape,np.uint8)
print(maskr.shape)
print(img[0])

cv2.floodFill(img,mask =maskr, seedPoint = (0,0), newVal = 1)
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3)) 
img = cv2.dilate(img, element)

cv2.imshow('flood',img)
cv2.waitKey()
plt.gray()
plt.subplot(121)
plt.imshow(img)
plt.show()

不幸的是,我得到了这个:

【问题讨论】:

    标签: python opencv image-processing contour scikit-image


    【解决方案1】:

    实现所需结果的另一种方法是在骨架化图像上进行泛光填充。由于外边界是封闭的,它将选择对象之外的所有像素。然后可以应用简单的膨胀来扩展填充区域以包括外环。将此作为蒙版应用,并删除任何已被洪水填充 + 膨胀的像素。这将只留下轮子的中心。

    【讨论】:

      【解决方案2】:

      一个非常简单的解决方案是标记图像中轮廓的组件。在这种情况下,您可以提取您直接感兴趣的轮廓。而且由于标签从拓扑外部开始,如果一个显示除第一个以外的所有轮廓标签,您应该得到结果。在轮廓已经闭合的情况下,不需要骨架!如果我们开始的轮廓很厚,也可以进一步使用细化来获得细轮廓。

      输入:我

      标记轮廓:L = bwlabel(~I);

      去除最大外轮廓:图,imshow(L>1)

      这必须可以在scikits 连接组件标签设置中复制。

      您还可以计算这些组件的大小并得到它们的长度(sum(sum(L==1)) 等等)

      【讨论】:

        【解决方案3】:

        您也可以使用圆形霍夫变换来尝试定位轮辋,然后从那里开始工作。

        【讨论】:

          猜你喜欢
          • 2016-09-25
          • 2020-09-23
          • 2017-04-01
          • 1970-01-01
          • 2016-04-27
          • 1970-01-01
          • 2020-01-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多