Phát hiện cực đại trong một mảng 2D


874

Tôi đang giúp một phòng khám thú y đo áp lực dưới chân chó. Tôi sử dụng Python để phân tích dữ liệu của mình và bây giờ tôi bị mắc kẹt khi cố gắng chia các bàn chân thành các tiểu vùng (giải phẫu).

Tôi đã tạo một mảng 2D của mỗi chân, bao gồm các giá trị tối đa cho mỗi cảm biến đã được tải bởi chân theo thời gian. Đây là một ví dụ về một chân, trong đó tôi đã sử dụng Excel để vẽ các khu vực tôi muốn 'phát hiện'. Đây là 2 trong 2 hộp xung quanh cảm biến với cực đại cục bộ, cùng nhau có tổng tiền lớn nhất.

văn bản thay thế

Vì vậy, tôi đã thử một số thử nghiệm và quyết định chỉ đơn giản là tìm kiếm mức tối đa của mỗi cột và hàng (không thể nhìn theo một hướng do hình dạng của bàn chân). Điều này dường như 'phát hiện' vị trí của các ngón chân riêng biệt khá tốt, nhưng nó cũng đánh dấu các cảm biến lân cận.

văn bản thay thế

Vậy đâu là cách tốt nhất để nói với Python rằng mức tối đa nào là thứ tôi muốn?

Lưu ý: Các hình vuông 2x2 không thể trùng nhau, vì chúng phải là các ngón chân riêng biệt!

Ngoài ra, tôi lấy 2x2 làm tiện lợi, mọi giải pháp tiên tiến hơn đều được hoan nghênh, nhưng tôi chỉ đơn giản là một nhà khoa học về chuyển động của con người, vì vậy tôi không phải là một lập trình viên thực sự hay một nhà toán học, vì vậy hãy giữ cho nó 'đơn giản'.

Đây là phiên bản có thể được tải vớinp.loadtxt


Các kết quả

Vì vậy, tôi đã thử giải pháp của @ jextee (xem kết quả bên dưới). Như bạn có thể thấy, nó hoạt động rất tốt ở bàn chân trước, nhưng nó hoạt động kém hơn đối với chân sau.

Cụ thể hơn, nó không thể nhận ra đỉnh nhỏ đó là ngón chân thứ tư. Điều này rõ ràng là cố hữu với thực tế là vòng lặp nhìn từ trên xuống về phía giá trị thấp nhất, mà không tính đến nơi này.

Có ai biết làm thế nào để điều chỉnh thuật toán của @ jextee, để nó cũng có thể tìm thấy ngón chân thứ 4 không?

văn bản thay thế

Vì tôi chưa xử lý bất kỳ thử nghiệm nào khác, tôi không thể cung cấp bất kỳ mẫu nào khác. Nhưng dữ liệu tôi đưa ra trước đây là trung bình của mỗi chân. Tệp này là một mảng với dữ liệu tối đa là 9 chân theo thứ tự chúng đã liên lạc với tấm.

Hình ảnh này cho thấy cách chúng được trải rộng trên không gian.

văn bản thay thế

Cập nhật:

Tôi đã thiết lập một blog cho bất kỳ ai quan tâm tôi đã thiết lập SkyDrive với tất cả các phép đo thô. Vì vậy, cho bất cứ ai yêu cầu nhiều dữ liệu hơn: nhiều quyền lực hơn cho bạn!


Cập nhật mới:

Vì vậy, sau khi được giúp đỡ, tôi đã nhận được câu hỏi của mình về phát hiện chânphân loại chân , cuối cùng tôi đã có thể kiểm tra phát hiện ngón chân cho mỗi chân! Hóa ra, nó không hoạt động tốt trong bất cứ thứ gì ngoại trừ bàn chân có kích thước giống như trong ví dụ của tôi. Dĩ nhiên, về mặt nhận thức, đó là lỗi của tôi khi chọn 2x2 một cách tùy tiện.

Đây là một ví dụ hay về sai lầm: móng tay được nhận ra là ngón chân và 'gót chân' rất rộng, nó được nhận ra hai lần!

văn bản thay thế

Bàn chân quá lớn, do đó, việc lấy kích thước 2x2 không có sự chồng chéo, khiến một số ngón chân bị phát hiện hai lần. Một cách khác, ở những con chó nhỏ thường không tìm thấy ngón chân thứ 5, mà tôi nghi ngờ là do diện tích 2x2 quá lớn.

Sau khi thử giải pháp hiện tại trên tất cả các phép đo của tôi tôi, tôi đã đi đến kết luận đáng kinh ngạc rằng gần như tất cả những con chó nhỏ của tôi, nó không tìm thấy ngón chân thứ 5 và trong hơn 50% tác động đối với những con chó lớn, nó sẽ tìm thấy nhiều hơn!

Vì vậy, rõ ràng tôi cần phải thay đổi nó. Dự đoán của riêng tôi là thay đổi kích thước của neighborhoodmột cái gì đó nhỏ hơn cho những con chó nhỏ và lớn hơn cho những con chó lớn. Nhưng generate_binary_structuresẽ không để tôi thay đổi kích thước của mảng.

Do đó, tôi hy vọng rằng bất cứ ai khác có một gợi ý tốt hơn để xác định vị trí các ngón chân, có lẽ có tỷ lệ diện tích ngón chân với kích thước bàn chân?


Tôi cho rằng dấu phẩy là vị trí thập phân chứ không phải dấu phân cách giá trị?
MattH

Vâng, họ là dấu phẩy. Và @Christian, tôi đang cố gắn nó vào một tệp dễ đọc, nhưng ngay cả điều đó cũng không thành công với tôi :(
Ivo Flipse

3
Khi tôi đang làm một nghiên cứu khả thi, bất cứ điều gì thực sự đi. Vì vậy, tôi đang tìm kiếm nhiều cách để xác định áp lực, bao gồm cả các tiểu vùng. Ngoài ra, tôi cần có khả năng phân biệt giữa hai bên 'ngón chân cái' và 'ngón chân út', để ước tính định hướng. Nhưng vì điều này chưa được thực hiện trước đó, nên không biết chúng ta có thể tìm thấy gì :-)
Ivo Flipse

2
@Ron: một trong những mục tiêu của nghiên cứu này là xem kích thước / trọng lượng của con chó phù hợp với hệ thống, vì vậy có trong khi con chó này nặng khoảng 20 kg. Tôi có một số nhỏ hơn đáng kể (và lớn hơn) và hy vọng rằng tôi sẽ không thể làm điều tương tự cho những người nhỏ thực sự.
Ivo Flipse

2
@frank bàn chân được đo theo thời gian, do đó chiều thứ 3. Tuy nhiên, chúng không di chuyển khỏi vị trí của chúng (nói một cách tương đối) nên tôi chủ yếu quan tâm đến việc các ngón chân nằm ở đâu trong 2D. Khía cạnh 3D được cung cấp miễn phí sau đó
Ivo Flipse

Câu trả lời:


332

Tôi đã phát hiện các đỉnh bằng bộ lọc tối đa cục bộ . Đây là kết quả trên bộ dữ liệu đầu tiên của bạn về 4 bàn chân: Kết quả phát hiện đỉnh

Tôi cũng đã chạy nó trên bộ dữ liệu thứ hai gồm 9 bàn chân và nó cũng hoạt động tốt .

Đây là cách bạn làm điều đó:

import numpy as np
from scipy.ndimage.filters import maximum_filter
from scipy.ndimage.morphology import generate_binary_structure, binary_erosion
import matplotlib.pyplot as pp

#for some reason I had to reshape. Numpy ignored the shape header.
paws_data = np.loadtxt("paws.txt").reshape(4,11,14)

#getting a list of images
paws = [p.squeeze() for p in np.vsplit(paws_data,4)]


def detect_peaks(image):
    """
    Takes an image and detect the peaks usingthe local maximum filter.
    Returns a boolean mask of the peaks (i.e. 1 when
    the pixel's value is the neighborhood maximum, 0 otherwise)
    """

    # define an 8-connected neighborhood
    neighborhood = generate_binary_structure(2,2)

    #apply the local maximum filter; all pixel of maximal value 
    #in their neighborhood are set to 1
    local_max = maximum_filter(image, footprint=neighborhood)==image
    #local_max is a mask that contains the peaks we are 
    #looking for, but also the background.
    #In order to isolate the peaks we must remove the background from the mask.

    #we create the mask of the background
    background = (image==0)

    #a little technicality: we must erode the background in order to 
    #successfully subtract it form local_max, otherwise a line will 
    #appear along the background border (artifact of the local maximum filter)
    eroded_background = binary_erosion(background, structure=neighborhood, border_value=1)

    #we obtain the final mask, containing only peaks, 
    #by removing the background from the local_max mask (xor operation)
    detected_peaks = local_max ^ eroded_background

    return detected_peaks


#applying the detection and plotting results
for i, paw in enumerate(paws):
    detected_peaks = detect_peaks(paw)
    pp.subplot(4,2,(2*i+1))
    pp.imshow(paw)
    pp.subplot(4,2,(2*i+2) )
    pp.imshow(detected_peaks)

pp.show()

Tất cả bạn cần làm sau là sử dụng scipy.ndimage.measurements.labeltrên mặt nạ để dán nhãn cho tất cả các đối tượng riêng biệt. Sau đó, bạn sẽ có thể chơi với họ cá nhân.

Lưu ý rằng phương pháp hoạt động tốt vì nền không ồn. Nếu đúng như vậy, bạn sẽ phát hiện ra một loạt các đỉnh không mong muốn khác trong nền. Một yếu tố quan trọng khác là quy mô của khu phố . Bạn sẽ cần điều chỉnh nó nếu kích thước cực đại thay đổi (nên duy trì tỷ lệ xấp xỉ).


1
Có một giải pháp đơn giản hơn (eroding_background ^ local_peaks). Chỉ cần làm (tiền cảnh & đỉnh địa phương)
Ryan Soklaski

53

Giải pháp

Tệp dữ liệu: paw.txt . Mã nguồn:

from scipy import *
from operator import itemgetter

n = 5  # how many fingers are we looking for

d = loadtxt("paw.txt")
width, height = d.shape

# Create an array where every element is a sum of 2x2 squares.

fourSums = d[:-1,:-1] + d[1:,:-1] + d[1:,1:] + d[:-1,1:]

# Find positions of the fingers.

# Pair each sum with its position number (from 0 to width*height-1),

pairs = zip(arange(width*height), fourSums.flatten())

# Sort by descending sum value, filter overlapping squares

def drop_overlapping(pairs):
    no_overlaps = []
    def does_not_overlap(p1, p2):
        i1, i2 = p1[0], p2[0]
        r1, col1 = i1 / (width-1), i1 % (width-1)
        r2, col2 = i2 / (width-1), i2 % (width-1)
        return (max(abs(r1-r2),abs(col1-col2)) >= 2)
    for p in pairs:
        if all(map(lambda prev: does_not_overlap(p,prev), no_overlaps)):
            no_overlaps.append(p)
    return no_overlaps

pairs2 = drop_overlapping(sorted(pairs, key=itemgetter(1), reverse=True))

# Take the first n with the heighest values

positions = pairs2[:n]

# Print results

print d, "\n"

for i, val in positions:
    row = i / (width-1)
    column = i % (width-1)
    print "sum = %f @ %d,%d (%d)" % (val, row, column, i)
    print d[row:row+2,column:column+2], "\n"

Đầu ra không có hình vuông chồng chéo. Có vẻ như các khu vực tương tự được chọn như trong ví dụ của bạn.

Một vài bình luận

Phần khó khăn là tính tổng của tất cả các hình vuông 2x2. Tôi giả sử bạn cần tất cả chúng, vì vậy có thể có một số chồng chéo. Tôi đã sử dụng các lát để cắt các cột và hàng đầu tiên / cuối cùng từ mảng 2D ban đầu, sau đó chồng chúng lại với nhau và tính tổng.

Để hiểu rõ hơn về nó, hãy tạo một mảng 3x3:

>>> a = arange(9).reshape(3,3) ; a
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

Sau đó, bạn có thể lấy lát của nó:

>>> a[:-1,:-1]
array([[0, 1],
       [3, 4]])
>>> a[1:,:-1]
array([[3, 4],
       [6, 7]])
>>> a[:-1,1:]
array([[1, 2],
       [4, 5]])
>>> a[1:,1:]
array([[4, 5],
       [7, 8]])

Bây giờ hãy tưởng tượng bạn xếp chúng lên trên các phần tử khác và tính tổng tại cùng một vị trí. Các khoản tiền này sẽ chính xác là các khoản tiền giống nhau trên các ô vuông 2x2 với góc trên cùng bên trái ở cùng một vị trí:

>>> sums = a[:-1,:-1] + a[1:,:-1] + a[:-1,1:] + a[1:,1:]; sums
array([[ 8, 12],
       [20, 24]])

Khi bạn có tổng tiền trên các hình vuông 2x2, bạn có thể sử dụng maxđể tìm mức tối đa hoặc sorthoặc sortedđể tìm các đỉnh.

Để ghi nhớ các vị trí của các đỉnh tôi ghép mọi giá trị (tổng) với vị trí thứ tự của nó trong một mảng phẳng (xem zip). Sau đó, tôi tính toán vị trí hàng / cột một lần nữa khi tôi in kết quả.

Ghi chú

Tôi cho phép các hình vuông 2x2 chồng lên nhau. Phiên bản đã chỉnh sửa lọc ra một số trong số chúng chỉ có các ô vuông không chồng lấp xuất hiện trong kết quả.

Chọn ngón tay (một ý tưởng)

Một vấn đề khác là làm thế nào để chọn những gì có khả năng là ngón tay trong số tất cả các đỉnh. Tôi có một ý tưởng có thể hoặc không thể làm việc. Tôi không có thời gian để thực hiện nó ngay bây giờ, vì vậy chỉ cần mã giả.

Tôi nhận thấy rằng nếu các ngón tay trước nằm trên một vòng tròn hoàn hảo, thì ngón tay sau phải nằm trong vòng tròn đó. Ngoài ra, các ngón tay phía trước cách đều nhau hoặc ít hơn. Chúng tôi có thể cố gắng sử dụng các đặc tính heuristic này để phát hiện các ngón tay.

Mã giả:

select the top N finger candidates (not too many, 10 or 12)
consider all possible combinations of 5 out of N (use itertools.combinations)
for each combination of 5 fingers:
    for each finger out of 5:
        fit the best circle to the remaining 4
        => position of the center, radius
        check if the selected finger is inside of the circle
        check if the remaining four are evenly spread
        (for example, consider angles from the center of the circle)
        assign some cost (penalty) to this selection of 4 peaks + a rear finger
        (consider, probably weighted:
             circle fitting error,
             if the rear finger is inside,
             variance in the spreading of the front fingers,
             total intensity of 5 peaks)
choose a combination of 4 peaks + a rear peak with the lowest penalty

Đây là một cách tiếp cận vũ phu. Nếu N tương đối nhỏ, thì tôi nghĩ nó có thể làm được. Đối với N = 12, có C_12 ^ 5 = 792 kết hợp, lần 5 cách để chọn một ngón tay phía sau, vì vậy 3960 trường hợp để đánh giá cho mỗi chân.


Anh ta sẽ phải lọc các bàn chân theo cách thủ công, đưa ra danh sách kết quả của bạn ... chọn bốn kết quả cao nhất sẽ cho anh ta bốn khả năng để xây dựng một hình vuông 2x2 chứa giá trị tối đa 6,8
Julian Charra

Các hộp 2x2 không thể trùng nhau, vì nếu tôi muốn thống kê, tôi không muốn sử dụng cùng một khu vực, tôi muốn so sánh các khu vực :-)
Ivo Flipse

Tôi chỉnh sửa câu trả lời. Bây giờ không có hình vuông chồng chéo trong kết quả.
sastanin

1
Tôi đã thử nó và nó dường như hoạt động cho bàn chân trước, nhưng ít hơn cho những người chân sau. Đoán chúng ta sẽ phải thử một cái gì đó biết nơi để tìm
Ivo Flipse

1
Tôi đã giải thích ý tưởng của mình làm thế nào ngón tay có thể được phát hiện trong mã giả. Nếu bạn thích nó, tôi có thể cố gắng thực hiện nó vào tối mai.
sastanin

34

Đây là một vấn đề đăng ký hình ảnh . Chiến lược chung là:

  • Có một ví dụ đã biết, hoặc một số loại trước trên dữ liệu.
  • Điều chỉnh dữ liệu của bạn với ví dụ hoặc điều chỉnh ví dụ với dữ liệu của bạn.
  • Nó giúp nếu dữ liệu của bạn được sắp xếp gần đúng ở vị trí đầu tiên.

Đây là một cách tiếp cận thô sơ và sẵn sàng , "điều ngu ngốc nhất có thể có thể làm việc":

  • Bắt đầu với năm tọa độ ngón chân ở khoảng nơi bạn mong đợi.
  • Với mỗi người, lặp đi lặp lại leo lên đỉnh đồi. tức là vị trí hiện tại, di chuyển đến pixel lân cận tối đa, nếu giá trị của nó lớn hơn pixel hiện tại. Dừng lại khi tọa độ ngón chân của bạn đã ngừng di chuyển.

Để chống lại sự cố định hướng, bạn có thể có 8 cài đặt ban đầu cho các hướng cơ bản (Bắc, Đông Bắc, v.v.). Chạy từng cái một và vứt bỏ mọi kết quả trong đó hai hoặc nhiều ngón chân kết thúc tại cùng một pixel. Tôi sẽ suy nghĩ thêm về điều này, nhưng loại điều này vẫn đang được nghiên cứu trong xử lý hình ảnh - không có câu trả lời đúng!

Ý tưởng phức tạp hơn một chút: (có trọng số) K-có nghĩa là phân cụm. Nó không tệ.

  • Bắt đầu với năm tọa độ ngón chân, nhưng bây giờ đây là "trung tâm cụm".

Sau đó lặp đi lặp lại cho đến khi hội tụ:

  • Gán từng pixel cho cụm gần nhất (chỉ cần tạo một danh sách cho mỗi cụm).
  • Tính trọng tâm khối lượng của mỗi cụm. Đối với mỗi cụm, đây là: Tổng (tọa độ * giá trị cường độ) / Tổng (tọa độ)
  • Di chuyển từng cụm đến trung tâm mới của khối lượng.

Phương pháp này gần như chắc chắn sẽ cho kết quả tốt hơn nhiều và bạn có được khối lượng của từng cụm có thể giúp xác định các ngón chân.

(Một lần nữa, bạn đã chỉ định số lượng cụm phía trước. Với việc phân cụm bạn phải chỉ định mật độ theo cách này hay cách khác: Hoặc chọn số lượng cụm, phù hợp trong trường hợp này hoặc chọn bán kính cụm và xem bạn kết thúc bao nhiêu lên với. Một ví dụ về cái sau là mean-shift .)

Xin lỗi về việc thiếu chi tiết thực hiện hoặc các chi tiết cụ thể khác. Tôi sẽ viết mã này nhưng tôi đã có thời hạn. Nếu không có gì khác làm việc vào tuần tới, hãy cho tôi biết và tôi sẽ thử.


1
Vấn đề là, các bàn chân thay đổi hướng của chúng và tôi không có bất kỳ hiệu chuẩn / đường cơ sở nào của một chân chính xác để bắt đầu. Thêm vào đó tôi sợ rằng rất nhiều thuật toán nhận dạng hình ảnh nằm ngoài khả năng của tôi.
Ivo Flipse

Cách tiếp cận "thô và sẵn sàng" khá đơn giản - có thể tôi đã không hiểu rõ ý tưởng. Tôi sẽ đưa vào một số mã giả để minh họa.
CakeMaster

Tôi có cảm giác đề nghị của bạn sẽ giúp khắc phục sự nhận biết của bàn chân sau, tôi chỉ không biết 'làm thế nào'
Ivo Flipse

Tôi đã thêm một ý tưởng khác. Nhân tiện, nếu bạn có một tải dữ liệu tốt, sẽ rất tuyệt nếu đặt nó trực tuyến ở đâu đó. Nó có thể hữu ích cho những người nghiên cứu xử lý hình ảnh / học máy và bạn có thể lấy thêm một số mã từ nó ...
CakeMaster

1
Tôi chỉ nghĩ về việc viết ra xử lý dữ liệu của mình trên một blog Wordpress đơn giản, đơn giản là để sử dụng cho mục đích khác và dù sao tôi cũng phải viết nó xuống. Tôi thích tất cả các đề xuất của bạn, nhưng tôi sợ tôi sẽ phải đợi ai đó mà không có thời hạn ;-)
Ivo Flipse

18

Sử dụng tương đồng liên tục để phân tích tập dữ liệu của bạn Tôi nhận được kết quả sau (nhấp để phóng to):

Kết quả

Đây là phiên bản 2D của phương pháp phát hiện cực đại được mô tả trong câu trả lời SO này . Hình trên chỉ đơn giản cho thấy các lớp tương đồng liên tục 0 chiều được sắp xếp theo sự kiên trì.

Tôi đã nâng cấp dữ liệu gốc theo hệ số 2 bằng scipy.misc.imresize (). Tuy nhiên, lưu ý rằng tôi đã coi bốn bàn chân là một bộ dữ liệu; chia nó thành bốn sẽ làm cho vấn đề dễ dàng hơn.

Phương pháp luận. Ý tưởng đằng sau điều này khá đơn giản: Hãy xem xét biểu đồ hàm của hàm gán cho mỗi pixel mức của nó. Nó trông như thế này:

Biểu đồ chức năng 3D

Bây giờ hãy xem xét mực nước ở độ cao 255 liên tục hạ xuống mức thấp hơn. Tại các đảo cực đại địa phương bật lên (sinh). Tại điểm yên ngựa hai hòn đảo hợp nhất; chúng tôi coi hòn đảo thấp hơn sẽ được sáp nhập với hòn đảo cao hơn (cái chết). Cái gọi là sơ đồ bền vững (của các lớp tương đồng chiều 0, các đảo của chúng ta) mô tả các giá trị sinh tử trên tất cả các đảo:

Sơ đồ bền

Sự kiên trì của một hòn đảo là sự khác biệt giữa mức độ sinh và tử; khoảng cách dọc của một dấu chấm đến đường chéo chính màu xám. Con số ghi nhãn các đảo bằng cách giảm sự kiên trì.

Hình ảnh đầu tiên cho thấy các địa điểm sinh ra của các hòn đảo. Phương pháp này không chỉ mang lại cực đại cục bộ mà còn định lượng "tầm quan trọng" của chúng bằng sự kiên trì đã đề cập ở trên. Người ta sẽ lọc tất cả các đảo với độ bền quá thấp. Tuy nhiên, trong ví dụ của bạn, mọi hòn đảo (tức là mọi địa phương tối đa) là một đỉnh bạn tìm kiếm.

Mã Python có thể được tìm thấy ở đây .


16

Vấn đề này đã được nghiên cứu ở một số độ sâu bởi các nhà vật lý. Có một triển khai tốt trong ROOT . Nhìn vào các lớp TSpectrum (đặc biệt là TSpectrum2 cho trường hợp của bạn) và tài liệu cho chúng.

Người giới thiệu:

  1. M.Morhac et al.: Phương pháp loại bỏ nền cho quang phổ tia gamma trùng khớp đa chiều. Các công cụ và phương pháp hạt nhân trong nghiên cứu vật lý A 401 (1997) 113-132.
  2. M.Morhac et al.: Hiệu quả giải mã vàng một và hai chiều và ứng dụng của nó vào phân rã phổ tia gamma. Các công cụ và phương pháp hạt nhân trong nghiên cứu vật lý A 401 (1997) 385-408.
  3. M.Morhac et al.: Xác định các đỉnh trong quang phổ tia gamma trùng khớp đa chiều. Dụng cụ và phương pháp hạt nhân trong nghiên cứu Vật lý A 443 (2000), 108-125.

... Và đối với những người không có quyền truy cập vào đăng ký vào NIM:


Để xem lướt qua bài viết, nó dường như mô tả quá trình xử lý dữ liệu giống như những gì tôi đang cố gắng ở đây, tuy nhiên tôi sợ nó vượt qua các kỹ năng lập trình của tôi rất nhiều :(
Ivo Flipse

@Ivo: Tôi chưa bao giờ thử tự mình thực hiện nó. Tôi chỉ sử dụng ROOT. Có các ràng buộc python, không hơn không kém, nhưng lưu ý rằng ROOT là một gói khá nặng.
dmckee --- ex-moderator mèo con

@Ivo Flipse: Tôi đồng ý với dmckee. Bạn có rất nhiều khách hàng tiềm năng trong các câu trả lời khác. Nếu tất cả đều thất bại và bạn cảm thấy muốn đầu tư một chút thời gian, bạn có thể đào sâu vào ROOT và nó (có thể) sẽ làm những gì bạn cần. Tôi chưa từng biết ai đã cố gắng học ROOT thông qua các ràng buộc python (chứ không phải là C ++ tự nhiên), vì vậy tôi chúc bạn may mắn.
vật lý học

13

Đây là một ý tưởng: bạn tính toán Laplacian (rời rạc) của hình ảnh. Tôi hy vọng nó sẽ lớn (âm và) ở cực đại, theo cách ấn tượng hơn so với ảnh gốc. Do đó, cực đại có thể dễ dàng tìm thấy hơn.

Đây là một ý tưởng khác: nếu bạn biết kích thước điển hình của các điểm áp suất cao, trước tiên bạn có thể làm mịn hình ảnh của mình bằng cách kết hợp nó với một Gaussian có cùng kích thước. Điều này có thể cung cấp cho bạn hình ảnh đơn giản hơn để xử lý.


11

Chỉ cần một vài ý tưởng ngoài đỉnh đầu của tôi:

  • lấy gradient (đạo hàm) của quá trình quét, xem điều đó có loại bỏ các cuộc gọi sai không
  • lấy cực đại của cực đại cục bộ

Bạn cũng có thể muốn xem OpenCV , nó có API Python khá tốt và có thể có một số chức năng bạn thấy hữu ích.


Với độ dốc, ý bạn là tôi nên tính độ dốc của độ dốc, một khi giá trị này vượt quá một giá trị nhất định tôi biết có "đỉnh"? Tôi đã thử điều này, nhưng một số ngón chân chỉ có các đỉnh rất thấp (1,2 N / cm) so với một số ngón chân khác (8 N / cm). Vậy làm thế nào tôi nên xử lý các đỉnh với độ dốc rất thấp?
Ivo Flipse

2
Điều gì đã làm việc cho tôi trong quá khứ nếu tôi không thể sử dụng trực tiếp độ dốc là để xem độ dốc và cực đại, ví dụ: nếu độ dốc là một điểm cực trị cục bộ và tôi đang ở cực đại cục bộ, thì tôi đang ở điểm quan tâm.
ChrisC

11

Tôi chắc chắn bây giờ bạn đã có đủ để tiếp tục, nhưng tôi không thể không đề xuất sử dụng phương pháp phân cụm k-nghĩa. k-mean là một thuật toán phân cụm không giám sát sẽ đưa bạn dữ liệu (theo bất kỳ số lượng kích thước nào - tôi tình cờ thực hiện điều này trong 3D) và sắp xếp nó thành các cụm k với các ranh giới riêng biệt. Ở đây thật tuyệt vì bạn biết chính xác có bao nhiêu ngón chân mà những chiếc răng nanh này nên có.

Ngoài ra, nó được triển khai trong Scipy, điều này thực sự tốt ( http://docs.scipy.org/doc/scipy/reference/cluster.vq.html ).

Đây là một ví dụ về những gì nó có thể làm để giải quyết các cụm 3D: nhập mô tả hình ảnh ở đây

Những gì bạn muốn làm là một chút khác biệt (2D và bao gồm các giá trị áp lực), nhưng tôi vẫn nghĩ rằng bạn có thể cho nó một shot.


10

cảm ơn dữ liệu thô Tôi đang ở trên tàu và điều này là xa như tôi đã nhận được (điểm dừng của tôi đang đến). Tôi đã mát xa tệp txt của bạn bằng regexps và đã đưa nó vào một trang html với một số javascript để trực quan hóa. Tôi đang chia sẻ nó ở đây bởi vì một số người, giống như tôi, có thể thấy nó dễ bị hack hơn python.

Tôi nghĩ rằng một cách tiếp cận tốt sẽ là quy mô và bất biến xoay vòng, và bước tiếp theo của tôi sẽ là điều tra các hỗn hợp của gaussian. (mỗi bàn chân là trung tâm của một gaussian).

    <html>
<head>
    <script type="text/javascript" src="http://vis.stanford.edu/protovis/protovis-r3.2.js"></script> 
    <script type="text/javascript">
    var heatmap = [[[0,0,0,0,0,0,0,4,4,0,0,0,0],
[0,0,0,0,0,7,14,22,18,7,0,0,0],
[0,0,0,0,11,40,65,43,18,7,0,0,0],
[0,0,0,0,14,61,72,32,7,4,11,14,4],
[0,7,14,11,7,22,25,11,4,14,65,72,14],
[4,29,79,54,14,7,4,11,18,29,79,83,18],
[0,18,54,32,18,43,36,29,61,76,25,18,4],
[0,4,7,7,25,90,79,36,79,90,22,0,0],
[0,0,0,0,11,47,40,14,29,36,7,0,0],
[0,0,0,0,4,7,7,4,4,4,0,0,0]
],[
[0,0,0,4,4,0,0,0,0,0,0,0,0],
[0,0,11,18,18,7,0,0,0,0,0,0,0],
[0,4,29,47,29,7,0,4,4,0,0,0,0],
[0,0,11,29,29,7,7,22,25,7,0,0,0],
[0,0,0,4,4,4,14,61,83,22,0,0,0],
[4,7,4,4,4,4,14,32,25,7,0,0,0],
[4,11,7,14,25,25,47,79,32,4,0,0,0],
[0,4,4,22,58,40,29,86,36,4,0,0,0],
[0,0,0,7,18,14,7,18,7,0,0,0,0],
[0,0,0,0,4,4,0,0,0,0,0,0,0],
],[
[0,0,0,4,11,11,7,4,0,0,0,0,0],
[0,0,0,4,22,36,32,22,11,4,0,0,0],
[4,11,7,4,11,29,54,50,22,4,0,0,0],
[11,58,43,11,4,11,25,22,11,11,18,7,0],
[11,50,43,18,11,4,4,7,18,61,86,29,4],
[0,11,18,54,58,25,32,50,32,47,54,14,0],
[0,0,14,72,76,40,86,101,32,11,7,4,0],
[0,0,4,22,22,18,47,65,18,0,0,0,0],
[0,0,0,0,4,4,7,11,4,0,0,0,0],
],[
[0,0,0,0,4,4,4,0,0,0,0,0,0],
[0,0,0,4,14,14,18,7,0,0,0,0,0],
[0,0,0,4,14,40,54,22,4,0,0,0,0],
[0,7,11,4,11,32,36,11,0,0,0,0,0],
[4,29,36,11,4,7,7,4,4,0,0,0,0],
[4,25,32,18,7,4,4,4,14,7,0,0,0],
[0,7,36,58,29,14,22,14,18,11,0,0,0],
[0,11,50,68,32,40,61,18,4,4,0,0,0],
[0,4,11,18,18,43,32,7,0,0,0,0,0],
[0,0,0,0,4,7,4,0,0,0,0,0,0],
],[
[0,0,0,0,0,0,4,7,4,0,0,0,0],
[0,0,0,0,4,18,25,32,25,7,0,0,0],
[0,0,0,4,18,65,68,29,11,0,0,0,0],
[0,4,4,4,18,65,54,18,4,7,14,11,0],
[4,22,36,14,4,14,11,7,7,29,79,47,7],
[7,54,76,36,18,14,11,36,40,32,72,36,4],
[4,11,18,18,61,79,36,54,97,40,14,7,0],
[0,0,0,11,58,101,40,47,108,50,7,0,0],
[0,0,0,4,11,25,7,11,22,11,0,0,0],
[0,0,0,0,0,4,0,0,0,0,0,0,0],
],[
[0,0,4,7,4,0,0,0,0,0,0,0,0],
[0,0,11,22,14,4,0,4,0,0,0,0,0],
[0,0,7,18,14,4,4,14,18,4,0,0,0],
[0,4,0,4,4,0,4,32,54,18,0,0,0],
[4,11,7,4,7,7,18,29,22,4,0,0,0],
[7,18,7,22,40,25,50,76,25,4,0,0,0],
[0,4,4,22,61,32,25,54,18,0,0,0,0],
[0,0,0,4,11,7,4,11,4,0,0,0,0],
],[
[0,0,0,0,7,14,11,4,0,0,0,0,0],
[0,0,0,4,18,43,50,32,14,4,0,0,0],
[0,4,11,4,7,29,61,65,43,11,0,0,0],
[4,18,54,25,7,11,32,40,25,7,11,4,0],
[4,36,86,40,11,7,7,7,7,25,58,25,4],
[0,7,18,25,65,40,18,25,22,22,47,18,0],
[0,0,4,32,79,47,43,86,54,11,7,4,0],
[0,0,0,14,32,14,25,61,40,7,0,0,0],
[0,0,0,0,4,4,4,11,7,0,0,0,0],
],[
[0,0,0,0,4,7,11,4,0,0,0,0,0],
[0,4,4,0,4,11,18,11,0,0,0,0,0],
[4,11,11,4,0,4,4,4,0,0,0,0,0],
[4,18,14,7,4,0,0,4,7,7,0,0,0],
[0,7,18,29,14,11,11,7,18,18,4,0,0],
[0,11,43,50,29,43,40,11,4,4,0,0,0],
[0,4,18,25,22,54,40,7,0,0,0,0,0],
[0,0,4,4,4,11,7,0,0,0,0,0,0],
],[
[0,0,0,0,0,7,7,7,7,0,0,0,0],
[0,0,0,0,7,32,32,18,4,0,0,0,0],
[0,0,0,0,11,54,40,14,4,4,22,11,0],
[0,7,14,11,4,14,11,4,4,25,94,50,7],
[4,25,65,43,11,7,4,7,22,25,54,36,7],
[0,7,25,22,29,58,32,25,72,61,14,7,0],
[0,0,4,4,40,115,68,29,83,72,11,0,0],
[0,0,0,0,11,29,18,7,18,14,4,0,0],
[0,0,0,0,0,4,0,0,0,0,0,0,0],
]
];
</script>
</head>
<body>
    <script type="text/javascript+protovis">    
    for (var a=0; a < heatmap.length; a++) {
    var w = heatmap[a][0].length,
    h = heatmap[a].length;
var vis = new pv.Panel()
    .width(w * 6)
    .height(h * 6)
    .strokeStyle("#aaa")
    .lineWidth(4)
    .antialias(true);
vis.add(pv.Image)
    .imageWidth(w)
    .imageHeight(h)
    .image(pv.Scale.linear()
        .domain(0, 99, 100)
        .range("#000", "#fff", '#ff0a0a')
        .by(function(i, j) heatmap[a][j][i]));
vis.render();
}
</script>
  </body>
</html>

văn bản thay thế


1
Tôi cho rằng đây là một bằng chứng về khái niệm rằng các kỹ thuật Gaussian được đề xuất có thể hoạt động, bây giờ nếu chỉ có ai đó có thể chứng minh điều đó với Python ;-)
Ivo Flipse

8

Giải pháp của nhà vật lý:
Xác định 5 điểm đánh dấu xác định bởi vị trí của họ X_ivà khởi tạo chúng với vị trí ngẫu nhiên. Xác định một số chức năng năng lượng kết hợp một số giải thưởng cho vị trí của các điểm đánh dấu ở vị trí của bàn chân với một số hình phạt cho sự chồng chéo của các điểm đánh dấu; hãy cùng nói nào:

E(X_i;S)=-Sum_i(S(X_i))+alfa*Sum_ij (|X_i-Xj|<=2*sqrt(2)?1:0)

( S(X_i)là lực trung bình trong 2x2 vuông xung quanh X_i, alfalà một tham số được đạt đỉnh bằng thực nghiệm)

Bây giờ là lúc để thực hiện một số phép thuật của Metropolis-Hastings:
1. Chọn điểm đánh dấu ngẫu nhiên và di chuyển nó theo một pixel theo hướng ngẫu nhiên.
2. Tính dE, sự khác biệt của năng lượng di chuyển này gây ra.
3. Lấy một số ngẫu nhiên thống nhất từ ​​0-1 và gọi nó là r.
4. Nếu dE<0hoặc exp(-beta*dE)>r, chấp nhận di chuyển và đi đến 1; nếu không, hoàn tác di chuyển và chuyển đến 1.
Điều này nên được lặp lại cho đến khi các điểm đánh dấu sẽ hội tụ đến bàn chân. Beta kiểm soát việc quét để tối ưu hóa sự đánh đổi, do đó, nó cũng nên được tối ưu hóa bằng thực nghiệm; nó cũng có thể được tăng liên tục theo thời gian mô phỏng (mô phỏng ủ).


Quan tâm để cho thấy làm thế nào điều này sẽ làm việc trên ví dụ của tôi? Vì tôi thực sự không học toán cấp cao, nên tôi đã có một thời gian khó khăn để làm sáng tỏ công thức mà bạn đề xuất :(
Ivo Flipse

1
Đây là môn toán cấp ba, có lẽ ký hiệu của tôi chỉ bị xáo trộn. Tôi có một kế hoạch để kiểm tra nó, vì vậy hãy theo dõi.
mbq

4
Tôi là một nhà vật lý hạt. Trong một thời gian dài, công cụ phần mềm chuyển sang môn học của chúng tôi được gọi là PAW và nó có một thực thể liên quan đến các biểu đồ được gọi là "điểm đánh dấu". Bạn có thể tưởng tượng sự khó hiểu của tôi như thế nào khi tôi tìm thấy câu trả lời này trong vài lần đầu tiên xung quanh ...
dmckee --- ex-moderator mèo con

6

Đây là một cách tiếp cận khác mà tôi đã sử dụng khi làm một cái gì đó tương tự cho một kính thiên văn lớn:

1) Tìm kiếm pixel cao nhất. Khi bạn đã có được điều đó, hãy tìm kiếm xung quanh đó để có mức phù hợp nhất cho 2x2 (có thể tối đa hóa tổng số 2x2) hoặc thực hiện một gaussian 2d phù hợp bên trong vùng phụ của 4 x 4 ở giữa pixel cao nhất.

Sau đó, đặt các pixel 2x2 mà bạn đã tìm thấy về 0 (hoặc có thể là 3x3) xung quanh tâm điểm

quay trở lại 1) và lặp lại cho đến khi đỉnh cao nhất rơi xuống dưới ngưỡng tiếng ồn hoặc bạn có tất cả các ngón chân bạn cần


Muốn chia sẻ một ví dụ mã làm điều này? Tôi có thể làm theo những gì bạn đang cố gắng thực hiện, nhưng không biết làm thế nào để tự viết mã
Ivo Flipse

Tôi thực sự đến từ làm việc với Matlab, vì vậy, điều đó đã có ích. Nhưng nếu bạn sử dụng các hàm thực sự lạ, tôi có thể khó tái tạo nó bằng Python
Ivo Flipse

6

Có thể đáng để thử với các mạng thần kinh nếu bạn có thể tạo một số dữ liệu đào tạo ... nhưng điều này cần nhiều mẫu được chú thích bằng tay.


Nếu nó đáng để rắc rối, tôi sẽ không chú thích một mẫu lớn bằng tay. Vấn đề của tôi sẽ là: làm thế nào để tôi thực hiện điều này, vì tôi không biết gì về lập trình mạng thần kinh
Ivo Flipse

6

một phác thảo thô ...

bạn có thể muốn sử dụng một thuật toán thành phần được kết nối để cô lập từng vùng chân. wiki có một mô tả đúng về điều này (với một số mã) ở đây: http://en.wikipedia.org/wiki/Connected_Component_Labeling

bạn sẽ phải đưa ra quyết định về việc nên sử dụng kết nối 4 hoặc 8. cá nhân, đối với hầu hết các vấn đề tôi thích kết nối 6. dù sao đi nữa, một khi bạn đã tách ra từng "dấu chân" như một vùng được kết nối, việc lặp lại qua vùng đó và tìm cực đại là đủ dễ dàng. một khi bạn đã tìm thấy cực đại, bạn có thể phóng to khu vực cho đến khi bạn đạt đến ngưỡng xác định trước để xác định đó là một "ngón chân" nhất định.

Một vấn đề tế nhị ở đây là ngay khi bạn bắt đầu sử dụng các kỹ thuật thị giác máy tính để xác định một cái gì đó là một chân phải / trái / trước / sau và bạn bắt đầu nhìn vào các ngón chân riêng lẻ, bạn phải bắt đầu tính toán xoay, xiên và dịch thuật. điều này được thực hiện thông qua việc phân tích cái gọi là "khoảnh khắc". có một vài khoảnh khắc khác nhau để xem xét trong các ứng dụng tầm nhìn:

khoảnh khắc trung tâm: dịch bất biến khoảnh khắc bình thường: nhân rộng và dịch bất biến khoảnh khắc hu: dịch, tỷ lệ và xoay bất biến

thêm thông tin về các khoảnh khắc có thể được tìm thấy bằng cách tìm kiếm "khoảnh khắc hình ảnh" trên wiki.



4

Có vẻ như bạn có thể gian lận một chút bằng thuật toán của jetxee. Anh ta đang tìm thấy ba ngón chân đầu tiên tốt, và bạn sẽ có thể đoán được nơi thứ tư dựa trên đó.


4

Vấn đề thú vị. Giải pháp tôi sẽ thử là như sau.

  1. Áp dụng bộ lọc thông thấp, chẳng hạn như tích chập với mặt nạ gaussian 2D. Điều này sẽ cung cấp cho bạn một loạt các giá trị (có thể, nhưng không nhất thiết là dấu phẩy động).

  2. Thực hiện triệt tiêu không tối đa 2D bằng cách sử dụng bán kính gần đúng đã biết của mỗi bàn chân (hoặc ngón chân).

Điều này sẽ cung cấp cho bạn các vị trí tối đa mà không có nhiều ứng cử viên gần nhau. Chỉ cần làm rõ, bán kính của mặt nạ ở bước 1 cũng tương tự như bán kính được sử dụng ở bước 2. Bán kính này có thể được lựa chọn hoặc bác sĩ thú y có thể đo lường rõ ràng trước đó (nó sẽ thay đổi theo tuổi / giống / v.v.).

Một số giải pháp được đề xuất (dịch chuyển trung bình, mạng lưới thần kinh, v.v.) có thể sẽ hoạt động ở một mức độ nào đó, nhưng quá phức tạp và có thể không lý tưởng.


Tôi có 0 kinh nghiệm với ma trận tích chập và bộ lọc Gaussian, vậy bạn có muốn chỉ ra cách nó hoạt động trên ví dụ của tôi không?
Ivo Flipse

3

Chà, đây là một số mã đơn giản và không hiệu quả khủng khiếp, nhưng với kích thước của tập dữ liệu này thì nó vẫn ổn.

import numpy as np
grid = np.array([[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
              [0,0,0,0,0,0,0,0,0.4,0.4,0.4,0,0,0],
              [0,0,0,0,0.4,1.4,1.4,1.8,0.7,0,0,0,0,0],
              [0,0,0,0,0.4,1.4,4,5.4,2.2,0.4,0,0,0,0],
              [0,0,0.7,1.1,0.4,1.1,3.2,3.6,1.1,0,0,0,0,0],
              [0,0.4,2.9,3.6,1.1,0.4,0.7,0.7,0.4,0.4,0,0,0,0],
              [0,0.4,2.5,3.2,1.8,0.7,0.4,0.4,0.4,1.4,0.7,0,0,0],
              [0,0,0.7,3.6,5.8,2.9,1.4,2.2,1.4,1.8,1.1,0,0,0],
              [0,0,1.1,5,6.8,3.2,4,6.1,1.8,0.4,0.4,0,0,0],
              [0,0,0.4,1.1,1.8,1.8,4.3,3.2,0.7,0,0,0,0,0],
              [0,0,0,0,0,0.4,0.7,0.4,0,0,0,0,0,0]])

arr = []
for i in xrange(grid.shape[0] - 1):
    for j in xrange(grid.shape[1] - 1):
        tot = grid[i][j] + grid[i+1][j] + grid[i][j+1] + grid[i+1][j+1]
        arr.append([(i,j),tot])

best = []

arr.sort(key = lambda x: x[1])

for i in xrange(5):
    best.append(arr.pop())
    badpos = set([(best[-1][0][0]+x,best[-1][0][1]+y)
                  for x in [-1,0,1] for y in [-1,0,1] if x != 0 or y != 0])
    for j in xrange(len(arr)-1,-1,-1):
        if arr[j][0] in badpos:
            arr.pop(j)


for item in best:
    print grid[item[0][0]:item[0][0]+2,item[0][1]:item[0][1]+2]

Về cơ bản, tôi chỉ tạo một mảng với vị trí của phía trên bên trái và tổng của mỗi hình vuông 2x2 và sắp xếp nó theo tổng. Sau đó, tôi lấy hình vuông 2x2 với tổng số cao nhất ra khỏi sự tranh chấp, đặt nó vào bestmảng và loại bỏ tất cả các hình vuông 2x2 khác sử dụng bất kỳ phần nào của hình vuông này vừa loại bỏ hình vuông 2x2.

Nó dường như hoạt động tốt, ngoại trừ với chân cuối cùng (cái có tổng nhỏ nhất ở bên phải trong bức ảnh đầu tiên của bạn), hóa ra có hai hình vuông 2x2 đủ điều kiện khác với tổng lớn hơn (và chúng có tổng bằng nhau lẫn nhau). Một trong số họ vẫn chọn một hình vuông từ hình vuông 2x2 của bạn, nhưng cái còn lại ở bên trái. May mắn thay, may mắn thay, chúng tôi thấy sẽ chọn được nhiều thứ bạn muốn, nhưng điều này có thể yêu cầu một số ý tưởng khác được sử dụng để có được những gì bạn thực sự muốn mọi lúc.


Tôi cho rằng kết quả của bạn giống như kết quả trong câu trả lời của @ Jextee. Hoặc ít nhất vì vậy có vẻ như từ tôi thử nghiệm nó.
Ivo Flipse


1

Có lẽ một cách tiếp cận ngây thơ là đủ ở đây: Xây dựng một danh sách tất cả các hình vuông 2x2 trên máy bay của bạn, sắp xếp chúng theo tổng của chúng (theo thứ tự giảm dần).

Đầu tiên, chọn hình vuông có giá trị cao nhất vào "danh sách chân" của bạn. Sau đó, lặp đi lặp lại chọn 4 trong số các hình vuông tốt nhất tiếp theo không giao nhau với bất kỳ hình vuông nào được tìm thấy trước đó.


Tôi thực sự đã lập một danh sách với tất cả các khoản tiền 2x2, nhưng khi tôi ra lệnh, tôi không biết làm thế nào để so sánh chúng. Vấn đề của tôi là khi tôi sắp xếp nó, tôi đã mất dấu tọa độ. Có lẽ tôi có thể dán chúng trong một từ điển, với tọa độ là chìa khóa.
Ivo Flipse

Vâng, một số loại từ điển sẽ là cần thiết. Tôi đã có thể giả định rằng đại diện của bạn của lưới là một số loại từ điển.
Julian Charra

Vâng, hình ảnh bạn nhìn thấy ở trên là một mảng numpy. Phần còn lại hiện được lưu trữ trong danh sách đa chiều. Có lẽ sẽ tốt hơn nếu ngừng làm điều đó, mặc dù tôi không quen với việc lặp lại từ điển
Ivo Flipse

1

Có một số phần mềm rộng lớn có sẵn từ cộng đồng thiên văn học và vũ trụ học - đây là một lĩnh vực nghiên cứu quan trọng cả trong lịch sử và hiện tại.

Đừng hoảng hốt nếu bạn không phải là nhà thiên văn học - một số dễ sử dụng ngoài lĩnh vực này. Ví dụ: bạn có thể sử dụng astropy / photutils:

https://photutils.readthedocs.io/en/urdy/detection.html#local-peak-detection

[Có vẻ hơi thô lỗ khi lặp lại mã mẫu ngắn của họ ở đây.]

Một danh sách các kỹ thuật / gói / liên kết không đầy đủ và hơi thiên vị có thể được quan tâm được đưa ra dưới đây - hãy thêm nhiều hơn trong các ý kiến ​​và tôi sẽ cập nhật câu trả lời này khi cần thiết. Tất nhiên, có sự đánh đổi về độ chính xác so với tài nguyên tính toán. [Thành thật mà nói, có quá nhiều để đưa ra các ví dụ mã trong một câu trả lời duy nhất như vậy nên tôi không chắc câu trả lời này có bay hay không.]

Trình trích xuất nguồn https://www.astromatic.net/software/sextractor

MultiNest https://github.com/farhanferoz/MultiNest [+ pyMultiNest]

Thử thách tìm nguồn ASKAP / EMU: https://arxiv.org/abs/1509.03931

Bạn cũng có thể tìm kiếm các thách thức trích xuất nguồn Planck và / hoặc WMAP.

...


0

Điều gì sẽ xảy ra nếu bạn tiến hành từng bước: trước tiên bạn xác định vị trí tối đa toàn cầu, xử lý nếu cần các điểm xung quanh cho giá trị của chúng, sau đó đặt vùng tìm thấy về 0 và lặp lại cho điểm tiếp theo.


Hmmm, cài đặt về 0 ít nhất sẽ loại bỏ nó khỏi mọi tính toán tiếp theo, điều đó sẽ hữu ích.
Ivo Flipse

Thay vì đặt thành 0, bạn có thể tính hàm gaussian với các tham số được chọn bằng tay và trừ các giá trị tìm thấy khỏi giá trị áp suất ban đầu. Vì vậy, nếu ngón chân đang nhấn các cảm biến của bạn, thì bằng cách tìm điểm nhấn cao nhất, bạn sử dụng nó để giảm tác động của ngón chân đó lên các cảm biến, do đó, loại bỏ các tế bào lân cận bằng các giá trị áp suất cao. vi.wikipedia.org/wiki/File:Gaussian_2d.png
Daniyar

Muốn hiển thị một ví dụ dựa trên dữ liệu mẫu của tôi @Daniyar? Vì tôi thực sự không quen thuộc với kiểu xử lý dữ liệu như vậy
Ivo Flipse

0

Tôi không chắc điều này trả lời câu hỏi, nhưng có vẻ như bạn chỉ có thể tìm kiếm n đỉnh cao nhất không có hàng xóm.

Đây là ý chính. Lưu ý rằng đó là trong Ruby, nhưng ý tưởng nên rõ ràng.

require 'pp'

NUM_PEAKS = 5
NEIGHBOR_DISTANCE = 1

data = [[1,2,3,4,5],
        [2,6,4,4,6],
        [3,6,7,4,3],
       ]

def tuples(matrix)
  tuples = []
  matrix.each_with_index { |row, ri|
    row.each_with_index { |value, ci|
      tuples << [value, ri, ci]
    }
  }
  tuples
end

def neighbor?(t1, t2, distance = 1)
  [1,2].each { |axis|
    return false if (t1[axis] - t2[axis]).abs > distance
  }
  true
end

# convert the matrix into a sorted list of tuples (value, row, col), highest peaks first
sorted = tuples(data).sort_by { |tuple| tuple.first }.reverse

# the list of peaks that don't have neighbors
non_neighboring_peaks = []

sorted.each { |candidate|
  # always take the highest peak
  if non_neighboring_peaks.empty?
    non_neighboring_peaks << candidate
    puts "took the first peak: #{candidate}"
  else
    # check that this candidate doesn't have any accepted neighbors
    is_ok = true
    non_neighboring_peaks.each { |accepted|
      if neighbor?(candidate, accepted, NEIGHBOR_DISTANCE)
        is_ok = false
        break
      end
    }
    if is_ok
      non_neighboring_peaks << candidate
      puts "took #{candidate}"
    else
      puts "denied #{candidate}"
    end
  end
}

pp non_neighboring_peaks

Tôi sẽ thử và xem thử xem tôi có thể chuyển đổi nó thành mã Python không :-)
Ivo Flipse

Vui lòng bao gồm mã trong chính bài đăng, thay vì liên kết với ý chính, nếu đó là độ dài hợp lý.
agf
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.