2011-01-26 28 views
16

Tôi đang xử lý các mảng được tạo thông qua numpy.array() và tôi cần vẽ các điểm trên canvas mô phỏng hình ảnh. Vì có rất nhiều giá trị bằng không quanh phần trung tâm của mảng chứa dữ liệu có ý nghĩa, tôi muốn "cắt" mảng, xóa các cột chỉ chứa số không và các hàng chỉ chứa số không. Vì vậy, tôi muốn biết một số chức năng cục bộ hoặc thậm chí một đoạn mã để "cắt" hoặc tìm một "hộp giới hạn" để chỉ cắt phần chứa dữ liệu của mảng đó.Có chức năng "bounding box" (slice với giá trị khác 0) cho một ndarray trong NumPy không?

(. Vì nó là một câu hỏi khái niệm, tôi không đặt bất kỳ mã, xin lỗi nếu tôi nên, tôi rất tươi để niêm yết tại SO)

Thanks for reading

+0

http://stackoverflow.com/questions/31400769/bounding-box-of-numpy-array xem hàm bbox2 ... MUCH nhanh hơn, nếu có nhiều hàng/cột được điền đầy đủ số không và chỉ một lượng nhỏ dữ liệu nhóm. – Benjamin

Trả lời

6

Đoạn code dưới đây, từ this answer chạy nhanh nhất trong các thử nghiệm của tôi:

def bbox2(img): 
    rows = np.any(img, axis=1) 
    cols = np.any(img, axis=0) 
    ymin, ymax = np.where(rows)[0][[0, -1]] 
    xmin, xmax = np.where(cols)[0][[0, -1]] 
    return img[ymin:ymax+1, xmin:xmax+1] 

Câu trả lời được chấp nhận sử dụng argwhere làm việc nhưng chạy chậm hơn. Tôi đoán là, bởi vì argwhere phân bổ một mảng đầu ra khổng lồ của các chỉ mục. Tôi đã thử nghiệm trên một mảng 2D lớn (một hình ảnh 1024 x 1024, với khoảng 50x100 vùng không đông).

+0

Tôi tìm thấy cách trả lời này nhiều hơn nữa! Cảm ơn! – heltonbiker

+0

Thận trọng, mã này có thể tạo ra lỗi trong trường hợp cạnh của một hình ảnh hoàn toàn màu đen. Bạn phải xác minh rằng cả hai cuộc gọi 'np.where()' đều trả về một mảng trống. – Delgan

0

Cái gì như:

empty_cols = sp.all(array == 0, axis=0) 
empty_rows = sp.all(array == 0, axis=1) 

Mảng kết quả sẽ là mảng boolian 1D. Lặp lại chúng từ cả hai đầu để tìm 'bounding box'.

+1

looping over arrump mảng nên tránh – Paul

+0

Vòng lặp chỉ là 1D, do đó, để n, không n^2. Không phải là vấn đề lớn. – kiyo

+1

Bạn đúng về thứ tự và thậm chí bạn không cần một vòng lặp trên toàn bộ chiều rộng mảng, nhưng vòng python chứa tất cả các loại bước bổ sung như kiểm tra kiểu. Trong ví dụ 1D này: http://www.scipy.org/Getting_Started#head-9aed725bd569d40f625240b2b6ec710550ff14b9 Vòng python chạy chậm hơn 25X để hoàn thành nhiệm vụ tương tự! Nếu không biết kích thước hoặc số lượng của hình ảnh hoặc ứng dụng của thuật toán (tầm nhìn máy tính?), Tôi không thể nói một thỏa thuận lớn như thế nào là loại tăng tốc. – Paul

20

này nên làm điều đó:

from numpy import array, argwhere 

A = array([[0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 1, 0, 0, 0, 0], 
      [0, 0, 1, 1, 0, 0, 0], 
      [0, 0, 0, 0, 1, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0], 
      [0, 0, 0, 0, 0, 0, 0]]) 

B = argwhere(A) 
(ystart, xstart), (ystop, xstop) = B.min(0), B.max(0) + 1 
Atrim = A[ystart:ystop, xstart:xstop] 
+1

Tuyệt vời! Chỉ cần trên một ghi chú dễ đọc, bạn có thể làm '(ystart, xstart), (ystop, xstop) = B.min (0), B.max (0) + 1' và sau đó chỉ cần chỉ mục' A' với 'Atrim = a [ystart: ystop, xstart: xstop] '. Tất nhiên, nó hoàn toàn tương đương, nhưng tôi thấy nó dễ đọc hơn, dù sao đi chăng nữa. –

+0

Xong. Cảm ơn, Joe. – Paul

+0

Điều này là tốt, ví dụ bạn sử dụng là chính xác mảng điển hình tôi sẽ sử dụng (chỉ lớn hơn). Tôi không biết chức năng ở đâu, sẽ làm bài tập về nhà ngay bây giờ. Cảm ơn! – heltonbiker

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