2012-03-13 17 views
12

Mục tiêu của tôi là theo dõi các bản vẽ có nhiều hình dạng riêng biệt trong chúng và chia các hình này thành các hình ảnh riêng lẻ. Nó có màu đen trắng. Tôi khá mới để NumPy, opencv & đồng - nhưng đây là suy nghĩ hiện tại của tôi:Nhận diện hình dạng với numpy/scipy (có thể là lưu vực)

  • quét cho pixel đen
  • điểm ảnh đen tìm thấy -> rừng đầu nguồn
  • tìm ranh giới lưu vực sông (như đường đa giác)
  • tiếp tục tìm kiếm, nhưng bỏ qua các điểm trong phạm vi ranh giới đã tìm thấy

tôi không giỏi các loại của sự vật, là có một cách tốt hơn?

Trước tiên tôi đã cố gắng để tìm ra hộp bounding hình chữ nhật của các kết quả đầu nguồn (điều này là nhiều hơn hoặc ít hơn một cắt dán các ví dụ):

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 

Bằng cách nào đó, khi tôi sử dụng các mảng ban đầu (a) sau đó argwhere dường như làm việc, nhưng sau khi lưu vực (res) nó chỉ xuất ra các mảng hoàn chỉnh một lần nữa.

Bước tiếp theo có thể là tìm đường đa giác xung quanh hình dạng, nhưng hộp giới hạn sẽ là tuyệt vời ngay bây giờ!

Vui lòng trợ giúp!

Trả lời

14

@Hooked đã trả lời hầu hết các câu hỏi của bạn, nhưng tôi đã ở giữa văn bản này lên khi anh trả lời, vì vậy tôi sẽ đăng nó trong hy vọng rằng nó vẫn hữu ích ...

Bạn đang cố gắng nhảy qua một vài vòng lặp quá nhiều. Bạn không cần watershed_ift.

Bạn sử dụng scipy.ndimage.label để phân biệt các đối tượng riêng biệt trong mảng boolean và scipy.ndimage.find_objects để tìm hộp giới hạn của từng đối tượng.

Hãy chia nhỏ mọi thứ một chút.

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

Hy vọng mà làm cho nó một chút rõ ràng làm thế nào để tìm thấy các hộp giới hạn của các đối tượng.

+0

Cảm ơn cả hai bạn rất nhiều vì câu trả lời của bạn, tôi nghĩ đây là điều đó. Chỉ có một câu hỏi mới của người mới nếu tôi có thể: Tôi không thể chỉ lưu khu vực của các ranh giới bị ràng buộc, bởi vì các hình dạng khác sẽ là 'nhìn trộm'. Vì vậy, kế hoạch của tôi là nhân diện tích hình ảnh bằng mảng nhãn đảo ngược (vì vậy mọi thứ bên ngoài hình dạng hiện tại sẽ trở thành màu đen) và sau đó lưu khu vực hình ảnh bằng ndimage. Bạn có thể chỉ cho tôi đúng hướng làm thế nào để làm điều này?Tôi biết, ngay sau khi tôi có thời gian tôi sẽ cẩn thận rtfm! – user978250

+1

Tôi nghĩ bạn chỉ muốn 'label == num' trong đó' num' là số của đối tượng trong 'label' (mảng được gắn nhãn). Các hoạt động như thế này được vector hóa trên các mảng có nhiều mảng, do đó, nó theo nghĩa đen là tuyên bố ở trên. Bạn sẽ nhận được một mảng boolean 'True' bên trong đối tượng" và 'False' bên ngoài. –

5

Sử dụng thư viện ndimage từ scipy. Hàm label đặt một thẻ duy nhất trên mỗi khối pixel nằm trong ngưỡng. Điều này xác định các cụm duy nhất (hình dạng). Bắt đầu với định nghĩa của bạn về 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

Các vấn đề liên quan