ben bir çözüm buldum düşünüyorum: Eğer bir deneyin isterseniz
Bu eksenler olmadan ilk görüntüdür. Zamanım tükendiğinden beri biraz uzun, ama belki yardımcı olur. Sadece bu sorun için kodlanmıştım, ancak birçok görüntü için genelleştirmesi kolay olmalı. İlk
Bazı adlandırma kurallarına:
- I fon ışıması çevrelediği kompakt bölgeler olarak "ilk seviye bölgeleri" tanımlar. Bu birinci seviye bölgeler farklı alt bölgelerden oluşabilir. Birden fazla alt bölgeden oluşan birinci düzey bölgeye kritik bölge adı verilir.
Temel düşüncem kritik bölgelerin parçası olan iki alt bölgedeki konturların uzunluklarını karşılaştırmaktır. Ancak, Ben onların tam kontür uzunluğunu karşılaştırmak değil, sadece arka plan yakın olan segment. Arka tarafa yakın olan kısa kontur segmenti olan bir delik olarak kabul edilir.
İlk olarak sonuç görüntüleriyle başlayacağım.
biz bahsediyoruz yukarıdaki adlandırma kurallarına vizualizing şeyin Bazı bakış: kritik bölgenin

iki alt bölgeler. Arka plana yakın olan bölgelerin her birinin iki kenarlık bölümü farklı renklerde (çok ince, mavi ve koyu kırmızı, ancak görünür) işaretlenmiştir. Bu segmentler ("ince" alanlar hatalara neden) elbette mükemmel değil, ama yeterli uzunluğunu karşılaştırmak için:

nihai sonuç. "Kapalı" deliğe sahip olmak istediğinizde bana bildirin, sadece orijinal siyah konturları arka plan yerine bölgelere atamanız gerekir ([DÜZENLE] Sınırları atayan üç işaretli kod satırı dahil ettim siz istediniz bölgelerde) için:

Kod burada takılır. Oldukça sağlam ve açık bir şekilde OpenCV kontur fonksiyonunu kullandım ve bazı maskeleme teknikleri.Kod, görselleştirilmeleri nedeniyle okunaklı, okunaklılığı nedeniyle özür diler, ancak bu soruna iki çizgi çözümü görünmemektedir.
Bazı son sözler: İlk olarak, döngülerden kaçınan ve arka plana yakın iki kontur parçasını belirlemek için set.intersection kullanılmasına izin veren nokta kümelerini kullanarak konturları eşleştirmeyi denedim, ancak siyah çizgilerinizden oldukça kalın, kontürler birbiriyle uyuşmuyor. Konturların iskeletlenmesini denedim, fakat bu başka bir solucan konservesi açmıştı, bu yüzden kontur noktaları arasında bir döngü ve hesaplama mesafesi yapan bir döküm yaklaşımıyla çalıştım. Bu kısmı yapmanın daha güzel bir yolu olabilir, ama işe yarıyor.
Ayrıca Shapely modülünü kullanmayı düşündüm, ondan bazı avantajlar elde etmenin yolları olabilir, ama bulamadım, bu yüzden tekrar düşürdüm.
import numpy as np
import scipy.ndimage as ndimage
from matplotlib import pyplot as plt
import cv2
img= ndimage.imread('image.png')
# Label digfferentz original regions
labels, n_regions = ndimage.label(img)
print "Original number of regions found: ", n_regions
# count the number of pixels in each region
ulabels, sizes = np.unique(labels, return_counts=True)
print sizes
# Delete all regions with size < 2 and relabel
mask_size = sizes < 2
remove_pixel = mask_size[labels]
labels[remove_pixel] = 0
labels, n_regions = ndimage.label(labels) #,s)
print "Number of regions found (region size >1): ", n_regions
# count the number of pixels in each region
ulabels, sizes = np.unique(labels, return_counts=True)
print ulabels
print sizes
# Determine large "first level" regions
first_level_regions=np.where(labels ==1, 0, 1)
labeled_first_level_regions, n_fl_regions = ndimage.label(first_level_regions)
print "Number of first level regions found: ", n_fl_regions
# Plot regions and first level regions
fig = plt.figure()
a=fig.add_subplot(2,3,1)
a.set_title('All regions')
plt.imshow(labels, cmap='Paired', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([]), plt.colorbar()
a=fig.add_subplot(2,3,2)
a.set_title('First level regions')
plt.imshow(labeled_first_level_regions, cmap='Paired', vmin=0, vmax=n_fl_regions)
plt.xticks([]), plt.yticks([]), plt.colorbar()
for region_label in range(1,n_fl_regions):
mask= labeled_first_level_regions!=region_label
result = np.copy(labels)
result[mask]=0
subregions = np.unique(result).tolist()[1:]
print region_label, ": ", subregions
if len(subregions) >1:
print " Element 4 is a critical element: ", region_label
print " Subregions: ", subregions
#Critical first level region
crit_first_level_region=np.ones(labels.shape)
crit_first_level_region[mask]=0
a=fig.add_subplot(2,3,4)
a.set_title('Crit. first level region')
plt.imshow(crit_first_level_region, cmap='Paired', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([])
#Critical Region Contour
im = np.array(crit_first_level_region * 255, dtype = np.uint8)
_, contours0, hierarchy = cv2.findContours(im.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
crit_reg_contour = [contours0[0].flatten().tolist()[i:i+2] for i in range(0, len(contours0[0].flatten().tolist()), 2)]
print crit_reg_contour
print len(crit_reg_contour)
#First Subregion
mask2= labels!=subregions[1]
first_subreg=np.ones(labels.shape)
first_subreg[mask2]=0
a=fig.add_subplot(2,3,5)
a.set_title('First subregion: '+str(subregions[0]))
plt.imshow(first_subreg, cmap='Paired', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([])
#First Subregion Contour
im = np.array(first_subreg * 255, dtype = np.uint8)
_, contours0, hierarchy = cv2.findContours(im.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
first_sub_contour = [contours0[0].flatten().tolist()[i:i+2] for i in range(0, len(contours0[0].flatten().tolist()), 2)]
print first_sub_contour
print len(first_sub_contour)
#Second Subregion
mask3= labels!=subregions[0]
second_subreg=np.ones(labels.shape)
second_subreg[mask3]=0
a=fig.add_subplot(2,3,6)
a.set_title('Second subregion: '+str(subregions[1]))
plt.imshow(second_subreg, cmap='Paired', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([])
#Second Subregion Contour
im = np.array(second_subreg * 255, dtype = np.uint8)
_, contours0, hierarchy = cv2.findContours(im.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
second_sub_contour = [contours0[0].flatten().tolist()[i:i+2] for i in range(0, len(contours0[0].flatten().tolist()), 2)]
print second_sub_contour
print len(second_sub_contour)
maxdist=6
print "Points in first subregion close to first level contour:"
close_1=[]
for p1 in first_sub_contour:
for p2 in crit_reg_contour:
if (abs(p1[0]-p2[0])+abs(p1[1]-p2[1]))<maxdist:
close_1.append(p1)
break
print close_1
print len(close_1)
print "Points in second subregion close to first level contour:"
close_2=[]
for p1 in second_sub_contour:
for p2 in crit_reg_contour:
if (abs(p1[0]-p2[0])+abs(p1[1]-p2[1]))<maxdist:
close_2.append(p1)
break
print close_2
print len(close_2)
for p in close_1:
result[p[1],p[0]]=1
for p in close_2:
result[p[1],p[0]]=2
if len(close_1)>len(close_2):
print "first subregion is considered a hole:", subregions[0]
hole=subregions[0]
else:
print "second subregion is considered a hole:", subregions[1]
hole=subregions[1]
#Plot Critical region with subregions
a=fig.add_subplot(2,3,3)
a.set_title('Critical first level region with subregions')
plt.imshow(result, cmap='Paired', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([])
result2=result.copy()
#Plot result
fig2 = plt.figure()
a=fig2.add_subplot(1,1,1)
a.set_title('Critical first level region with subregions and bordering contour segments')
plt.imshow(result2, cmap='flag', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([])
#Plot result
mask_hole=np.where(labels ==hole, True, False)
labels[mask_hole]=1
labels=np.where(labels > 1, 2, 1)
# [Edit] Next two lines include black borders into final result
mask_borders=np.where(img ==0, True, False)
labels[mask_borders]=2
fig3 = plt.figure()
a=fig3.add_subplot(1,1,1)
a.set_title('Final result')
plt.imshow(labels, cmap='flag', vmin=0, vmax=n_regions)
plt.xticks([]), plt.yticks([])
plt.show()
Güzel sorun. Burada açıklandığı gibi OpenCV'den kontur hiyerarşisi ile çözebileceğinizi düşündünüz. Http://docs.opencv.org/3.1.0/d9/d8b/tutorial_py_contours_hierarchy.html#gsc.tab=0 ama bu kritik kontur olduğundan bu işe yaramaz. gerçek çocuk yok. Bunun, örnek dosyayı kullanarak çalışmadığını hızlıca görebilirsiniz. Https://github.com/Itseez/opencv/blob/master/samples/python/contours.py – tfv
Teşekkürler, @tfv! Olumsuz sonuç da bir sonuçtur ... – Phlya
Verdiğiniz resmin, aradığınız kararı vermesine izin vermediğini söyleyebilirim. Bir sınır var (eğer algoritma sizin istediğinizi alması bekleniyorsa), bir kesişme noktasını geçtikten sonra bir diğerini geçtiğinizde, hala bir deliğin içindeydiniz. normal durumlar. – roadrunner66