Cách: gói pixel trong ảnh đến tọa độ điểm đại diện (x, y)


7

Chúng ta hãy có một hình ảnh (thang màu xám hoặc thậm chí là nhị phân) như được hiển thị trên hình dưới đây ở phía bên trái, mục tiêu là tạo ra một danh sách các điểm tức là tọa độ dưới dạng (x, y) cho mỗi gói của pixel tối trong hình ảnh.
Các công cụ xử lý hình ảnh thích hợp để làm điều này là gì và chúng có sẵn ở đâu?

gói pixel để tọa độ điểm


Cập nhật:
1) Tại đây bạn có thể tìm thấy một số chi tiết về vấn đề. (Lưu ý sự thay đổi kích thước của các gói)

chi tiết

Tôi có thể đề nghị có các gói được phát hiện để tính ranh giới lồi cho mỗi và sau đó tìm trung tâm đại diện {xem phần này để biết chi tiết} .

gói pixel để lồi lên đến điểm trung tâm


2)
Đây là kết quả được tạo ra bởi ứng dụng Biến đổi khoảng cách (được đề xuất bởi "Libor"). Lưu ý các chú thích của tôi trên hình. Phương pháp này không hoạt động như đã hứa!

nhập mô tả hình ảnh ở đây

3)
Ăn mòn loại bỏ các gói nhỏ!

from __future__ import division
from scipy import zeros, ndimage as dsp
from pylab import subplot,plot,matshow,show

img = zeros((30,30))
img[10:14,10:14] = 1
img[16:17,16:17] = 1
img[19:23,19] = 1
img[19,19:23] = 1

subplot(221)
matshow(img,0)

subplot(222)
y = dsp.binary_erosion(img,[[1,1],[1,1]])
matshow(y,0)

subplot(223)
y = dsp.binary_erosion(img,[[0,1,0],[1,1,1],[0,1,0]])
matshow(y,0)

subplot(224)
y = dsp.binary_erosion(img,[[1,1,1],[1,1,1],[1,1,1]])
matshow(y,0)

show()

nhập mô tả hình ảnh ở đây

4)
Vâng, đây là một Python (nghĩa là ngôn ngữ của tình yêu :)) thực hiện ý tưởng ghi nhãn (cũng được đề xuất bởi "Jean-Yves" bên dưới):

subplot(221)
l,n = dsp.label(img)
sl = dsp.find_objects(l)
for s in sl:
    x = (s[1].start+s[1].stop-1)/2
    y = (s[0].start+s[0].stop-1)/2
    plot(x,y,'wo')

và kết quả:

nhập mô tả hình ảnh ở đây

Lưu ý rằng mặc dù nó được thực hiện bằng Python rất nhanh do hiệu năng Scipy, quy trình nền trong labelchức năng phải là một phép lặp hết sức. Điều này có thể được coi là một sự đánh đổi. Vì vậy, trong một thời gian, tôi luôn mong muốn tìm kiếm các thuật toán hiệu quả hơn. Và cũng lưu ý rằng trong đoạn mã đã cho ở trên, tôi thấy trung tâm của hình học rất đơn giản trong khi đối với các hình dạng phức tạp hoặc không đối xứng, điều này có thể khiến định vị bị sai lệch. Đó là một công việc đang tiến triển;).

5)
Đây là một trường hợp phức tạp (một hình ảnh thực) được chụp từ đây mà đề xuất ghi nhãn được áp dụng và bạn thấy kết quả. Lưu ý rằng chỉ mất 0,015 giây cho toàn bộ quy trình bao gồm ghi nhãn và tìm các đối tượng. Những người Scipy , tôi đã làm rất tốt, tôi nghĩ vậy. Ồ {nhấp chuột phải vào hình ảnh, nhấp vào xem hình ảnh để có độ phân giải đầy đủ}

nhập mô tả hình ảnh ở đây


Bạn có biết: 1) Số lượng gói. 2) Kích thước tối đa / tối thiểu của một gói. 3) Kích thước tối đa / tối thiểu của một gói.
Spacey

@Mohammad Đưa ra chỉ là một hình ảnh. Do đó, không có thông tin cần thiết mà bạn đề cập có sẵn.
Nhà phát triển

Nếu bạn có thể phát hiện số lượng gói, thì tôi sẽ sử dụng đó làm giá trị của 'k' trong thuật toán k-mean chung. Nó sẽ hội tụ đến trung tâm của mỗi cụm, với giá trị k. Tuy nhiên, tôi không chắc làm thế nào bạn có thể xác định giá trị của 'k'. Làm thế nào bạn sẽ xác định điều đó?
Spacey

Bạn cần độ chính xác của pixel phụ để biến đổi / xói mòn khoảng cách để phát hiện cực đại trong các miếng vá nhỏ (ví dụ 2x2). Có cực đại, nhưng không thể được phát hiện vì bạn bỏ qua chúng với mẫu của bạn. Trong trường hợp biến đổi khoảng cách, bạn có thể lấy mẫu hình ảnh của mình theo hệ số hai hoặc tính toán biến đổi cho các vị trí pixel phụ (0,0, 0,5, 1,0, 1,5 ...). Trong trường hợp xói mòn, bạn có thể thực hiện nó bằng cách sử dụng hình thái dựa trên PDE (lặp).
Libor

@ Nhà phát triển câu hỏi này của tôi về SO có thể được quan tâm: stackoverflow.com/questions /
Ivo Flipse

Câu trả lời:


4

Chỉ là một gợi ý ngây thơ: bạn có biết về ghi nhãn thành phần không?

Kỹ thuật này là về việc tìm các khối pixel "chạm" và gán cho chúng một nhãn, ví dụ số nguyên. Sau đó, bạn có thể thẩm vấn từng chink riêng biệt, tìm kiếm pixel có chung nhãn.

Trong MATLAB, đây là chức năng thực hiện nó một cách tầm thường: bwlabel


Cảm ơn đề xuất. Tôi đã tiếp cận theo cách này và như bạn đã đề cập, tôi đã cập nhật bài đăng với sự bổ sung bằng Python . Tôi đã xuất hiện một số vấn đề liên quan đến việc sử dụng nhãn trong Cập nhật 4 :
Nhà phát triển

Tôi ủng hộ điều này vì nó là một cách tiếp cận khác để giải quyết vấn đề. Cảm ơn đã chia sẻ :)
Nhà phát triển

Bạn có thể làm rõ bản cập nhật 4? Tôi không hiểu ý bạn là gì khi đánh đổi và kiệt sức.
Jean-Yves

Làm nhãn là một công việc lặp đi lặp lại đòi hỏi rất nhiều tính toán. Tuy nhiên, những người Scipy đã hoàn thành xuất sắc công việc (hoặc một số thủ thuật!) Để làm điều đó gần như ngay lập tức. Tôi đặt một trường hợp phức tạp thực sự để đánh giá và nó chỉ hoạt động trong 0,015 s. Nó không tuyệt sao? Lưu ý rằng phần thứ hai tức là tìm trung tâm của các gói được phát hiện vẫn còn là một câu hỏi. Rõ ràng việc áp dụng vỏ lồi cho một bộ gói mssive như vậy là không nên.
Nhà phát triển

Ở đó tôi không đồng ý: ghi nhãn các thành phần được kết nối KHÔNG mở rộng. Nó chạy trong thời gian tuyến tính trong hầu hết các triển khai hiện đại, và một số thậm chí còn quản lý để nó chạy đa luồng.
Jean-Yves

3

Bạn cũng có thể chạy biến đổi khoảng cách trên hình ảnh, sau đó phát hiện cực đại cục bộ (tìm kiếm các pixel có giá trị cao nhất / thấp nhất của tất cả các pixel trong bản vá 3x3 pixel - có thể lớn hơn tùy thuộc vào khoảng cách tối thiểu dự kiến ​​giữa các đốm màu gốc).

Lưu ý rằng để phát hiện các tính năng có kích thước 1-3 pixel, bạn cần tăng gấp đôi tần số lấy mẫu của mình (nâng cao hình ảnh nguồn hoặc thực hiện chuyển đổi / xói mòn khoảng cách với độ chính xác của pixel phụ).

CẬP NHẬT:

Cả hai cách tiếp cận biến đổi và xói mòn đều cho rằng các tính năng bạn đang phát hiện là lồi. Một cái gì đó có hình chữ U, ví dụ, có thể bắn vào máy dò của bạn nhiều lần.

Một phương pháp phức tạp hơn cho phân đoạn như vậy dựa trên tập cấp độđường viền hoạt động . Nó bắt đầu với một đường cong khép kín lớn thích ứng với các tính năng của bạn. Phương pháp này đã được sử dụng trên trường đại học của tôi để đếm các tế bào và phát hiện nhiễm sắc thể trong hình ảnh kính hiển vi.


Bạn có thể thấy kết quả thực hiện ý tưởng của tôi trong phần Cập nhật: 2 . Có vẻ như nó không hoạt động như mong đợi :(
Nhà phát triển

OK, tôi đã mở rộng câu trả lời của mình.
Libor

Tôi ủng hộ điều này vì nó là một cách tiếp cận khác để giải quyết vấn đề. Cảm ơn đã chia sẻ :)
Nhà phát triển

2

Một lựa chọn sẽ là áp dụng xói mòn hình thái lặp đi lặp lại cho hình ảnh cho đến khi nó bị xói mòn hoàn toàn. Tại thời điểm đó, mỗi đốm màu hiển thị ở trên sẽ được giảm xuống một pixel; bạn có thể lấy vị trí của các pixel đó làm danh sách các điểm bạn đang tìm kiếm.


Một số điểm: 1) làm thế nào để dừng lặp? 2) nó có thể biến mất những gói nhỏ hơn. 3) nó trông rất chuyên sâu khi tính toán lặp lại cho toàn bộ tập dữ liệu. Lưu ý hình ảnh có thể lớn.
Nhà phát triển

Tôi nhanh chóng thực hiện ý tưởng của bạn ở dạng hiện tại nhưng nó không hoạt động. Nó loại bỏ các gói nhỏ. Tất cả các ý kiến ​​trước đây của tôi áp dụng.
Nhà phát triển

Tôi không chắc ý của bạn là "gói nhỏ". Có bất kỳ hiển thị trong hình ảnh ví dụ?
Jason R

Chà, như thể hiện các gói có kích cỡ và hình dạng khác nhau và khi tôi áp dụng xói mòn lặp đi lặp lại (Python: Scipy: Spatial: Xói mòn) thì các gói nhỏ hơn (hoặc hẹp hơn) đã biến mất. Lưu ý rằng trong trường hợp thực tế, gói trong hình ảnh đầu vào có thể nằm trong phạm vi từ một pixel đến rất lớn.
Nhà phát triển

@ Nhà phát triển Bạn có biết số lượng 'gói' trước thời hạn không? Ví dụ: ở đây, bạn có 6.
Spacey

2

Tôi sợ rằng bất cứ cách nào bạn chọn để làm điều này, nó sẽ không đơn giản bởi vì để gán các mục tiêu cho các cụm bạn sẽ phải đi qua hình ảnh (ít nhất một lần).

Tôi cho rằng việc đạt được điểm là vấn đề dễ dàng hơn của cả hai (có lẽ bạn đã áp dụng một số hình thức ngưỡng) chẳng hạn).

Để khôi phục các cụm điểm được nhóm lại và thực hiện nhanh chóng, bạn có thể tạo cấu trúc bốn cây chứa "chuỗi các pixel được kết nối" nằm ở đâu đó quanh khu vực của ô bốn cây.

Theo cách này, bạn có thể lặp qua hình ảnh và một khi bạn bắt gặp một pixel là mục tiêu, hãy "đẩy" nó trong cấu trúc bốn cây của bạn.

Thao tác "đẩy" này sẽ bắt đầu một quy trình lặp sẽ trả về ô (nói cách khác là khu vực cụ thể của hình ảnh) nơi pixel cụ thể nằm trong. Sau đó, bạn có thể lặp qua tất cả các chuỗi pixel được gán cho ô đó và thử để "đẩy" (một lần nữa) pixel vào chuỗi pixel. Chuỗi pixel chấp nhận một pixel mới nếu nó có ít nhất 1 pixel gần với bất kỳ pixel nào đã được gán. Nếu không có chuỗi pixel nào "chấp nhận" pixel mới, thì hãy tạo chuỗi pixel mới vào ô này và gán pixel mới cho nó.

Cây tứ giác ở đây là một cách để giới hạn tìm kiếm của bạn cho chuỗi pixel gần nhất và sẽ được yêu cầu nếu hình ảnh của bạn lớn và nhiều mục tiêu để các hoạt động đẩy chuỗi pixel được thực hiện nhanh chóng. Nếu bạn biết rằng bạn sẽ không phải đối phó với một số lượng lớn các mục tiêu thì bạn thậm chí có thể bỏ qua cây bốn lá và duy trì một "danh sách chuỗi pixel" đơn giản. Mỗi khi bạn bắt gặp một "mục tiêu", bạn có thể lặp lại qua các danh sách và thử "đẩy" pixel trên chúng. Nếu không có danh sách "thừa nhận" pixel thì hãy tạo một danh sách mới và gán pixel vào.

Dù bạn chọn cách nào, vào cuối quá trình này, bạn sẽ có một bộ "chuỗi pixel" được kết nối (cụm của bạn) mà sau đó bạn có thể chuyển sang phần khác của chương trình sẽ xử lý ước tính của chúng vị trí. Đây có thể là thân lồi, khớp mô hình (ví dụ ellipsoid hoặc loại khác) hoặc đơn giản là giá trị trung bình / trung bình của tọa độ x, y.

Tôi hi vọng cái này giúp được.


Tôi ủng hộ điều này vì nó là một cách tiếp cận khác để giải quyết vấn đề. Cảm ơn đã chia sẻ :)
Nhà phát triển
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.