opencv - How can i delete largest contour in a skeleton image in python? -
i delete circumference (the outermost perimeter of sign) of wheel skeleton sign except what's inside. think function findcontours() , delete largest contour found
this input image:
skeletonized:
but unfortunately output image:
why not remain 2 crossed segments , segment made lot of dots
from __future__ import division import mahotas mh import pymorph pm import numpy np import os import math import cv2 skimage import io import scipy skimage import morphology complete_path = 'duplinuova/ruote 7/e (11).jpg' fork = mh.imread(complete_path) fork = fork[:,:,0]# extract 1 component, ex r #structuring elements disk7 = pm.sedisk(3)#size 7x7: 7=3+1+3 disk5 = pm.sedisk(2) #just simple thresholding 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 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 deleting little signs areacontours = list() calcarea = 0.0 unicocnt = 0.0 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()
update solution (and new question):
if make deep copy of skeletonized img after line of code: img = img.astype(np.uint8) #after skeletonization procedure
i can use find_contour copied image , apply draw_contour original image , that's all!
my questions are:
why find contour edit image , i'm forced use temporary image? why matplotlib show me right result , cv2 imshow don't (it show me black image)?
new part of code:
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()
update floodfile+dilate:
it correct floodfill-dilate procedure? its' wrong?
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()
and unfortunately obtain this:
another way might achieve desired result flood fill on skeletonized image. since outer boundary closed select pixels outside of object. simple dilation can applied expand filled region include outer ring. apply mask , remove pixels have been flood filled + dilation. leave center of wheel.
Comments
Post a Comment