Я хотел бы удалить окружность (крайний периметр знака) этого знака каркаса колеса, кроме того, что находится внутри. Я думаю о функции 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:
Это правильная процедура заливки-расширения? Где это неправильно?
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()
и я, к сожалению, получаю это: