[PYTHON] Eindimensionale und zweidimensionale Vertexerkennungsverarbeitung

Eindimensionale Scheitelpunkterkennung

Wenn der Faltungsprozess mit [-1, 1] durchgeführt wird, wird der ansteigende Teil zu einem Wert größer als 0 und der fallende Teil wird kleiner als 0. Auf diese Weise werden ein aufsteigendes Flag und ein absteigendes Flag erzeugt. Der Punkt, an dem sich die Flags überlappen, ist der Scheitelpunkt.

import math
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import PIL.Image
import random
import scipy.ndimage

#Eindimensionale Scheitelpunkterkennung
x = np.array([0, 0, 1, 0, 0])
print("x", x, "Zielarray")
conv1 = np.convolve(x, [1, -1], mode="full")
print("conv1", conv1, "[-1, 1]Markieren Sie mit dem Filter von Markierungen für steigende und fallende Punkte")
flag1 = (conv1 > 0).astype(int)
print("flag1", flag1, "Flagge des aufsteigenden Punktes")
flag2 = (conv1 <= 0).astype(int)
print("flag2", flag2, "Flagge des Abstiegspunktes")
flag1 = flag1[:-1]
print("flag1", flag1, "Schneiden Sie ein Ende der aufsteigenden Flagge entsprechend der Länge ab")
flag2 = flag2[1:]
print("flag2", flag2, "Schneiden Sie den Anfang der absteigenden Flagge um eins ab, richten Sie ihn an der Spitze aus und richten Sie die Länge aus.")
flag3 = flag1 & flag2
print("flag3", flag3, "Das Ergebnis der UND-Verknüpfung der aufsteigenden und absteigenden Flagge ist der Spitzenpunkt.")

Ausführungsergebnis

x [0 0 1 0 0]Zielarray
conv1 [ 0  0  1 -1  0  0] [-1, 1]Markieren Sie mit dem Filter von Markierungen für steigende und fallende Punkte
flag1 [0 0 1 0 0 0]Flagge des aufsteigenden Punktes
flag2 [1 1 0 1 1 1]Flagge des Abstiegspunktes
flag1 [0 0 1 0 0]Schneiden Sie ein Ende der aufsteigenden Flagge entsprechend der Länge ab
flag2 [1 0 1 1 1]Schneiden Sie den Anfang der absteigenden Flagge um eins ab, richten Sie ihn an der Spitze aus und richten Sie die Länge aus.
flag3 [0 0 1 0 0]Das Ergebnis der UND-Verknüpfung der aufsteigenden und absteigenden Flagge ist der Spitzenpunkt.

Beispiel erstellen

cycle = 4
data = np.zeros(100)
cycleWidth = len(data) / cycle
unit = math.pi / cycleWidth * 2
for i in range(cycle):
    for j in range(int(cycleWidth)):
        data[i * int(cycleWidth) + j] = math.cos(unit * float(j))

plt.plot(data)
plt.show()

一次元サンプル.PNG

Durchführen einer Scheitelpunkterkennung an einer Probe

#Funktionieren Sie die eindimensionale Scheitelpunkterkennung
def detectPeak1D(x):
    conv1 = np.convolve(x, [1, -1], mode="full")
    flag1 = (conv1 > 0).astype(int)
    flag2 = (conv1 <= 0).astype(int)
    flag1 = flag1[:-1]
    flag2 = flag2[1:]
    flag3 = flag1 & flag2
    return flag3

peaks = detectPeak1D(data)
plt.plot(data)
plt.plot(peaks)
plt.show()

一次元サンプル2.PNG

Der Anstieg wird als Spitze für horizontale Punkte erkannt

data[data > 0.7] = 0.7
peaks = detectPeak1D(data)
print("Wenn die Eckpunkte horizontal sind, wird der Anstieg als Eckpunkte erkannt")
plt.plot(data)
plt.plot(peaks)
plt.show()

一次元サンプル3.PNG

Zweidimensionale Scheitelpunkterkennung

Zweidimensionale Daten sind das Ergebnis der UND-Verknüpfung der beiden "Flags für alle Zeilen (zweidimensionales Array)" und "Flags für alle Spalten (zweidimensionales Array)" für die eindimensionale Scheitelpunkterkennung. Die Spitze sein

#Zweidimensionale Scheitelpunkterkennung
x = np.array([
    [0, 0, 1, 0, 0],
    [0, 2, 3, 2, 0],
    [1, 3, 5, 3, 1],
    [0, 2, 3, 2, 0],
    [0, 0, 1, 0, 0],
])
print(x, "Zieldaten")
#Führen Sie eine Scheitelpunkterkennung für alle Zeilen durch
peaks1 = []
for ix in x:
    peak = detectPeak1D(ix)
    peaks1.append(peak)
peaks1 = np.array(peaks1)
print(peaks1, "Horizontales Scheitelpunkterkennungsflag")
#Führen Sie eine Scheitelpunkterkennung für alle Spalten durch
peaks2 = []
for ix in x.transpose():
    peak = detectPeak1D(ix)
    peaks2.append(peak)
peaks2 = np.array(peaks2).transpose() #Führen Sie die Erkennung durch Transponieren aus und kehren Sie zum Original zurück
print(peaks2, "Vertikales Scheitelpunkterkennungsflag")
peaks3 = (peaks1 & peaks2).astype(int)
print(peaks3, "UND die Zeilen- und Spaltenerkennungsflags und die verbleibenden Flags werden zu zweidimensionalen Scheitelpunktflags.")

Ausführungsergebnis

[[0 0 1 0 0]
 [0 2 3 2 0]
 [1 3 5 3 1]
 [0 2 3 2 0]
 [0 0 1 0 0]]Zieldaten
[[0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]
 [0 0 1 0 0]]Horizontales Scheitelpunkterkennungsflag
[[0 0 0 0 0]
 [0 0 0 0 0]
 [1 1 1 1 1]
 [0 0 0 0 0]
 [0 0 0 0 0]]Vertikales Scheitelpunkterkennungsflag
[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 1 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]UND die Zeilen- und Spaltenerkennungsflags und die verbleibenden Flags werden zu zweidimensionalen Scheitelpunktflags.
#Funktionieren Sie die zweidimensionale Scheitelpunkterkennung
def detectPeak2D(x):
    peaks1 = []
    for ix in x:
        peak = detectPeak1D(ix)
        peaks1.append(peak)
    peaks1 = np.array(peaks1)
    peaks2 = []
    for ix in x.transpose():
        peak = detectPeak1D(ix)
        peaks2.append(peak)
    peaks2 = np.array(peaks2).transpose()
    flag = (peaks1 & peaks2).astype(int)
    return flag

Erstellen einer zweidimensionalen Datenprobe

#Erstellen Sie Testdaten für die zweidimensionale Scheitelpunkterkennung und drehen Sie Daten mit eindimensionalen Scheitelpunkten
random.seed(1)
data2d = np.zeros((200, 200))
pattern = np.array([1, 2, 3, 4, 5, 6, 7, 6, 5, 4, 3, 2, 1])
for i in range(10):
    ox, oy = random.randrange(200), random.randrange(200)
    for j in range(50):
        rad = (math.pi / 50) * j
        for ix, v in enumerate(pattern):
            pos = ix - len(pattern) / 2
            x = ox + math.cos(rad) * pos
            y = oy + math.sin(rad) * pos
            if x < 0: continue
            if x >= 200: continue
            if y < 0: continue
            if y >= 200: continue
            data2d[int(x)][int(y)] = v

plt.figure(figsize=(10,4),dpi=200)
plt.imshow(data2d)
plt.show()

Zweidimensionales Beispielbild

二次元データサンプル1.PNG

Durchführen einer zweidimensionalen Scheitelpunkterkennung

peaks = detectPeak2D(data2d)
print("Da alle ansteigenden Flanken als Eckpunkte erkannt werden, werden Punkte, an denen der gleiche Wert stetig ist, als Eckpunkte erkannt.")
plt.figure(figsize=(10,4),dpi=200)
plt.imshow(peaks)
plt.show()

二次元データサンプル2.PNG

Ausführung der zweidimensionalen Scheitelpunkterkennung nach dem Glätten

data2dGaussian = scipy.ndimage.gaussian_filter(data2d, sigma=1)
peaks = detectPeak2D(data2dGaussian)
print("Die Eckpunkte können normal erkannt werden, indem parallele Teile so weit wie möglich geglättet und entfernt werden.")
plt.figure(figsize=(10,4),dpi=200)
plt.imshow(peaks)
plt.show()

二次元データサンプル3.PNG

Achtung etc.

Es gibt keine Vorverarbeitung oder Verarbeitung, und es handelt sich um einen Prozess, bei dem Daten mit einer schönen Bergform angenommen werden. Grundsätzlich denke ich, dass sie oft nicht wie erwartet funktionieren, wenn sie nicht geglättet werden. Verwenden Sie sie also so, wie sie sind Es spielt keine Rolle, ob es sich um einen gleitenden Durchschnitt oder einen Gaußschen Filter handelt. Verwenden Sie ihn daher nach dem Glätten.

das ist alles.

Recommended Posts

Eindimensionale und zweidimensionale Vertexerkennungsverarbeitung
100 Klopfen bei der Bildverarbeitung !! (001 - 010) Vorsichtig und vorsichtig
Bildausdehnung und Kontraktionsverarbeitung
[Bildverarbeitung] Poo-san ist durch Kantenerkennung mit Python und OpenCV nackt!