Ich beschäftige mich immer wieder mal mit Themen rund um Videosignalverarbeitung (Analog wie auch digital), meine Kentnisse sind jedoch recht oberflächlich. Objekterkennung in Videosignalen, sagen wir mal von einer kleinen CCD-Kamera ist heutzutage ja eigentlich nichts besonderes mehr. Ich meine damit das eine Software aus einem Bild oder Bildstrom darin befindliche Objekte erkennt und ggf. auch verfolgt. Die dahinter steckende Theorie, sowie die grundlegenden Verfahren um sowas in Software und vor allem in Echtzeit umzusetzen würde ich gern verstehen. Was braucht es dazu alles? Ich habe irgendwie keine Idee wie ich da anfangen und wonach ich konkret suchen soll? Einzelne Fragen zu irgendwelchen Spezialbereichen daraus zu stellen scheint mir aktuell wenig sinnvoll, ich glaube ich muss erstmal ein paar Grundlagen büffeln...
Für den Privatbastler ist wahrscheinlich die OpenCV Bibliothek https://opencv.org/ am zugängigsten wenn es um die paar hundert Basisalgorithmen geht. Ein paar hundert Algorithmen ist dabei kein Witz. Damit kann man dann Copy-Paste von im Internet gefundenen Code zu Objekterkennung machen, oder man setzt sich mit einem halben Hochschulstudium für die Grundlagen auseinander.
Mal was zum herumprobieren: https://www.codeproject.com/Articles/196168/Contour-Analysis-for-Image-Recognition-in-C
Gibt es denn sowas wie einen grundsätzlichen, theoretischen Ansatz für ein solches Problem? Oder sind aufgrund der genannten zahlreichen Algorithmen (100+) garkeine allgemeingültigen Vorgehensweisen nennbar? Wohlgemerkt, ich will garnicht den aktuellen Stand der Technik ergründen, sondern die Basiskonzepte denen es zugrunde liegt. Ich denke ja das man komplexe Objekte, besonders im 3D Raum irgendwie über ein neuronales Netz antrainieren muss. Wenn ich das Problem nun vereinfache und sage ich möchte nur im 2D Raum Objekte erkennen, evtl. auf Basis eines S/W-Bildes, wie erkennt eine Software in dem Array von Bytes ein geometrisches Objekt? Geht sowas über ein komplettes Bild oder über den Stream?
Um sich in einem (fast) völlig unbekannten Thema ersteinmal grob zu orientieren, lohnt sich meiner Meinung nach ein Blick in Wikipedia. Einmal auf Deutsch https://de.wikipedia.org/wiki/Objekterkennung und einmal auf Englisch https://en.wikipedia.org/wiki/Outline_of_object_recognition Ich bevorzuge die englische Version, weil sie oft lesbarer und ausführlicher geschrieben und mit mehr Kontext und Literaturangaben versehen ist. Darüber hinaus ist eine Suche im Internet meist ziemlich hilfreich.
Olli Z. schrieb: > Gibt es denn sowas wie einen grundsätzlichen, theoretischen Ansatz für > ein solches Problem? Im Prinzip läuft es immer darauf hinaus, "Merkmale" eines gesuchten Objektes zu definieren und geeignete Filter, die es ermöglichen, eben diese Merkmale möglichst zweifelsfrei und gleichzeitig effizient aufzuspüren. Das beides in kompetenter Form zu tun, erfordert ein tiefes Verständnis der Signalverarbeitung, welches du offensichtlich nicht besitzt. Da hilft nur eins: Lernen... Hart ist das Leben...
Für den Start würde ich mit den Tensorflow examples anfangen mit einem Pretrained Model (z.B.) ssd_mobilenet_v1_coco. Ist recht einfach:
1 | #!/usr/bin/env python
|
2 | # coding: utf-8
|
3 | |
4 | # Imports
|
5 | |
6 | import numpy as np |
7 | import os |
8 | import six.moves.urllib as urllib |
9 | import sys |
10 | import tarfile |
11 | import tensorflow as tf |
12 | import zipfile |
13 | |
14 | from collections import defaultdict |
15 | from io import StringIO |
16 | from matplotlib import pyplot as plt |
17 | from PIL import Image |
18 | |
19 | print(tf.__version__) |
20 | |
21 | if tf.__version__ < '1.10.0': |
22 | raise ImportError('Please upgrade your tensorflow installation to v1.4.* or later!') |
23 | |
24 | |
25 | # ## Env setup
|
26 | |
27 | # This is needed to display the images.
|
28 | #get_ipython().run_line_magic('matplotlib', 'inline')
|
29 | |
30 | # This is needed since the notebook is stored in the object_detection folder.
|
31 | #sys.path.append("..")
|
32 | |
33 | |
34 | # ## Object detection imports
|
35 | # Here are the imports from the object detection module.
|
36 | |
37 | |
38 | from utils import label_map_util |
39 | |
40 | from utils import visualization_utils as vis_util |
41 | |
42 | |
43 | # # Model preparation
|
44 | |
45 | # ## Variables
|
46 | #
|
47 | # Any model exported using the `export_inference_graph.py` tool can be loaded here simply by changing `PATH_TO_CKPT` to point to a new .pb file.
|
48 | #
|
49 | # By default we use an "SSD with Mobilenet" model here. See the [detection model zoo](https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md) for a list of other models that can be run out-of-the-box with varying speeds and accuracies.
|
50 | |
51 | |
52 | # What model to download.
|
53 | MODEL_NAME = 'ssd_mobilenet_v1_coco_2017_11_17' |
54 | MODEL_FILE = MODEL_NAME + '.tar.gz' |
55 | DOWNLOAD_BASE = 'http://download.tensorflow.org/models/object_detection/' |
56 | |
57 | # Path to frozen detection graph. This is the actual model that is used for the object detection.
|
58 | PATH_TO_CKPT = MODEL_NAME + '/frozen_inference_graph.pb' |
59 | |
60 | # List of the strings that is used to add correct label for each box.
|
61 | PATH_TO_LABELS = os.path.join('data', 'mscoco_label_map.pbtxt') |
62 | |
63 | NUM_CLASSES = 90 |
64 | |
65 | |
66 | # ## Download Model
|
67 | |
68 | |
69 | opener = urllib.request.URLopener() |
70 | opener.retrieve(DOWNLOAD_BASE + MODEL_FILE, MODEL_FILE) |
71 | tar_file = tarfile.open(MODEL_FILE) |
72 | for file in tar_file.getmembers(): |
73 | file_name = os.path.basename(file.name) |
74 | if 'frozen_inference_graph.pb' in file_name: |
75 | tar_file.extract(file, os.getcwd()) |
76 | |
77 | |
78 | detection_graph = tf.Graph() |
79 | with detection_graph.as_default(): |
80 | od_graph_def = tf.GraphDef() |
81 | with tf.gfile.GFile(PATH_TO_CKPT, 'rb') as fid: |
82 | serialized_graph = fid.read() |
83 | od_graph_def.ParseFromString(serialized_graph) |
84 | tf.import_graph_def(od_graph_def, name='') |
85 | |
86 | |
87 | # ## Loading label map
|
88 | # Label maps map indices to category names, so that when our convolution network predicts `5`, we know that this corresponds to `airplane`. Here we use internal utility functions, but anything that returns a dictionary mapping integers to appropriate string labels would be fine
|
89 | |
90 | label_map = label_map_util.load_labelmap(PATH_TO_LABELS) |
91 | categories = label_map_util.convert_label_map_to_categories(label_map, max_num_classes=NUM_CLASSES, use_display_name=True) |
92 | category_index = label_map_util.create_category_index(categories) |
93 | |
94 | |
95 | import cv2 |
96 | cap=cv2.VideoCapture(0) # 0 stands for very first webcam attach |
97 | cap.set(3,640) |
98 | cap.set(4,480) |
99 | |
100 | |
101 | with detection_graph.as_default(): |
102 | with tf.Session(graph=detection_graph) as sess: |
103 | |
104 | ret=True |
105 | |
106 | while (ret): |
107 | |
108 | ret, image_np=cap.read() |
109 | |
110 | # Definite input and output Tensors for detection_graph
|
111 | image_tensor = detection_graph.get_tensor_by_name('image_tensor:0') |
112 | # Each box represents a part of the image where a particular object was detected.
|
113 | detection_boxes = detection_graph.get_tensor_by_name('detection_boxes:0') |
114 | # Each score represent how level of confidence for each of the objects.
|
115 | # Score is shown on the result image, together with the class label.
|
116 | detection_scores = detection_graph.get_tensor_by_name('detection_scores:0') |
117 | detection_classes = detection_graph.get_tensor_by_name('detection_classes:0') |
118 | num_detections = detection_graph.get_tensor_by_name('num_detections:0') |
119 | |
120 | # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
|
121 | image_np_expanded = np.expand_dims(image_np, axis=0) |
122 | # Actual detection.
|
123 | (boxes, scores, classes, num) = sess.run( |
124 | [detection_boxes, detection_scores, detection_classes, num_detections], |
125 | feed_dict={image_tensor: image_np_expanded}) |
126 | # Visualization of the results of a detection.
|
127 | vis_util.visualize_boxes_and_labels_on_image_array( |
128 | image_np, |
129 | np.squeeze(boxes), |
130 | np.squeeze(classes).astype(np.int32), |
131 | np.squeeze(scores), |
132 | category_index, |
133 | use_normalized_coordinates=True, |
134 | line_thickness=8) |
135 | |
136 | |
137 | cv2.imshow('live_detection',image_np) |
138 | if cv2.waitKey(25) & 0xFF==ord('q'): |
139 | break
|
140 | cv2.destroyAllWindows() |
141 | cap.release() |
Olli Z. schrieb: > ich glaube ich muss erstmal ein paar > Grundlagen büffeln... Das ist gut für Grundlagen: ISBN: 978-3642130960
Das vereinfachte Vorgehen ist die Korrelation. Nun ist das direkt eher rechenintensiv, in Fourierraum aber einfach. Die Korrelation wird im Fourierraum zu einer Multiplikation. Also das Bild Fouriertransformieren, und mit den verschiedenen zu findenden, fouriertransformierten Mustern einzeln multiplizieren. Das in Echtzeit ist eine Menge Holz. Allenfalls, mit etwas mehr Theorie kann man's beschleunigen.
Olli Z. schrieb: > Gibt es denn sowas wie einen grundsätzlichen, theoretischen Ansatz für > ein solches Problem? Oder sind aufgrund der genannten zahlreichen > Algorithmen (100+) garkeine allgemeingültigen Vorgehensweisen nennbar? > Wohlgemerkt, ich will garnicht den aktuellen Stand der Technik > ergründen, sondern die Basiskonzepte denen es zugrunde liegt. Der grundlegene Ansatz ist ein Vergleich zwischen Soll und Ist. Das kann ein direkter Vergleich von Pixelfolgen sein, oder man zerlegt die Pixelfolgen in Frequenzen und vergleicht es im Frequenzbereich unter Weglassen von Nichtbenötigtem. Um Vergleiche durchzuführen (was ist ein Kreis, was eine Kante, was eine Ecke und was ist eine Fläche gleicher Farbe) muss das Bild passend vorverarbeitet werden, also - globaler / lokaler offset raus - Rauschen raus - Beleuchtungsgradient raus Hinzu kommem Mechanismen, um Bewegungen zu erkennen, also Vergleiche das Bildes mit sich selbst. Dann kann man z.B. direkt ablesen, welche Bereiche sich wohin bewegt haben, was eine Hintegrund, eine Vordergrund oder Boden oder ein Objekt ist.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.