Verwenden Sie TensorFlow Hub, um ** ein vorab trainiertes Modell der allgemeinen Objekterkennung (erstellt von Google) ** zu erstellen und damit eine allgemeine Objekterkennung (allgemeine Objekterkennung) für jedes Bild durchzuführen. Es ist der Inhalt.
Grundsätzlich verweise ich auf https://github.com/tensorflow/hub/blob/master/examples/colab/object_detection.ipynb.
Die Ausführungsumgebung ist ** Google Colab. ** und unterstützt TensorFlow ** 2.x **.
Ändern Sie die GPU für die Berechnung. Wählen Sie "Runtime" - "Change Runtime Type" aus dem Menü oben und ändern Sie den Hardwarebeschleuniger in "** GPU **".
Fügen Sie als Nächstes eine Umgebungsvariable hinzu, die das Verzeichnis angibt, in dem Sie die Module (trainierte Modelle), die Sie von TensorFlow Hub mitbringen, vorübergehend speichern möchten. Dieser Vorgang ist nur erforderlich, wenn Sie überprüfen möchten, welche Art von Modul heruntergeladen wird. Er kann weggelassen werden.
Umgebungsvariable hinzufügen
import os
os.environ['TFHUB_CACHE_DIR'] ='/content/tfhub'
Überprüfen Sie die Umgebungsvariablen
!printenv TFHUB_CACHE_DIR
Wechseln Sie zu TensorFlow 2.x.
TensorFlow2.Wechseln Sie zu x
%tensorflow_version 2.x
Laden Sie außerdem das Bild, das Sie als Objekt erkennen möchten, in Google Colab hoch. (Sie können es hochladen, indem Sie die Seitenleiste erweitern, die Registerkarte Datei aktivieren und die Datei ziehen und ablegen.) Hier wird die JPG-Formatdatei verwendet, aber auch das PNG-Format ist in Ordnung.
Holen Sie sich das allgemeine Objekterkennungsmodul (trainiertes Modell) von TensorFlow Hub.
Detektor wird geladen
import tensorflow as tf
import tensorflow_hub as hub
module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'
#module_handle = 'https://tfhub.dev/google/faster_rcnn/openimages_v4/inception_resnet_v2/1'
detector = hub.load(module_handle).signatures['default']
Das obige Modul ist "* SSD-basiertes Objekterkennungsmodell, das auf Open Images V4 mit ImageNet vorab trainiertem MobileNet V2 als Bildfeaturextraktor trainiert wurde. *". Darüber hinaus gibt es verschiedene Module für die "Bildobjekterkennung" auf dem Hub.
Wenn die Umgebungsvariable TFHUB_CACHE_DIR
gesetzt ist, wird das erfasste Modul dort gespeichert (wenn es nicht angegeben ist, wird es irgendwo in / tmp
gespeichert?).
Schreiben Sie eine Funktion "run_detector (...)", die den oben geladenen "Detektor" und "Bilddateipfad" als Argumente verwendet, die Objekterkennung ausführt und das Ergebnis als Text ausgibt.
Die in der letzten Zeile aufgerufene Funktion "showImage (...)" wird später erstellt, daher werde ich sie hier auskommentieren.
Die Hauptpunkte sind wie folgt.
Funktionsdefinition zur Objekterkennung
import time
import numpy as np
import PIL.Image as Image
def run_detector(detector, path):
#Importieren Sie das Bild und konvertieren Sie es in ein Format, das in den Detektor eingegeben werden kann
img = Image.open(path) # Pillow(PIL)
if img.mode == 'RGBA' :
img = img.convert('RGB')
converted_img = img.copy()
converted_img = converted_img.resize((227,227),Image.LANCZOS) #Auf Eingabegröße reduzieren
converted_img = np.array(converted_img, dtype=np.float32) # np.In Array konvertieren
converted_img = converted_img / 255. # 0.0 ~ 1.Normalisiert auf 0
converted_img = converted_img.reshape([1,227,227,3])
converted_img = tf.constant(converted_img)
t1 = time.time()
result = detector(converted_img) #Allgemeine Objekterkennung (Hauptkörper)
t2 = time.time()
print(f'Erkennungszeit: {t2-t1:.3f}Sekunden' )
#Vorbereitung zur Ausgabe des Ergebnisses als Text
r = {key:value.numpy() for key,value in result.items()}
boxes = r['detection_boxes']
scores = r['detection_scores']
decode = np.frompyfunc( lambda p : p.decode('ascii'), 1, 1)
class_names = decode( r['detection_class_entities'] )
#Punktzahl ist 0.Textausgabe für mehr als 25 Ergebnisse (n)
print(f'Erkennungsobjekt' )
n = np.count_nonzero(scores >= 0.25 )
for i in range(n):
y1, x1, y2, x2 = tuple(boxes[i])
x1, x2 = int(x1*img.width), int(x2*img.width)
y1, y2 = int(y1*img.height),int(y2*img.height)
t = f'{class_names[i]:10} {100*scores[i]:3.0f}% '
t += f'({x1:>4},{y1:>4}) - ({x2:>4},{y2:>4})'
print(t)
# showImage(np.array(img), r, min_score=0.25) #Überlagern Sie das Erkennungsergebnis auf dem Bild
Der obige "run_detector (...)" wird wie folgt aufgerufen:
Führen Sie dies aus, indem Sie den Bildpfad angeben
img_path = '/content/sample1.jpg'
run_detector(detector, img_path)
Hier habe ich das folgende Foto (kostenloses Material) für sample1.jpg
verwendet.
Das Ausführungsergebnis ist wie folgt. Die Zahlen in Klammern sind die oberen linken und unteren rechten Koordinaten des Rechtecks, das das Objekt umgibt.
Erkennungszeit: 0.251 Sekunden
Erkennungsobjekt
Human face 57% ( 522, 156) - ( 636, 276)
Clothing 57% ( 403, 203) - ( 757, 577)
Clothing 57% ( 144, 211) - ( 481, 583)
Girl 41% ( 393, 104) - ( 763, 595)
Girl 34% ( 214, 81) - ( 619, 614)
Mit einem solchen Text ist das Ergebnis schwer zu verstehen, daher werde ich es dem Bild überlagern.
Schreiben Sie eine Funktion "showImage (...)", um das Erkennungsergebnis auf das Bild zu legen.
Überlagern Sie das Erkennungsergebnis auf dem Bild
import matplotlib.pyplot as plt
import matplotlib.patheffects as pe
def showImage(img, r, min_score=0.1):
fig = plt.figure(dpi=150,figsize=(8,8))
ax = plt.gca()
ax.tick_params(axis='both', which='both', left=False,
labelleft=False, bottom=False, labelbottom=False)
ax.imshow(img)
decode = np.frompyfunc( lambda p : p.decode("ascii"), 1, 1)
boxes = r['detection_boxes']
scores = r['detection_scores']
class_names = decode( r['detection_class_entities'] )
n = np.count_nonzero(scores >= min_score)
# class_Farbvorbereitung entsprechend Namen
class_set = np.unique(class_names[:n])
colors = dict()
cmap = plt.get_cmap('tab10')
for i, v in enumerate(class_set):
colors[v] =cmap(i)
#Zeichnen Sie ein Rechteck Zeichnen Sie das Rechteck mit der niedrigsten Punktzahl
img_w = img.shape[1]
img_h = img.shape[0]
for i in reversed(range(n)):
text = f'{class_names[i]} {100*scores[i]:.0f}%'
color = colors[class_names[i]]
y1, x1, y2, x2 = tuple(boxes[i])
y1, y2 = y1*img_h, y2*img_h
x1, x2 = x1*img_w, x2*img_w
#Rahmen
r = plt.Rectangle(xy=(x1, y1), width=(x2-x1), height=(y2-y1),
fill=False, edgecolor=color, joinstyle='round',
clip_on=False, zorder=8+(n-i) )
ax.add_patch( r )
#Tags: Text
t = ax.text(x1+img_w/200, y1-img_h/300, text, va='bottom', fontsize=6, color=color,zorder=8+(n-i))
t.set_path_effects([pe.Stroke(linewidth=1.5,foreground='white'), pe.Normal()])
fig.canvas.draw()
r = fig.canvas.get_renderer()
coords = ax.transData.inverted().transform(t.get_window_extent(renderer=r))
tag_w = abs(coords[0,0]-coords[1,0])+img_w/100
tag_h = abs(coords[0,1]-coords[1,1])+img_h/120
#Tags: Hintergrund
r = plt.Rectangle(xy=(x1, y1-tag_h), width=tag_w, height=tag_h,
edgecolor=color, facecolor=color,
joinstyle='round', clip_on=False, zorder=8+(n-i))
ax.add_patch( r )
Entfernen Sie dann das auskommentierte in der letzten Zeile der Definition von "run_detector (...)" und führen Sie "run_detector (detector, img_path)" erneut aus.
Das folgende Ausführungsergebnis (Bild) wird erhalten.
Wechseln Sie zu einem anderen Modul (Detektor) und versuchen Sie die Objekterkennung für dasselbe Bild (dies nimmt viel Zeit in Anspruch).
python
import tensorflow as tf
import tensorflow_hub as hub
#module_handle = 'https://tfhub.dev/google/openimages_v4/ssd/mobilenet_v2/1'
module_handle = 'https://tfhub.dev/google/faster_rcnn/openimages_v4/inception_resnet_v2/1'
detector = hub.load(module_handle).signatures['default']
Das Ausführungsergebnis ist wie folgt. Es dauert viele Male länger als zuvor, aber wir können mehr erkennen.
Erkennungszeit: 1.379 Sekunden
Erkennungsobjekt
Human face 94% ( 524, 147) - ( 625, 272)
Human face 86% ( 266, 149) - ( 351, 270)
Clothing 75% ( 383, 234) - ( 750, 565)
Footwear 70% ( 154, 511) - ( 306, 598)
Boy 65% ( 351, 93) - ( 759, 606)
Footwear 59% ( 311, 521) - ( 477, 600)
Clothing 53% ( 152, 225) - ( 438, 565)
Girl 53% ( 144, 88) - ( 481, 598)
Boy 49% ( 225, 88) - ( 618, 592)
Boy 45% ( 145, 90) - ( 464, 603)
Girl 37% ( 324, 85) - ( 771, 587)
Sun hat 29% ( 479, 78) - ( 701, 279)
Recommended Posts