我想删除这个轮骨架标志的圆周(标志的最外周),除了里面的东西。我考虑一个函数 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) #after 骨架化过程
我可以将 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()
更新洪水文件+扩张:
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()
不幸的是,我得到了这个: