2012-03-13 10 views
12

मेरा लक्ष्य उन चित्रों का पता लगाने के लिए है जिनमें उनमें बहुत से अलग आकार हैं और इन आकारों को अलग-अलग छवियों में विभाजित करना है। यह सफेद पर काला है। मैं काफी numpy, opencv & सह करने के लिए नए हूँ - लेकिन यहाँ मेरे वर्तमान सोचा है:numpy/scipy (शायद वाटरशेड) के साथ आकार पहचान

  • काला पिक्सल के लिए स्कैन
  • काला पिक्सेल पाया -> वाटरशेड
  • जल सीमा लगता है (बहुभुज पथ के रूप में)
  • खोज जारी है, लेकिन पहले से ही पाया सीमाओं

मैं चीजों को इस तरह से बहुत अच्छा नहीं कर रहा हूँ के भीतर अंक की अनदेखी, वहाँ एक बेहतर तरीका है?

सबसे पहले मैं वाटरशेड परिणामों के आयताकार सीमांकन बॉक्स लगाने के लिए (यह कम या ज्यादा उदाहरण के एक महाविद्यालय है) की कोशिश की:

from numpy import * 
import numpy as np 
from scipy import ndimage 

np.set_printoptions(threshold=np.nan) 

a = np.zeros((512, 512)).astype(np.uint8) #unsigned integer type needed by watershed 
y, x = np.ogrid[0:512, 0:512] 
m1 = ((y-200)**2 + (x-100)**2 < 30**2) 
m2 = ((y-350)**2 + (x-400)**2 < 20**2) 
m3 = ((y-260)**2 + (x-200)**2 < 20**2) 
a[m1+m2+m3]=1 

markers = np.zeros_like(a).astype(int16) 
markers[0, 0] = 1 
markers[200, 100] = 2 
markers[350, 400] = 3 
markers[260, 200] = 4 

res = ndimage.watershed_ift(a.astype(uint8), markers) 
unique(res) 

B = argwhere(res.astype(uint8)) 
(ystart, xstart), (ystop, xstop) = B.min(0), B.max(0) + 1 
tr = a[ystart:ystop, xstart:xstop] 

print tr 

किसी तरह, जब मैं मूल सरणी का प्रयोग (क) तो तर्क कहां काम करता है, लेकिन वाटरशेड (res) के बाद यह फिर से पूरी सरणी आउटपुट करता है।

अगला चरण आकार के चारों ओर बहुभुज पथ खोजने के लिए हो सकता है, लेकिन बाउंडिंग बॉक्स अब के लिए बहुत अच्छा होगा!

कृपया मदद करें!

उत्तर

14

@Hooked पहले से ही अपने प्रश्न का सबसे उत्तर दिया है, लेकिन मैं यह लिख जब वह जवाब के बीच में था, तो मैं इसे पोस्ट करेंगे आशा है कि यह अभी भी उपयोगी है ...

आप कुछ बहुत सारे हुप्स के माध्यम से कूदने की कोशिश कर रहे हैं। आपको watershed_ift की आवश्यकता नहीं है।

प्रत्येक ऑब्जेक्ट के बाउंडिंग बॉक्स को खोजने के लिए आप एक बूलियन सरणी में अलग ऑब्जेक्ट्स को अलग करने और scipy.ndimage.find_objects का उपयोग करने के लिए scipy.ndimage.label का उपयोग करते हैं।

चलिए चीजों को थोड़ा सा तोड़ दें।

import numpy as np 
from scipy import ndimage 
import matplotlib.pyplot as plt 

def draw_circle(grid, x0, y0, radius): 
    ny, nx = grid.shape 
    y, x = np.ogrid[:ny, :nx] 
    dist = np.hypot(x - x0, y - y0) 
    grid[dist < radius] = True 
    return grid 

# Generate 3 circles... 
a = np.zeros((512, 512), dtype=np.bool) 
draw_circle(a, 100, 200, 30) 
draw_circle(a, 400, 350, 20) 
draw_circle(a, 200, 260, 20) 

# Label the objects in the array. 
labels, numobjects = ndimage.label(a) 

# Now find their bounding boxes (This will be a tuple of slice objects) 
# You can use each one to directly index your data. 
# E.g. a[slices[0]] gives you the original data within the bounding box of the 
# first object. 
slices = ndimage.find_objects(labels) 

#-- Plotting... ------------------------------------- 
fig, ax = plt.subplots() 
ax.imshow(a) 
ax.set_title('Original Data') 

fig, ax = plt.subplots() 
ax.imshow(labels) 
ax.set_title('Labeled objects') 

fig, axes = plt.subplots(ncols=numobjects) 
for ax, sli in zip(axes.flat, slices): 
    ax.imshow(labels[sli], vmin=0, vmax=numobjects) 
    tpl = 'BBox:\nymin:{0.start}, ymax:{0.stop}\nxmin:{1.start}, xmax:{1.stop}' 
    ax.set_title(tpl.format(*sli)) 
fig.suptitle('Individual Objects') 

plt.show() 

enter image description here enter image description here enter image description here

उम्मीद है कि यह थोड़ा साफ वस्तुओं के सीमांकन बॉक्स लगाने के लिए कैसे है कि बनाता है।

+0

आप दोनों को अपने उत्तरों के लिए बहुत बहुत धन्यवाद, मुझे लगता है कि यह है। केवल एक नौसिखिया संख्यात्मक सवाल अगर मैं कर सकता हूं: मैं केवल बाध्यकारी संप्रदायों के क्षेत्र को नहीं बचा सकता, क्योंकि अन्य आकार 'झुकने' में होंगे। तो मेरी योजना उलटा लेबल सरणी द्वारा छवि क्षेत्र को गुणा करना है (इसलिए वर्तमान आकार के बाहर सब कुछ काला हो जाता है) और फिर छवि क्षेत्र को एनडीमेज से बचाएं। क्या आप मुझे सही दिशा में इंगित कर सकते हैं कि यह कैसे करें?मुझे पता है, जैसे ही मेरे पास समय होगा मैं सावधानीपूर्वक rtfm होगा! – user978250

+1

मुझे लगता है कि आप बस 'लेबल == num' चाहते हैं जहां 'num'' लेबल' (लेबल वाली सरणी) में ऑब्जेक्ट की संख्या है। इस तरह के संचालन numpy arrays पर vectorized हैं, तो यह सचमुच उपरोक्त बयान है। आपको "ऑब्जेक्ट" और 'गलत' के अंदर 'ट्रू' की एक बूलियन सरणी मिल जाएगी। –

5

ndimage लाइब्रेरी का उपयोग करें। फ़ंक्शन label एक थ्रेसहोल्ड के भीतर वाले पिक्सल के प्रत्येक ब्लॉक पर एक अनूठा टैग रखता है। यह अद्वितीय क्लस्टर (आकार) की पहचान करता है। a की अपनी परिभाषा के साथ शुरू:

from scipy import ndimage 

image_threshold = .5 
label_array, n_features = ndimage.label(a>image_threshold) 

# Plot the resulting shapes 
import pylab as plt 
plt.subplot(121) 
plt.imshow(a) 
plt.subplot(122) 
plt.imshow(label_array) 
plt.show() 

enter image description here

संबंधित मुद्दे