gpt4 book ai didi

python - 如何删除 python 中骨架图像中的最大轮廓?

转载 作者:太空宇宙 更新时间:2023-11-03 21:37:43 24 4
gpt4 key购买 nike

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

这是输入图像:

Original image

骨架化:

skeleton image

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

skeleton image without largest contour

为什么它不只保留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()

correct result in matplotlib

更新 FLOODFILE+扩张:

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()

不幸的是我得到了这个:

floodfil+dilate

最佳答案

另一种可以达到预期效果的方法是对骨架图像进行填充。由于外边界是封闭的,它将选择对象外部的所有像素。然后可以应用简单的扩张来扩展填充区域以包括外环。将其用作 mask 并移除任何已被填充 + 膨胀的像素。这将只留下轮子的中心。

关于python - 如何删除 python 中骨架图像中的最大轮廓?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16347499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com