การตรวจจับจุดสูงสุดในอาร์เรย์ 2D


874

ฉันกำลังช่วยคลินิกสัตวแพทย์ในการวัดความดันภายใต้อุ้งเท้าสุนัข ฉันใช้ Python สำหรับการวิเคราะห์ข้อมูลของฉันและตอนนี้ฉันกำลังพยายามแบ่งอุ้งเท้าออกเป็นส่วนย่อย (กายวิภาค)

ฉันสร้างอาร์เรย์สองมิติของอุ้งเท้าแต่ละตัวซึ่งประกอบด้วยค่าสูงสุดสำหรับเซ็นเซอร์แต่ละตัวที่อุ้งมือเมื่อเวลาผ่านไป นี่คือตัวอย่างของอุ้งเท้าหนึ่งซึ่งฉันใช้ Excel เพื่อวาดพื้นที่ที่ฉันต้องการ 'ตรวจสอบ' กล่องเหล่านี้มีขนาด 2 x 2 รอบเซ็นเซอร์พร้อม maxima ท้องถิ่นซึ่งมีขนาดใหญ่ที่สุด

ข้อความแสดงแทน

ดังนั้นฉันจึงลองทำการทดลองและตัดสินใจที่จะมองหาค่าสูงสุดของแต่ละคอลัมน์และแถว (ไม่สามารถมองในทิศทางเดียวเนื่องจากรูปร่างของอุ้งเท้า) ดูเหมือนว่า 'ตรวจจับ' ตำแหน่งของนิ้วเท้าแยกจากกันค่อนข้างดี แต่มันก็ทำเครื่องหมายเซ็นเซอร์ที่อยู่ใกล้เคียง

ข้อความแสดงแทน

ดังนั้นจะเป็นวิธีที่ดีที่สุดในการบอก Python ว่าค่าสูงสุดเหล่านี้คือสิ่งที่ฉันต้องการหรือไม่

หมายเหตุ: สี่เหลี่ยม 2x2 ไม่สามารถซ้อนทับกันได้เนื่องจากจะต้องแยกนิ้วเท้าออก!

นอกจากนี้ฉันยังใช้ 2x2 เพื่ออำนวยความสะดวกอีกทั้งยังยินดีต้อนรับวิธีแก้ปัญหาขั้นสูงอีกด้วย แต่ฉันเป็นเพียงนักวิทยาศาสตร์การเคลื่อนไหวของมนุษย์ดังนั้นฉันจึงไม่ใช่โปรแกรมเมอร์หรือนักคณิตศาสตร์ที่แท้จริงดังนั้นโปรดทำให้มันง่าย

นี่คือรุ่นที่สามารถโหลดได้np.loadtxt


ผล

ดังนั้นฉันจึงลองวิธีแก้ปัญหาของ @ jextee (ดูผลลัพธ์ด้านล่าง) อย่างที่คุณเห็นมันทำงานได้ดีบนอุ้งเท้าหน้า แต่มันทำงานได้ไม่ดีนักสำหรับขาหลัง

โดยเฉพาะอย่างยิ่งมันไม่สามารถจดจำจุดสูงสุดเล็ก ๆ นั่นคือนิ้วเท้าที่สี่ เห็นได้ชัดว่านี่เป็นสิ่งที่เกิดขึ้นจริงจากการที่ลูปดูจากบนลงล่างถึงค่าต่ำสุดโดยไม่คำนึงถึงว่ามันอยู่ที่ไหน

มีใครบ้างที่รู้วิธีปรับแต่งอัลกอริทึมของ @ jextee เพื่อที่จะสามารถหานิ้วเท้าที่ 4 ด้วย

ข้อความแสดงแทน

เนื่องจากฉันยังไม่ได้ประมวลผลการทดลองอื่นฉันจึงไม่สามารถจัดหาตัวอย่างอื่นได้ แต่ข้อมูลที่ฉันให้ไว้ก่อนหน้านี้คือค่าเฉลี่ยของอุ้งเท้าแต่ละตัว ไฟล์นี้เป็นอาร์เรย์ที่มีข้อมูลมากที่สุดคือ 9 paws ตามลำดับที่พวกเขาทำการติดต่อกับ plate

ภาพนี้แสดงให้เห็นว่าพวกมันกระจายไปทั่วจานอย่างไร

ข้อความแสดงแทน

ปรับปรุง:

ฉันได้ตั้งค่าบล็อกสำหรับทุกคนที่สนใจและฉันได้ติดตั้ง SkyDrive ด้วยการวัดแบบดิบทั้งหมด ดังนั้นสำหรับทุกคนที่ขอข้อมูลเพิ่มเติม: มีพลังมากขึ้นสำหรับคุณ!


อัพเดทใหม่:

ดังนั้นหลังจากที่ฉันได้รับคำถามเกี่ยวกับการตรวจจับอุ้งเท้าและการเรียงอุ้งเท้าในที่สุดฉันก็สามารถตรวจจับนิ้วเท้าทุกอุ้งเท้าได้! กลับกลายเป็นว่ามันทำงานได้ไม่ดีนักในทุกอย่างยกเว้นอุ้งเท้าขนาดเท่าตัวอย่างของฉันเอง ในการเข้าใจถึงปัญหาหลังเหตุการณ์มันเป็นความผิดของตัวเองในการเลือก 2x2 โดยพลการ

นี่เป็นตัวอย่างที่ดีว่าเกิดอะไรขึ้น: เล็บได้รับการยอมรับว่าเป็นนิ้วเท้าและ 'ส้นเท้า' กว้างมากจนได้รับการยอมรับสองครั้ง!

ข้อความแสดงแทน

อุ้งเท้าใหญ่เกินไปดังนั้นการยึดขนาด 2x2 โดยไม่มีการเหลื่อมกันทำให้นิ้วเท้าบางคู่ถูกตรวจจับสองครั้ง อีกวิธีหนึ่งในสุนัขตัวเล็ก ๆ มักจะล้มเหลวในการหานิ้วเท้าที่ 5 ซึ่งฉันสงสัยว่าเกิดจากพื้นที่ 2x2 มีขนาดใหญ่เกินไป

หลังจากลองใช้วิธีแก้ปัญหาในปัจจุบันกับการวัดทั้งหมดของฉันฉันได้ข้อสรุปที่ส่ายว่าสำหรับสุนัขตัวเล็กเกือบทั้งหมดของฉันมันไม่พบที่นิ้วเท้าที่ 5 และในกว่า 50% ของผลกระทบสำหรับสุนัขขนาดใหญ่

เห็นได้ชัดว่าฉันต้องเปลี่ยน ฉันคิดว่าตัวเองกำลังเปลี่ยนขนาดของneighborhoodสิ่งที่เล็กกว่าสำหรับสุนัขตัวเล็กและใหญ่กว่าสำหรับสุนัขตัวใหญ่ แต่generate_binary_structureจะไม่ให้ฉันเปลี่ยนขนาดของอาเรย์

ดังนั้นฉันหวังว่าคนอื่นจะมีข้อเสนอแนะที่ดีกว่าสำหรับการค้นหานิ้วเท้าอาจมีขนาดพื้นที่นิ้วเท้าที่มีขนาดอุ้งเท้า?


ฉันคิดว่าเครื่องหมายจุลภาคเป็นทศนิยมมากกว่าตัวคั่นค่าหรือไม่
MattH

ใช่พวกเขาเป็นจุลภาค และ @ Christian ฉันพยายามที่จะทำให้มันเป็นไฟล์ที่อ่านง่าย แต่ถึงอย่างนั้นฉันก็ไม่สามารถ :(
Ivo Flipse

3
ในขณะที่ฉันกำลังศึกษาความเป็นไปได้ไม่มีอะไรเป็นจริง ดังนั้นฉันกำลังมองหาวิธีกำหนดความดันได้หลายวิธีรวมถึงอนุภูมิภาค นอกจากนี้ฉันยังต้องสามารถแยกแยะระหว่างด้าน 'บิ๊กเขย' และ 'ลิตเติ้ลโท๊ต' เพื่อประเมินการวางแนว แต่เนื่องจากสิ่งนี้ยังไม่เคยทำมาก่อนไม่มีการบอกสิ่งที่เราอาจพบ :-)
Ivo Flipse

2
@Ron: หนึ่งในเป้าหมายของการศึกษานี้คือการดูว่าสุนัขมีขนาด / น้ำหนักของระบบที่เหมาะสมดังนั้นใช่ในขณะที่สุนัขตัวนี้มีน้ำหนักประมาณ 20 กิโลกรัม ฉันมีบางอย่างที่เล็กกว่า (และใหญ่กว่า) และคาดหวังว่าฉันจะไม่สามารถทำสิ่งเดียวกันกับของจริงได้
Ivo Flipse

2
@ Frank อุ้งเท้าวัดตลอดเวลาดังนั้นมิติที่ 3 อย่างไรก็ตามพวกเขาไม่ย้ายจากจุดของพวกเขา (พูดค่อนข้าง) ดังนั้นฉันส่วนใหญ่ให้ความสนใจที่เท้าตั้งอยู่ในแบบ 2D มุมมอง 3 มิติฟรีหลังจากนั้น
Ivo Flipse

คำตอบ:


331

ผมตรวจพบยอดโดยใช้ตัวกรองสูงสุดท้องถิ่น นี่คือผลลัพธ์ในชุดข้อมูลชุดแรกของคุณที่มี 4 paws: ผลการตรวจสอบจุดสูงสุด

ฉันยังวิ่งในชุดที่สองของ 9 อุ้งเท้าและมันทำงานได้เป็นอย่างดี

นี่คือวิธีที่คุณทำ:

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()

สิ่งที่คุณต้องทำหลังจากใช้งานscipy.ndimage.measurements.labelบนมาสก์เพื่อติดฉลากวัตถุที่แตกต่างกันทั้งหมด จากนั้นคุณจะสามารถเล่นกับพวกเขาทีละคน

โปรดทราบว่าวิธีการทำงานได้ดีเพราะพื้นหลังไม่ดัง หากเป็นเช่นนั้นคุณจะตรวจพบจุดยอดที่ไม่ต้องการอื่น ๆ ในพื้นหลัง อีกปัจจัยที่สำคัญคือขนาดของพื้นที่ใกล้เคียง คุณจะต้องปรับหากขนาดสูงสุดเปลี่ยนไป (ควรอยู่ในสัดส่วนโดยประมาณ)


1
มีวิธีที่ง่ายกว่า (eroded_background ^ local_peaks) ทำแค่ (เบื้องหน้า & ยอดเขาท้องถิ่น)
Ryan Soklaski

53

สารละลาย

แฟ้มข้อมูล: paw.txt รหัสแหล่งที่มา:

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"

เอาต์พุตโดยไม่มีสี่เหลี่ยมที่ทับซ้อนกัน ดูเหมือนว่าจะเลือกพื้นที่เดียวกันในตัวอย่างของคุณ

ความคิดเห็นบางส่วน

ส่วนที่ยุ่งยากคือการคำนวณผลบวกของ 2x2 กำลังสองทั้งหมด ฉันคิดว่าคุณต้องการทั้งหมดดังนั้นจึงอาจมีบางอย่างทับซ้อนกัน ฉันใช้สไลซ์เพื่อตัดคอลัมน์และแถวแรก / สุดท้ายจากอาร์เรย์ 2D เดิมจากนั้นซ้อนทับพวกเขาทั้งหมดเข้าด้วยกันและคำนวณผลรวม

เพื่อให้เข้าใจได้ดีขึ้นให้ทำภาพอาเรย์ 3x3:

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

จากนั้นคุณสามารถใช้ชิ้น:

>>> 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]])

ทีนี้ลองนึกภาพว่าคุณสแตกพวกมันหนึ่งตัวเหนือองค์ประกอบอื่น ๆ ผลรวมเหล่านี้จะเป็นผลรวมเดียวกันกับสี่เหลี่ยม 2x2 ที่มีมุมซ้ายบนในตำแหน่งเดียวกัน:

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

เมื่อคุณมีผลรวมมากกว่า 2x2 สี่เหลี่ยมคุณสามารถใช้maxเพื่อหาค่าสูงสุดหรือsortหรือsortedเพื่อหาจุดสูงสุด

เพื่อจดจำตำแหน่งของจุดสูงสุดฉันจับคู่ทุกค่า (ผลรวม) กับตำแหน่งที่เป็นลำดับในอาเรย์แบน (ดูzip) จากนั้นฉันคำนวณตำแหน่งแถว / คอลัมน์อีกครั้งเมื่อฉันพิมพ์ผลลัพธ์

หมายเหตุ

ฉันอนุญาตให้ 2x2 กำลังสองทับกัน เวอร์ชันที่แก้ไขจะกรองบางส่วนออกเพื่อให้มีเพียงสี่เหลี่ยมที่ไม่ทับซ้อนกันเท่านั้นที่ปรากฏในผลลัพธ์

การเลือกนิ้ว (ความคิด)

ปัญหาอีกประการคือวิธีเลือกสิ่งที่น่าจะเป็นนิ้วออกจากยอดเขาทั้งหมด ฉันมีความคิดที่อาจหรืออาจจะไม่ทำงาน ฉันไม่มีเวลาที่จะใช้มันในตอนนี้ดังนั้นแค่หลอกโค้ด

ฉันสังเกตเห็นว่าถ้านิ้วด้านหน้าอยู่ในวงกลมที่เกือบสมบูรณ์แบบนิ้วด้านหลังควรอยู่ในวงกลมนั้น นอกจากนี้นิ้วด้านหน้าจะเว้นระยะห่างกันไม่มากก็น้อย เราอาจพยายามใช้คุณสมบัติแก้ปัญหาเหล่านี้เพื่อตรวจจับนิ้วมือ

รหัสหลอก:

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

นี่เป็นวิธีการที่โหดร้าย ถ้า N มีขนาดค่อนข้างเล็กฉันก็คิดว่ามันใช้ได้ สำหรับ N = 12 มีชุดค่า C_12 ^ 5 = 792 ครั้งคูณ 5 วิธีในการเลือกนิ้วหลังดังนั้น 3960 รายที่จะประเมินสำหรับอุ้งมือทุกตัว


เขาจะต้องกรองอุ้งเท้าด้วยตนเองให้กับรายการผลลัพธ์ของคุณ ... การเลือกผลลัพธ์สูงสุดสี่รายการจะทำให้เขามีความเป็นไปได้สี่ทางในการสร้าง 2x2 สแควร์ที่มีค่าสูงสุด 6.8
Johannes Charra

กล่อง 2x2 ไม่สามารถซ้อนทับกันได้เนื่องจากถ้าฉันต้องการทำสถิติฉันไม่ต้องการใช้พื้นที่เดียวกันฉันต้องการเปรียบเทียบภูมิภาค :-)
Ivo Flipse

ฉันแก้ไขคำตอบ ขณะนี้ไม่มีสี่เหลี่ยมที่ทับซ้อนกันในผลลัพธ์
sastanin

1
ฉันลองแล้วดูเหมือนว่ามันจะใช้ได้กับอุ้งเท้าหน้า แต่ก็น้อยกว่าสำหรับพวกหลัง เดาว่าเราจะต้องลองสิ่งที่รู้ว่าจะต้องดูที่ไหน
Ivo Flipse

1
ฉันอธิบายความคิดของฉันว่านิ้วมือสามารถตรวจจับได้ในรหัสหลอก ถ้าคุณชอบฉันอาจลองใช้ตอนเย็นพรุ่งนี้
sastanin

34

นี่คือปัญหาการลงทะเบียนภาพ กลยุทธ์ทั่วไปคือ:

  • มีตัวอย่างที่รู้จักกันหรือชนิดของบางอย่างก่อนที่ข้อมูลที่
  • ใส่ข้อมูลของคุณให้ตรงกับตัวอย่างหรือใส่ตัวอย่างลงในข้อมูลของคุณ
  • ช่วยถ้าข้อมูลของคุณถูกจัดตำแหน่งอย่างคร่าวๆในตอนแรก

นี่เป็นวิธีที่คร่าวๆและพร้อมใช้งาน "สิ่งที่โง่ที่สุดที่อาจเป็นไปได้":

  • เริ่มด้วยพิกัดห้านิ้วในสถานที่ที่คุณคาดหวัง
  • เมื่อปีนขึ้นไปบนยอดเขาบ่อยๆ เช่นได้รับตำแหน่งปัจจุบันย้ายไปยังพิกเซลข้างเคียงสูงสุดหากค่ามากกว่าพิกเซลปัจจุบัน หยุดเมื่อพิกัดนิ้วเท้าของคุณหยุดเคลื่อนไหว

หากต้องการแก้ไขปัญหาการวางแนวคุณสามารถตั้งค่าเริ่มต้นได้ 8 หรือมากกว่านั้นสำหรับทิศทางพื้นฐาน (เหนือ, ตะวันออกเฉียงเหนือ, ฯลฯ ) เรียกใช้แต่ละรายการแยกกันและทิ้งผลลัพธ์ใด ๆ ที่มีสองนิ้วหรือมากกว่านั้นสิ้นสุดที่พิกเซลเดียวกัน ฉันจะคิดอีกมากกว่านี้ แต่สิ่งนี้ยังคงถูกวิจัยในการประมวลผลภาพ - ไม่มีคำตอบที่ถูกต้อง!

แนวคิดที่ซับซ้อนมากขึ้นเล็กน้อย: (ถ่วงน้ำหนัก) K- หมายถึงการรวมกลุ่ม มันไม่ได้แย่ขนาดนั้น

  • เริ่มต้นด้วยห้า toe toe แต่ตอนนี้เหล่านี้เป็น "ศูนย์ศูนย์"

จากนั้นวนซ้ำจนกว่าการบรรจบกัน:

  • กำหนดแต่ละพิกเซลให้กับคลัสเตอร์ที่ใกล้เคียงที่สุด (เพียงทำรายการสำหรับแต่ละคลัสเตอร์)
  • คำนวณจุดศูนย์กลางมวลของแต่ละกลุ่ม สำหรับแต่ละคลัสเตอร์นี่คือ: ผลรวม (ค่าพิกัดความเข้ม *) / ผลรวม (พิกัด)
  • ย้ายแต่ละคลัสเตอร์ไปยังจุดศูนย์กลางมวลใหม่

วิธีนี้จะให้ผลลัพธ์ที่ดีกว่าและคุณจะได้รับมวลของแต่ละคลัสเตอร์ซึ่งอาจช่วยในการระบุนิ้วเท้า

(อีกครั้งคุณได้ระบุจำนวนของคลัสเตอร์ไว้ล่วงหน้าด้วยการทำคลัสเตอร์คุณต้องระบุความหนาแน่นไม่ทางใดก็ทางหนึ่ง: เลือกจำนวนของกลุ่มที่เหมาะสมในกรณีนี้หรือเลือกรัศมีของคลัสเตอร์และดูจำนวนที่สิ้นสุด ขึ้นกับ. ตัวอย่างของสิ่งหลังคือmean-shift .)

ขออภัยเกี่ยวกับการขาดรายละเอียดการใช้งานหรือข้อมูลเฉพาะอื่น ๆ ฉันต้องการโค้ดนี้ แต่ฉันมีกำหนดเวลา หากไม่มีอะไรทำงานได้ภายในสัปดาห์หน้าให้ฉันรู้และฉันจะให้มันยิง


1
ปัญหาคือว่าอุ้งเท้าเปลี่ยนการวางแนวของพวกเขาและฉันไม่มีการสอบเทียบ / พื้นฐานของอุ้งเท้าที่ถูกต้องที่จะเริ่มต้นด้วย นอกจากนี้ฉันกลัวว่าอัลกอริธึมการจดจำภาพจำนวนมากออกมาจากลีกของฉันเล็กน้อย
Ivo Flipse

วิธีการ "หยาบและพร้อม" นั้นค่อนข้างเรียบง่าย - บางทีฉันอาจจะไม่เข้าใจ ฉันจะใส่ใน pseudocode เพื่อแสดง
CakeMaster

ฉันมีความรู้สึกข้อเสนอแนะของคุณจะช่วยแก้ไขการรับรู้ของอุ้งมือหลังฉันก็ไม่ทราบว่า 'อย่างไร'
Ivo Flipse

ฉันได้เพิ่มแนวคิดอื่น ยังไงก็ตามถ้าคุณมีข้อมูลจำนวนมากมันจะเจ๋งที่จะทำให้มันออนไลน์อยู่ที่ไหนซักแห่ง มันจะมีประโยชน์สำหรับคนที่เรียนรู้เกี่ยวกับการประมวลผลภาพ / การเรียนรู้ของเครื่องและคุณอาจได้รับโค้ดเพิ่มเติมจากมัน ...
CakeMaster

1
ฉันแค่คิดเกี่ยวกับการเขียนการประมวลผลข้อมูลของฉันลงในบล็อก Wordpress ง่ายๆเพียงเพื่อใช้สำหรับคนอื่นและฉันต้องเขียนมันต่อไป ฉันชอบคำแนะนำของคุณทั้งหมด แต่ฉันเกรงว่าฉันจะต้องรอใครซักคนโดยไม่มีกำหนด ;-)
Ivo Flipse

18

ใช้ homology แบบถาวรเพื่อวิเคราะห์ชุดข้อมูลของคุณฉันได้รับผลลัพธ์ต่อไปนี้ (คลิกเพื่อดูภาพขยาย):

ผลลัพธ์

นี่เป็นเวอร์ชัน 2 มิติของวิธีการตรวจจับสูงสุดที่อธิบายไว้ในคำตอบ SOนี้ รูปด้านบนแสดงคลาส homology แบบ 0 มิติที่เรียงตามการคงอยู่

ฉันอัปเกรดชุดข้อมูลดั้งเดิมด้วยค่า 2 โดยใช้ scipy.misc.imresize () อย่างไรก็ตามโปรดทราบว่าฉันได้พิจารณาสี่อุ้งมือเป็นชุดข้อมูลเดียว การแยกออกเป็นสี่จะทำให้ปัญหาง่ายขึ้น

ระเบียบวิธี แนวคิดเบื้องหลังเรื่องนี้ค่อนข้างง่าย: พิจารณากราฟฟังก์ชั่นของฟังก์ชั่นที่กำหนดระดับของแต่ละพิกเซล ดูเหมือนว่านี้:

กราฟฟังก์ชั่น 3 มิติ

ตอนนี้ให้พิจารณาระดับน้ำที่ความสูง 255 ซึ่งลดระดับลงอย่างต่อเนื่อง ที่ป๊อปอัปหมู่เกาะท้องถิ่นปรากฏขึ้น (เกิด) ที่จุดอานสองเกาะรวม; เราพิจารณาว่าเกาะล่างจะรวมเข้ากับเกาะที่สูงกว่า (ความตาย) แผนภาพการคงอยู่ที่เรียกว่า (ของคลาส homology 0 มิติที่เกาะของเรา) แสดงให้เห็นถึงความตาย - เกิดค่าของเกาะทั้งหมด:

แผนภาพความคงทน

ความคงทนของเกาะจึงแตกต่างกันระหว่างระดับการเกิดและความตาย ระยะทางแนวตั้งของจุดหนึ่งถึงเส้นทแยงมุมสีเทาหลัก รูปที่ติดป้ายหมู่เกาะโดยลดการติดตา

ภาพแรกแสดงตำแหน่งของการเกิดของหมู่เกาะ วิธีนี้ไม่เพียง แต่ช่วยให้ maxima ท้องถิ่น แต่ยังปริมาณ "ความสำคัญ" ของพวกเขาโดยการติดตาดังกล่าวข้างต้น จากนั้นหนึ่งตัวจะกรองหมู่เกาะทั้งหมดด้วยความเพียรต่ำเกินไป อย่างไรก็ตามในตัวอย่างของคุณทุกเกาะ (เช่นสูงสุดทุกท้องถิ่น) เป็นจุดสูงสุดที่คุณมองหา

รหัสงูใหญ่สามารถพบได้ที่นี่


16

ปัญหานี้ได้รับการศึกษาในเชิงลึกโดยนักฟิสิกส์ มีการดำเนินการที่ดีในการเป็นราก ดูคลาสTSpectrum (โดยเฉพาะTSpectrum2สำหรับกรณีของคุณ) และเอกสารประกอบสำหรับพวกเขา

อ้างอิง:

  1. M.Morhac et al.: วิธีการกำจัดฉากหลังสำหรับปรากฏการณ์พหุสัณฐานหลายมิติ เครื่องมือและวิธีการทางนิวเคลียร์ในการวิจัยทางฟิสิกส์ก 401 (1997) 113-132.
  2. M.Morhac et al .: การแยกแยะทองคำในรูปแบบหนึ่งและสองมิติอย่างมีประสิทธิภาพ เครื่องมือและวิธีการทางนิวเคลียร์ในการวิจัยทางฟิสิกส์ก 401 (1997) 385-408.
  3. M.Morhac et al.: การจำแนกพีคส์ในสเปกตรัมพหุสัณฐานหลายมิติ เครื่องมือและวิธีการทางนิวเคลียร์ในฟิสิกส์การวิจัย A 443 (2000), 108-125

... และสำหรับผู้ที่ไม่สามารถเข้าถึงการสมัครสมาชิก NIM:


สำหรับการอ่านบทความดูเหมือนว่าจะอธิบายการประมวลผลข้อมูลเดียวกับสิ่งที่ฉันพยายามที่นี่ แต่ฉันกลัวว่ามันเกินกว่าทักษะการเขียนโปรแกรมของฉัน :(
Ivo Flipse

@Ivo: ฉันไม่เคยพยายามที่จะใช้มันด้วยตัวเอง ฉันแค่ใช้รูท มีการผูกหลามแบบไม่มีส่วนน้อย แต่ให้ระวังว่า ROOT เป็นแพ็คเกจที่ค่อนข้างหนัก
dmckee --- ผู้ดูแลอดีตลูกแมว

@Ivo Flipse: ฉันเห็นด้วยกับ dmckee คุณมีโอกาสในการขายมากมายในคำตอบอื่น ๆ หากพวกเขาล้มเหลวและคุณรู้สึกอยากลงทุนสักระยะหนึ่งคุณสามารถเจาะรูทและจะทำในสิ่งที่คุณต้องการ ฉันไม่เคยรู้จักใครที่พยายามเรียนรู้รูทผ่านการผูกงูหลาม (แทนที่จะเป็น C ++ ธรรมดา) ดังนั้นฉันขอให้คุณโชคดี
physicsmichael

13

นี่คือแนวคิด: คุณคำนวณ Laplacian (ไม่ต่อเนื่อง) ของภาพ ฉันคาดหวังว่ามันจะมีขนาดใหญ่ (เป็นลบและ) ที่ maxima ในลักษณะที่น่าทึ่งกว่าภาพต้นฉบับ ดังนั้น maxima อาจหาได้ง่ายกว่า

นี่คือแนวคิดอื่น: หากคุณทราบขนาดปกติของจุดแรงดันสูงคุณสามารถทำให้ภาพของคุณราบรื่นโดยการโน้มน้าวใจด้วย Gaussian ที่มีขนาดเท่ากัน นี่อาจทำให้คุณประมวลภาพได้ง่ายขึ้น


11

เพียงความคิดสองสามข้อที่อยู่ด้านบนของหัวของฉัน

  • ใช้การไล่ระดับสี (อนุพันธ์) ของการสแกนดูว่ากำจัดการโทรที่ผิดพลาดหรือไม่
  • ใช้เวลาสูงสุดของท้องถิ่นสูงสุด

คุณอาจต้องการที่จะดูOpenCVมันเป็น Python API ที่ค่อนข้างดีและอาจมีฟังก์ชั่นบางอย่างที่คุณคิดว่ามีประโยชน์


ด้วยการไล่ระดับสีคุณหมายถึงฉันควรคำนวณความชันของเนินเขาเมื่อค่านี้สูงกว่าค่าที่ฉันรู้ว่ามันมีค่าสูงสุด ฉันลองสิ่งนี้ แต่นิ้วเท้าบางอันมียอดเขาต่ำมาก (1.2 N / cm) เท่านั้นเมื่อเทียบกับบางส่วน (8 N / cm) ดังนั้นฉันจะจัดการกับยอดเขาด้วยการไล่ระดับที่ต่ำมากได้อย่างไร
Ivo Flipse

2
สิ่งที่ได้ผลสำหรับฉันในอดีตถ้าฉันไม่สามารถใช้การไล่ระดับสีโดยตรงเพื่อดูการไล่ระดับสีและ maxima เช่นหากการไล่ระดับสีเป็น extrema ท้องถิ่นและฉันอยู่ที่จุดสูงสุดในท้องถิ่นแล้วฉันจะอยู่ที่จุดหนึ่ง น่าสนใจ.
ChrisC

11

ฉันแน่ใจว่าคุณมีเพียงพอที่จะดำเนินการต่อไปในตอนนี้ แต่ฉันไม่สามารถช่วยได้ k-mean เป็นอัลกอริธึมการจัดกลุ่มที่ไม่ได้รับการสนับสนุนซึ่งจะนำข้อมูลมาให้คุณ (ในหลาย ๆ มิติ - ฉันจะทำสิ่งนี้ในแบบ 3 มิติ) และจัดให้เป็นกลุ่ม k ที่มีขอบเขตที่แตกต่างกัน มันดีที่นี่เพราะคุณรู้ว่ามีกี่นิ้วเขี้ยวเหล่านี้ (ควร) มี

นอกจากนี้ยังมีการใช้งานใน Scipy ซึ่งดีมาก ( http://docs.scipy.org/doc/scipy/reference/cluster.vq.html )

นี่คือตัวอย่างของสิ่งที่สามารถทำได้เพื่อแก้ปัญหากลุ่ม 3D เชิงพื้นที่: ป้อนคำอธิบายรูปภาพที่นี่

สิ่งที่คุณต้องการทำคือแตกต่างกันเล็กน้อย (2D และรวมถึงค่าความดัน) แต่ฉันก็ยังคิดว่าคุณสามารถให้มันได้


10

ขอบคุณสำหรับข้อมูลดิบ ฉันอยู่บนรถไฟและนี่คือเท่าที่ฉันได้รับ (หยุดของฉันกำลังจะมาถึง) ฉันนวดไฟล์ txt ของคุณด้วย regexps และได้ plopped ลงในหน้า html ด้วย javascript บางส่วนสำหรับการสร้างภาพ ฉันแบ่งปันที่นี่เพราะบางคนเช่นฉันอาจพบว่าแฮ็คได้ง่ายกว่างูหลาม

ฉันคิดว่าวิธีการที่ดีจะทำให้ขนาดและการหมุนเวียนคงที่และขั้นตอนต่อไปของฉันคือการตรวจสอบส่วนผสมของ gaussians (อุ้งเท้าแต่ละอันเป็นจุดศูนย์กลางของเกาส์เซียน)

    <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>

ข้อความแสดงแทน


1
ฉันคิดว่านี่เป็นข้อพิสูจน์ของแนวคิดที่ว่าเทคนิคแบบเกาส์ที่แนะนำสามารถใช้งานได้ตอนนี้ถ้ามีใครบางคนเท่านั้นที่สามารถพิสูจน์ได้ด้วย Python ;-)
Ivo Flipse

8

วิธีการแก้ปัญหาของนักฟิสิกส์:
กำหนด 5 paw-marker ที่ระบุโดยตำแหน่งของพวกเขาX_iและเริ่มต้นด้วยตำแหน่งสุ่ม กำหนดฟังก์ชั่นพลังงานบางอย่างรวมรางวัลบางอย่างสำหรับตำแหน่งของเครื่องหมายในตำแหน่งของอุ้งเท้ากับการลงโทษบางอย่างสำหรับการทับซ้อนของเครื่องหมาย; สมมติว่า:

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

( S(X_i)เป็นแรงเฉลี่ยใน 2x2 ตารางรอบX_i, alfaเป็นพารามิเตอร์ที่จะแหลมทดลอง)

ถึงเวลาที่จะทำเวทย์มนตร์ Metropolis-Hastings:
1. เลือกเครื่องหมายสุ่มและย้ายไปทีละหนึ่งพิกเซลในทิศทางที่สุ่ม
2. คำนวณ dE ความแตกต่างของพลังงานที่เกิดขึ้น
3. รับตัวเลขสุ่มที่สม่ำเสมอจาก 0-1 และเรียกว่า r
4. ถ้าdE<0หรือexp(-beta*dE)>rยอมรับการย้ายและไปที่ 1; ถ้าไม่เลิกย้ายและไปที่ 1
สิ่งนี้ควรทำซ้ำจนกว่าเครื่องหมายจะมาบรรจบกันที่อุ้งเท้า เบต้าควบคุมการสแกนเพื่อปรับการแลกเปลี่ยนให้เหมาะสมดังนั้นจึงควรปรับปรุงการทดลองด้วย มันสามารถเพิ่มขึ้นอย่างต่อเนื่องกับเวลาของการจำลอง (การจำลองการหลอม)


สนใจที่จะแสดงว่ามันจะทำงานกับตัวอย่างของฉันได้อย่างไร เนื่องจากฉันไม่ได้เป็นคณิตศาสตร์ระดับสูงดังนั้นฉันจึงมีเวลายากที่จะไขสูตรที่คุณเสนอ :(
Ivo Flipse

1
นี่คือคณิตศาสตร์ของโรงเรียนมัธยมบางทีสัญกรณ์ของฉันอาจจะงง ๆ ฉันมีแผนที่จะตรวจสอบเพื่อติดตามความคืบหน้า
mbq

4
ฉันเป็นนักฟิสิกส์อนุภาค เป็นเวลานานที่เครื่องมือซอฟต์แวร์แบบไปสู่ในวินัยของเราถูกเรียกว่า PAW และมีเอนทิตีที่เกี่ยวข้องกับกราฟที่เรียกว่า "มาร์กเกอร์" คุณสามารถคิดวิธีการที่ทำให้เกิดความสับสนผมพบคำตอบเกี่ยวกับเรื่องนี้คู่แรกของรอบครั้ง ...
dmckee --- อดีตผู้ดูแลลูกแมว

6

นี่เป็นอีกวิธีที่ฉันใช้เมื่อทำสิ่งที่คล้ายกันกับกล้องโทรทรรศน์ขนาดใหญ่:

1) ค้นหาพิกเซลสูงสุด เมื่อคุณได้แล้วให้ค้นหารอบตัวเพื่อหาขนาดที่เหมาะสมที่สุดสำหรับ 2x2 (อาจรวมผลรวม 2x2 ให้มากที่สุด) หรือทำแบบเกาส์ 2d ภายในขอบเขตย่อยของการบอกว่า 4x4 มีศูนย์กลางอยู่ที่พิกเซลสูงสุด

จากนั้นตั้งค่าพิกเซล 2x2 ที่คุณพบว่ามีค่าเป็นศูนย์ (หรืออาจเป็น 3x3) รอบจุดกึ่งกลาง

กลับไปที่ 1) และทำซ้ำจนกระทั่งถึงจุดสูงสุดที่อยู่ต่ำกว่าระดับเสียงหรือคุณมีนิ้วเท้าที่คุณต้องการ


สนใจที่จะแบ่งปันตัวอย่างรหัสที่ทำเช่นนี้? ฉันสามารถติดตามสิ่งที่คุณพยายามทำ แต่ไม่รู้ว่าจะเขียนมันเองได้อย่างไร
Ivo Flipse

จริง ๆ แล้วฉันมาจากการทำงานกับ Matlab ดังนั้นใช่แล้วที่จะช่วยได้ แต่ถ้าคุณใช้ฟังก์ชั่นต่างประเทศจริง ๆ มันอาจจะยากสำหรับฉันที่จะทำซ้ำกับ Python
Ivo Flipse

6

อาจคุ้มค่าที่จะลองใช้เครือข่ายประสาทหากคุณสามารถสร้างข้อมูลการฝึกอบรมได้ ... แต่สิ่งนี้ต้องใช้ตัวอย่างจำนวนมากที่อธิบายด้วยมือ


ถ้ามันคุ้มค่ากับปัญหาฉันจะไม่ทำหมายเหตุประกอบตัวอย่างขนาดใหญ่ด้วยมือ ปัญหาของฉันคือ: ฉันจะใช้สิ่งนี้ได้อย่างไรเนื่องจากฉันไม่รู้อะไรเกี่ยวกับการเขียนโปรแกรมเครือข่ายนิว
รัล

6

เค้าร่างคร่าวๆ ...

คุณอาจต้องการใช้อัลกอริทึมที่เชื่อมต่อเพื่อแยกแต่ละภูมิภาคอุ้งเท้า wiki มีคำอธิบายที่ดีเกี่ยวกับเรื่องนี้ (พร้อมรหัส) ที่นี่: http://en.wikipedia.org/wiki/Connected_Component_Labeling

คุณจะต้องตัดสินใจว่าจะใช้การเชื่อมต่อ 4 หรือ 8 ส่วนตัวสำหรับปัญหาส่วนใหญ่ฉันชอบ 6-connectness อย่างไรก็ตามเมื่อคุณแยก "อุ้งเท้า" ออกเป็นภูมิภาคที่เชื่อมต่อกันแล้วควรจะง่ายพอที่จะวนซ้ำไปทั่วภูมิภาคและหาค่าสูงสุด เมื่อคุณพบจุดสูงสุดแล้วคุณสามารถขยายขอบเขตซ้ำ ๆ จนกว่าคุณจะถึงขีด จำกัด ที่กำหนดไว้ล่วงหน้าเพื่อระบุว่าเป็น "นิ้วเท้า" ที่ระบุ

ปัญหาที่ลึกซึ้งอย่างหนึ่งที่นี่ก็คือทันทีที่คุณเริ่มใช้เทคนิคการมองเห็นคอมพิวเตอร์เพื่อระบุสิ่งที่เป็นอุ้งเท้าขวา / ซ้าย / ด้านหน้า / หลังและคุณเริ่มมองนิ้วเท้าแต่ละนิ้วคุณจะต้องเริ่มการหมุน นี่คือความสำเร็จผ่านการวิเคราะห์ที่เรียกว่า "ช่วงเวลา" มีช่วงเวลาที่แตกต่างกันเล็กน้อยในการพิจารณาในแอปพลิเคชันการมองเห็น:

ช่วงเวลาสำคัญ: การแปลช่วงเวลาปกติ: การปรับขนาดและการแปลช่วงเวลา hu: การแปล, สเกลและการหมุนคงที่

ข้อมูลเพิ่มเติมเกี่ยวกับช่วงเวลาสามารถพบได้โดยการค้นหา "ช่วงเวลาภาพ" บนวิกิ



4

ดูเหมือนว่าคุณสามารถโกงได้โดยใช้อัลกอริทึมของ jetxee เขากำลังค้นพบสามนิ้วแรกที่ดีและคุณควรจะสามารถเดาได้ว่าอันดับที่สี่นั้นเป็นอย่างไร


4

ปัญหาที่น่าสนใจ ทางออกที่ฉันจะลองมีดังต่อไปนี้

  1. ใช้ฟิลเตอร์กรองความถี่ต่ำเช่นการบิดด้วยหน้ากาก Gaussian แบบ 2D สิ่งนี้จะทำให้คุณมีค่า (อาจ แต่ไม่จำเป็นต้องเป็นทศนิยม) จำนวนมาก

  2. ทำการปราบปรามแบบ 2 มิติไม่สูงสุดโดยใช้รัศมีโดยประมาณที่รู้จักกันในแต่ละอุ้งเท้า (หรือนิ้วเท้า)

สิ่งนี้จะทำให้คุณได้ตำแหน่งสูงสุดโดยไม่ต้องมีผู้สมัครหลายคนที่อยู่ใกล้กัน เพื่ออธิบายให้ชัดเจนรัศมีของหน้ากากในขั้นตอนที่ 1 ควรคล้ายกับรัศมีที่ใช้ในขั้นตอนที่ 2 รัศมีนี้สามารถเลือกได้หรือสัตว์แพทย์สามารถวัดได้ล่วงหน้าอย่างชัดเจน (มันจะแตกต่างกันตามอายุ / พันธุ์ / ฯลฯ )

วิธีแก้ปัญหาบางอย่างที่แนะนำ (หมายถึงการเปลี่ยนแปลงอวนประสาทและอื่น ๆ ) อาจใช้ได้ในระดับหนึ่ง แต่มีความซับซ้อนมากเกินไปและอาจไม่เหมาะ


ฉันมีประสบการณ์ 0 กับเมทริกซ์ convolution และตัวกรอง Gaussian ดังนั้นคุณต้องการแสดงให้เห็นว่ามันทำงานอย่างไรในตัวอย่างของฉัน
Ivo Flipse

3

ทีนี้นี่คือโค้ดที่เรียบง่ายและไม่มีประสิทธิภาพ แต่สำหรับชุดข้อมูลขนาดนี้ถือว่าใช้ได้

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]

โดยทั่วไปฉันแค่สร้างอาร์เรย์ด้วยตำแหน่งของมุมบนซ้ายและผลรวมของแต่ละ 2x2 สแควร์แล้วเรียงลำดับตามผลรวม จากนั้นฉันก็เอา 2x2 สแควร์พร้อมกับผลรวมสูงสุดของความขัดแย้งเอาไว้ในbestอาร์เรย์และลบสี่เหลี่ยม 2x2 อื่น ๆ ทั้งหมดที่ใช้ส่วนใดส่วนหนึ่งของสี่เหลี่ยมจัตุรัส 2x2 นี้ออก

ดูเหมือนว่าจะทำงานได้ดียกเว้นกับอุ้งเท้าสุดท้าย (อันที่มีผลรวมน้อยที่สุดทางขวาสุดในภาพแรกของคุณ) ปรากฎว่ามีอีก 2x2 สแควร์สที่มีสิทธิ์อีกสองตัวที่มีผลรวมขนาดใหญ่กว่า ซึ่งกันและกัน) หนึ่งในนั้นยังคงเลือกหนึ่งตารางจากตาราง 2x2 ของคุณ แต่อีกอันหนึ่งออกไปทางซ้าย โชคดีที่โชคดีที่เราเห็นว่าจะเลือกมากกว่าที่คุณต้องการ แต่สิ่งนี้อาจต้องใช้ความคิดอื่น ๆ เพื่อให้ได้สิ่งที่คุณต้องการตลอดเวลา


ฉันคิดว่าผลลัพธ์ของคุณเหมือนกับคำตอบของ @ Jextee หรืออย่างน้อยก็ดูเหมือนว่าจากฉันทดสอบ
Ivo Flipse


1

อาจเป็นวิธีที่ไร้เดียงสาเพียงพอแล้วที่นี่: สร้างรายการของ 2x2 กำลังสองทั้งหมดบนเครื่องบินของคุณสั่งซื้อพวกเขาด้วยผลรวมของพวกเขา

ก่อนอื่นให้เลือกสี่เหลี่ยมที่มีค่าสูงสุดลงใน "รายการอุ้งเท้าของคุณ" จากนั้นให้เลือก 4 จากสี่เหลี่ยมที่ดีที่สุดถัดไปที่ไม่ตัดกับสี่เหลี่ยมที่พบก่อนหน้านี้


ฉันทำรายการกับผลรวม 2x2 ทั้งหมด แต่เมื่อฉันสั่งให้ฉันไม่รู้ว่าจะเปรียบเทียบมันอย่างไร ปัญหาของฉันคือเมื่อฉันเรียงมันฉันลืมติดตามพิกัด บางทีฉันอาจติดมันไว้ในพจนานุกรมโดยใช้พิกัดเป็นกุญแจ
Ivo Flipse

ใช่พจนานุกรมบางประเภทอาจจำเป็น ฉันคิดว่าการเป็นตัวแทนของกริดของคุณเป็นพจนานุกรมประเภทหนึ่งอยู่แล้ว
Johannes Charra

รูปภาพที่คุณเห็นด้านบนเป็นอาร์เรย์ที่มีค่า ส่วนที่เหลือจะถูกเก็บไว้ในรายการหลายมิติ มันคงเป็นการดีกว่าถ้าจะหยุดทำแบบนั้นแม้ว่าฉันจะไม่คุ้นเคยกับการวนซ้ำในพจนานุกรม
Ivo Flipse

1

มีซอฟต์แวร์มากมายหลายชนิดจากชุมชนดาราศาสตร์และจักรวาลวิทยา - นี่เป็นพื้นที่สำคัญของการวิจัยทั้งในอดีตและปัจจุบัน

อย่าตื่นตระหนกหากคุณไม่ใช่นักดาราศาสตร์บางคนใช้งานง่ายนอกสนาม ตัวอย่างเช่นคุณสามารถใช้ astropy / photutils:

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

[ดูเหมือนหยาบคายเล็กน้อยที่จะทำซ้ำรหัสตัวอย่างแบบย่อของพวกเขาที่นี่]

รายการเทคนิค / แพ็คเกจ / ลิงก์ที่ไม่สมบูรณ์และลำเอียงเล็กน้อยซึ่งอาจเป็นที่สนใจได้รับด้านล่าง - เพิ่มความคิดเห็นเพิ่มเติมและฉันจะอัปเดตคำตอบนี้ตามความจำเป็น แน่นอนว่ามีการแลกเปลี่ยนความแม่นยำกับทรัพยากรการคำนวณ [สุจริตมีจำนวนมากเกินไปที่จะให้ตัวอย่างรหัสในคำตอบเดียวเช่นนี้ดังนั้นฉันไม่แน่ใจว่าคำตอบนี้จะบินหรือไม่]

Source Extractor https://www.astromatic.net/software/sextractor

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

ความท้าทายในการค้นหาแหล่งที่มา ASKAP / EMU: https://arxiv.org/abs/1509.03931

นอกจากนี้คุณยังสามารถค้นหาความท้าทายในการดึงข้อมูล Planck และ / หรือ WMAP

...


0

จะเกิดอะไรขึ้นถ้าคุณดำเนินการทีละขั้นตอน: คุณค้นหาค่าสูงสุดทั่วโลกก่อนประมวลผลหากต้องการจุดโดยรอบที่ให้ค่าของพวกเขาจากนั้นตั้งค่าภูมิภาคที่พบเป็นศูนย์และทำซ้ำสำหรับพื้นที่ถัดไป


อืมมที่การตั้งค่าเป็นศูนย์อย่างน้อยจะลบออกจากการคำนวณเพิ่มเติมใด ๆ ที่จะเป็นประโยชน์
Ivo Flipse

แทนที่จะตั้งค่าเป็นศูนย์คุณอาจคำนวณฟังก์ชัน gaussian ด้วยพารามิเตอร์ที่เลือกด้วยมือและลบค่าที่พบจากการอ่านค่าความดันดั้งเดิม ดังนั้นหากนิ้วเท้ากดเซ็นเซอร์ของคุณดังนั้นจากการหาจุดกดสูงสุดคุณจะใช้มันเพื่อลดผลกระทบของนิ้วเท้านั้นบนเซ็นเซอร์ดังนั้นกำจัดเซลล์ที่อยู่ใกล้เคียงด้วยค่าความดันสูง en.wikipedia.org/wiki/File:Gaussian_2d.png
Daniyar

สนใจที่จะแสดงตัวอย่างตามข้อมูลตัวอย่างของฉัน @Daniyar? เนื่องจากฉันไม่คุ้นเคยกับการประมวลผลข้อมูลประเภทนี้มากนัก
Ivo Flipse

0

ฉันไม่แน่ใจว่านี่เป็นคำตอบของคำถาม แต่ดูเหมือนว่าคุณสามารถมองหายอดเขาสูงสุดที่ไม่มีเพื่อนบ้าน

นี่คือส่วนสำคัญ โปรดทราบว่ามันอยู่ใน Ruby แต่แนวคิดควรชัดเจน

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

ฉันจะลองดูและดูว่าฉันสามารถแปลงเป็นรหัส Python ได้ไหม :-)
Ivo Flipse

โปรดใส่รหัสในโพสต์เองแทนที่จะลิงค์ไปยังส่วนสำคัญหากมีความยาวพอสมควร
agf
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.