6

=== SOLVED ===Nhận dạng đối tượng đơn giản

Cảm ơn đề xuất và nhận xét của bạn. Bằng cách làm việc trên các thuật toán flood_fill được đưa ra trong Beginning Python Visualization cuốn sách (Chương 9 - Xử lý hình ảnh) Tôi đã thực hiện những gì tôi đã muốn. Tôi có thể đếm các đối tượng, có được hình chữ nhật kèm theo cho mỗi đối tượng (do đó chiều cao và chiều rộng), và cuối cùng có thể xây dựng mảng NumPy hoặc ma trận cho mỗi người trong số họ.

Mặc dù đó không phải là cách tiếp cận tối ưu hóa nhưng nó thực hiện những gì tôi muốn. Mã nguồn (lab2.py) và tệp png (lab2-particles.png) mà tôi sử dụng đã được đặt dưới http://code.google.com/p/ccnworks/source/browse/#svn/trunk/AtSc450.

Bạn cần cài đặt NumPy và PIL và matplotlib để xem biểu đồ. Cốt lõi của mã nằm trong hàm objfind trong đó hành động tìm kiếm đối tượng đệ quy chính xảy ra.

Một cập nhật thêm:

scipy của ndimage.label() thực hiện chính xác những gì tôi muốn, quá.

Cheers cho David-Warde FarleyZachary Pincus từ NumPy và scipy gửi thư-danh sách để chỉ quyền này vào mắt tôi :)

=========== ==

Xin chào,

tôi có một hình ảnh có chứa bóng tối của các hạt băng đo bằng một máy quang phổ hạt. Tôi muốn có thể xác định từng đối tượng, để sau này tôi có thể phân loại và sử dụng chúng trong các tính toán của mình.

Về bản chất, những gì tôi sẵn sàng làm là chỉ cần thực hiện một công cụ chọn mờ mà tôi có thể chỉ cần chọn từng thực thể.

Tôi có thể dễ dàng giải quyết vấn đề này như thế nào? (Tốt hơn là sử dụng Python)

Cảm ơn.

LƯU Ý: Trong câu hỏi của tôi, tôi đang đề cập đến từng pixel được kết nối cụ thể dưới dạng đối tượng hoặc đối tượng. Ý định của tôi để giải nén chúng và tạo ra các biểu diễn mảng NumPy như hình dưới đây. (Ở đây tôi đang sử dụng đối tượng trên cùng bên trái, nếu một pixel tồn tại sử dụng 1 nếu không sử dụng 0. Hình dạng của đối tượng này là 3 bởi 3 tương ứng với chiều cao 3 pixel chiều rộng 3 pixel. , dưới sự giả định về việc bán kính hình cầu và tương đương của họ là (chiều cao + chiều rộng)/2, và sau đó một số vụn --from pixel kích thước thực tế và tính toán khối lượng sẽ theo)

import numpy as np 

np.array([[1,1,1], [1,1,1], [0,0,1]]) 

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

đây là một phần từ hình ảnh mà tôi sẽ sử dụng.

screenshot http://img43.imageshack.us/img43/2327/particles.png

+5

Nhận dạng đối tượng đơn giản có vẻ như mâu thuẫn với tôi. – Joren

+0

Bạn sẽ đề xuất điều gì khác? –

+3

Vui lòng không nói "đã giải quyết" trong câu hỏi của bạn. Hoặc là chấp nhận câu trả lời hay nhất hoặc trả lời câu hỏi của bạn và chấp nhận câu hỏi đó. – Soviut

Trả lời

2

OpenCV có một giao diện Python mà bạn có thể thấy hữu ích.

+0

Tìm thấy điều này: http://opencv.willowgarage.com/documentation/python/pattern_recognition.html Tuy nhiên hơi khó hiểu với tôi và ví dụ không hữu ích lắm. –

5
  1. Quét mọi hình vuông (ví dụ:từ phía trên bên trái, từ trái sang phải, từ trên xuống dưới)

  2. Khi bạn nhấn một hình vuông màu xanh sau đó:

    a. Ghi lại hình vuông này làm vị trí của đối tượng mới

    b. Tìm tất cả các ô vuông khác tiếp giáp xanh (ví dụ như bằng cách nhìn vào những người hàng xóm của hình vuông này, và những người hàng xóm của những người hàng xóm, vv) và đánh dấu chúng là một phần của cùng một đối tượng

  3. Tiếp tục để quét

  4. Khi bạn tìm thấy một hình vuông màu xanh lam khác, hãy kiểm tra xem nó có phải là một phần của một đối tượng đã biết trước khi chuyển sang bước 2 hay không; cách khác trong bước 2b, xóa bất kỳ vuông sau khi bạn đã kết hợp nó với một đối tượng

+0

Tôi đã suy nghĩ để thực hiện một cái gì đó tương tự như những gì bạn đã đề cập ở đây. Cảm ơn bạn đã đặt ra rõ ràng hơn tôi :) –

+0

Với một số trợ giúp tôi đã viết một triển khai thực hiện flood_fill đơn giản và có thể đếm số đối tượng (bóng hạt băng) trên hình ảnh đã cho. Và, có nó bao gồm đệ quy như tôi mong đợi. Bây giờ tôi muốn để có thể xây dựng các mảng numpy đơn giản đại diện cho từng đối tượng. (như được chứng minh thêm về câu hỏi của tôi) Cuối cùng, tôi đang nghĩ đến việc gắn thêm tất cả các mảng này vào một mảng, sau này tôi có thể lặp lại và lấy hình dạng của chúng. Hình dạng là quan trọng bởi vì tôi sẽ sử dụng chúng cho chiều cao và chiều rộng của các đối tượng hạt băng. –

3

Nhìn vào hình ảnh mà bạn cung cấp, tất cả các bạn cần làm tiếp theo là áp dụng một đơn giản region growing algorithm.

Nếu tôi đang sử dụng MATLAB, tôi sẽ sử dụng bwlabel/bwboundaries chức năng. Tôi tin rằng có một chức năng tương đương ở đâu đó trong NumPy, hoặc sử dụng OpenCV với wrappers python theo đề nghị của @kwatford

+0

Gói SciPy có chức năng ghi nhãn tương tự (http://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.measurements.label.html#scipy.ndimage.measurements.label) mà tôi có thể gắn nhãn tất cả các pixel chính xác bằng cách sử dụng nó. Nhưng điều đó chỉ giải quyết được phần đầu tiên của vấn đề. Tôi có thể phân biệt từng thực thể một cách riêng biệt. Thật không may, không có chức năng cho việc này. Cần phải được viết :) –

+0

Cách tôi hiểu nó, là mỗi đối tượng màu xanh trong hình ảnh là một thực thể, phải không? Sau đó, bằng cách gắn nhãn tất cả các điểm ảnh vào các vùng, bạn chỉ cần chọn tất cả các điểm ảnh được gắn nhãn là một, sau đó được gắn nhãn là hai, v.v ... để có được mỗi đối tượng ... Bước tiếp theo là trích xuất một số tính năng cho từng đối tượng (ranh giới, hình dạng, diện tích, kích thước, ...), sẽ được sử dụng trong nhiệm vụ phân loại được giám sát. – Amro

+0

Tôi đã làm rõ việc sử dụng các thực thể trong câu hỏi của mình trong phần LƯU Ý. Bây giờ, tất cả những gì tôi phải làm là lấy hình chữ nhật biên hoặc hình vuông cho một số trường hợp chiều rộng và chiều cao cho mỗi đối tượng. –

3

tôi sử dụng để làm điều này loại phân tích trên ảnh hiển vi và cuối cùng đưa tất cả những gì cần thiết vào một xử lý hình ảnh và gói phân tích được viết bằng C, được điều khiển thông qua Tcl. (Nó chỉ hoạt động với 512 x 512 hình ảnh, điều này giải thích tại sao 512 cây lại thường xuyên. Có những hình ảnh có kích thước khác nhau được phân bổ, nhưng hầu hết công việc được thực hiện với pixel 8 bit. 0xff và số lượng có ý nghĩa tối đa là 254 trên hình ảnh.)

Tóm lại, 'zz' ở đầu các lệnh Tcl gửi phần còn lại của dòng đến trình phân tích cú pháp của gói. Ngay sau 'zz' là một đối số cho biết đầu vào và đầu ra của lệnh. (Có thể có nhiều đầu vào nhưng chỉ có một đầu ra duy nhất.) 'R' cho biết hình ảnh 512 x 512 x 8-bit. Từ thứ ba là tên của lệnh được gọi; 'biểu đồ' đánh dấu một hình ảnh như được mô tả trong văn bản bên dưới. Vì vậy, 'zz rr graphs' có nghĩa là 'Gọi trình phân tích cú pháp ZZ; nhập một hình ảnh r vào lệnh đồ thị và lấy lại một hình ảnh r. ' Phần còn lại của dòng lệnh Tcl chỉ định hình ảnh được phân bổ trước nào để sử dụng. (Hình ảnh 'g' là ROI, tức là khu vực quan tâm, hình ảnh; hầu như tất cả các hoạt động của ZZ đều được thực hiện dưới sự kiểm soát ROI.) Vì vậy, 'r1 r1 g8' có nghĩa là 'Sử dụng r1 làm đầu vào, sử dụng r1 làm đầu ra (có nghĩa là, đánh dấu chính hình ảnh đầu vào) và thực hiện thao tác ở bất cứ nơi nào pixel tương ứng trên hình ảnh g8 --- tức là, r8, được sử dụng làm ROI --- là> 0.

Tôi không nghĩ rằng nó có sẵn trực tuyến ở bất cứ nơi nào, nhưng nếu bạn muốn chọn thông qua mã nguồn hoặc thậm chí biên dịch toàn bộ shebang, tôi sẽ rất vui khi gửi cho bạn. Dưới đây là một đoạn trích từ hướng dẫn sử dụng (nhưng tôi nghĩ rằng tôi thấy một số lỗi trong hướng dẫn tại ngày trễ này --- đó là đáng xấu hổ ...):

Ví dụ 6. Tính năng đếm.

Sự cố

Đếm là một tác vụ phổ biến. Các mục được tính được gọi là "tính năng" và thường cần phải chuẩn bị hình ảnh một cách cẩn thận để các đối tượng địa lý tương ứng theo cách một chiều với những thứ thực sự được tính. Ở đây, tuy nhiên, chúng tôi bỏ qua việc chuẩn bị hình ảnh và xem xét, thay vào đó, cơ chế đếm.Bài tập đếm đầu tiên là tìm hiểu xem có bao nhiêu tính năng trên hình ảnh trong thư mục ./cells?

Phương pháp tiếp cận

Trước tiên, chúng ta hãy định nghĩa "tính năng". Một đối tượng địa lý là nhóm lớn nhất của các pixel “set” (không khác), tất cả đều có thể đạt được bằng cách di chuyển từ một pixel này sang pixel khác dọc theo các tuyến đường bắc-nam-đông-tây (lên-xuống-phải-trái), bắt đầu từ một điểm ảnh đã cho. Lệnh zz phát hiện và đánh dấu các đối tượng trên hình ảnh là “biểu đồ zz rr R: src R: đích G: ROI”, được gọi là vì thuật ngữ toán học cho một đối tượng như vậy là “đồ thị”. Nếu tất cả các pixel trên một hình ảnh được đặt, thì chỉ có một biểu đồ trên hình ảnh, nhưng nó chứa 262144 pixel (512 * 512). Nếu pixel được đặt và rõ ràng (bằng 0) trong mẫu bàn cờ, thì sẽ có đồ thị 131072 (512 * 512/2), nhưng mỗi pixel sẽ chỉ chứa một pixel. Giải thích ngắn gọn, “biểu đồ zz rr” bắt đầu ở góc trên bên trái của hình ảnh và quét từng hàng thành công từ trái sang phải cho đến khi tìm thấy pixel được đặt, sau đó tìm tất cả các điểm ảnh được đặt ở phía bắc, nam, đông , hoặc biên giới phía tây ("4 kết nối"). Sau đó, nó đặt tất cả các pixel trong biểu đồ đó thành 1 (0x01). Sau khi tìm và đánh dấu biểu đồ 1, nó bắt đầu quét lại tại điểm ảnh sau điểm ảnh đầu tiên phát hiện biểu đồ 1, lần này bỏ qua bất kỳ pixel nào đã thuộc về biểu đồ. 254 đồ thị đầu tiên mà nó tìm thấy sẽ được đánh dấu duy nhất; Tuy nhiên, tất cả các đồ thị được tìm thấy sau đó sẽ được đánh dấu bằng giá trị 255 (0xff) và do đó không thể phân biệt được với nhau. Chìa khóa để có thể đếm bất kỳ số lượng đồ thị chính xác là xử lý từng hình ảnh theo từng giai đoạn, nghĩa là tìm số lượng đồ thị trên hình ảnh và nếu số lớn hơn 254, xóa 254 đồ thị vừa tìm thấy, lặp lại cho đến khi tìm thấy 254 hoặc ít hơn các đồ thị. Ngôn ngữ Tcl cung cấp các phương tiện để thiết lập quyền kiểm soát hoạt động này.

Hãy bắt đầu xây dựng các lệnh cần thiết bằng cách đọc tệp hình ảnh ZZ thành hình ảnh R và phát hiện và đánh dấu biểu đồ. Trước vòng lặp xử lý, chúng tôi khai báo và không phải là biến để giữ tổng số đối tượng địa lý trong chuỗi hình ảnh. Trong vòng lặp xử lý, chúng ta bắt đầu bằng cách đọc tệp hình ảnh thành một hình ảnh R và phát hiện và đánh dấu các biểu đồ.

zz ur to $inDir/$img r1 
zz rr graphs r1 r1 g8 

Tiếp theo, chúng tôi không có một số biến để theo dõi số lượng, sau đó sử dụng lệnh "tối đa" để tìm hiểu xem hơn 254 đồ thị đã được phát hiện hay chưa.

set nGraphs [ zz ra max r1 a1 g1 ] 

Nếu nGraphs làm bằng 255 thì 254 tính chính xác đồ thị nên được thêm vào tổng số, các đồ thị từ 1 đến 254 nên được xoá hoàn toàn, và các tính lặp đi lặp lại cho bao nhiêu lần vì nó cần thiết để giảm số đồ thị dưới 255.

while {$nGraphs == 255} { 
    incr sumGraphs 254 
    zz rbr lt r1 155 r1 g1 0 255 
    set sumGraphs 0 
    zz rr graphs r1 r1 g8 
    set nGraphs [ zz ra max r1 a1 g8 ] 
} 

Khi vòng lặp “while” thoát ra, biến nGraphs phải giữ số nhỏ hơn 255, tức là một số đồ thị được tính chính xác; điều này được thêm vào tổng số tăng của số lượng đối tượng trong chuỗi hình ảnh.

incr sumGraphs $nGraphs 

Sau vòng lặp xử lý, in tổng số tính năng tìm thấy trong chuỗi.

puts “Total number of features in $inDir \ 
images $beginImg through $endImg is $sumGraphs.” 

Sau vòng lặp xử lý, in tổng số tính năng tìm thấy trong chuỗi.

+0

Đây là câu trả lời rất dài. Sẽ mất một chút thời gian để nắm bắt các giải thích của bạn :) –

+0

Lưu ý rằng tôi đã thêm đoạn 2 vào làm phần giới thiệu nhỏ trong cú pháp dòng lệnh Tcl của gói. Điều đó có thể giúp bạn 'nắm bắt'. BTW, có các ví dụ khác trong hướng dẫn hiển thị cách chuẩn bị hình ảnh bằng cách sử dụng các hoạt động hình thái và sau đó, sau khi tìm và đếm các đối tượng địa lý, hãy làm những việc như tạo phân phối kích thước của chúng. Tôi chưa bao giờ nghiêm túc cố gắng thích nghi nó với Python, mặc dù nó đã được trong tâm trí của tôi để làm cho một thời gian. – behindthefall

+0

Ngoài ra BTW: 'đồ thị' về cơ bản sử dụng thuật toán từ Đồ họa Gems, Vol.I, p.721, của Paul Heckbert. – behindthefall

2

Connected component analysis có thể là những gì bạn đang tìm kiếm.

+0

Tôi biết rằng phải có một mới cho kỹ thuật này :) Cảm ơn các con trỏ. Cả pygraph (http://code.google.com/p/python-graph/) và opencv với Python wrappings có một số hỗ trợ cho các thuật toán này, tuy nhiên việc sử dụng chúng không rõ ràng đối với tôi. Bạn đã sử dụng bất kỳ chức năng nào trong số đó chưa? –

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