2013-05-02 1 views
1

안에있는 것을 제외하고이 휠 뼈대 기호의 둘레 (기호의 가장 바깥 둘레)를 삭제하고 싶습니다. 나는 함수 findcontours (생각) 그리고 난이 입력 이미지어떻게 파이썬에서 스켈레톤 이미지의 가장 큰 윤곽선을 삭제할 수 있습니까?

을 발견 가장 큰 윤곽 삭제 :

Original image

골격 화 : 불행하게도이

skeleton image

하지만를 내 출력 이미지 :

,

는이 세그먼트를 건너

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

UPDATE 해결책 (새로운 질문)

세그먼트는 점을 많이 의해 이루어집니다 만 남아 있지 않는 이유 :

내가 할 경우 다음 코드 줄 이후의 골격화 된 img의 전체 복사본 : img = img.astype (np.uint8) # 골격화 절차 이후

복사 된 이미지와 함께 find_contour를 사용할 수 있으며 원본 이미지에 draw_contour를 적용하면 그게 전부입니다!

왜 윤곽 편집 내 이미지를 발견하고 난 임시 이미지를 사용하도록 강요하고 있습니다 :

내 질문은? matplotlib가 올바른 결과를 표시하고 cv2가 표시되지 않는 이유는 무엇입니까 (검은 색 이미지를 보여 줍니까?). 코드의

새로운 부분 :

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

UPDATE FLOODFILE + 팽창 :

그것은 플러드 필 - 팽창 절차 맞습니까? 어디에 '잘못 됐니?

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

답변

1

또 다른 방법은 홍수가 골격 화 이미지를 입력하는 것입니다. 외부 경계가 닫혀 있기 때문에 객체 외부의 모든 픽셀을 선택합니다. 그런 다음 간단한 확장을 적용하여 채워진 영역을 확장하여 바깥 쪽 링을 포함시킵니다. 이것을 마스크로 적용하고 홍수가 채워지고 팽창 된 픽셀을 제거합니다. 이렇게하면 휠의 중앙 부분 만 남게됩니다.

0

원형 호프 변환을 사용하여 휠 림을 찾은 다음 거기에서 작업 할 수도 있습니다.

1

매우 간단한 해결책은 이미지의 윤곽선 구성 요소에 라벨을 지정하는 것입니다.이 경우 직접 관심있는 등고선을 추출 할 수 있습니다. 그리고 토폴로지 외부에서 라벨이 시작되기 때문에 첫 번째 라벨 이외의 모든 등고선 라벨을 표시하면 결과가 나타납니다. 윤곽선이 이미 닫힌 경우 골격은 필요하지 않습니다! 또한 시작 부분이 두꺼우면 얇은 윤곽을 얻기 위해 더 얇아지는 방법을 사용할 수 있습니다.

입력 : I

enter image description here

레이블 윤곽 : L = bwlabel (~ I); 그림 imshow (L> 1)

enter image description here

scikits 연결 컴포넌트 라벨 설정에서 복제 할 수 있어야한다 : 최대 외형 분리

enter image description here

.

또한 이러한 구성 요소의 크기를 계산하고 길이를 얻을 수 있습니다 (sum (sum (L == 1))