Einleitung: Warum die Erkennung einer Coca-Cola-Dose schwieriger ist, als es scheint
Stellen Sie sich vor: Sie programmieren einen Roboter, der automatisch Müll sortieren soll. Oder ein System, das die Anzahl der Produkte im Regal zählt. Eine der beliebtesten Aufgaben in Vorstellungsgesprächen und Studienprojekten ist die Erkennung einer Coca-Cola-Dose. Was könnte daran schon schwer sein? Ein leuchtend roter Zylinder mit weißer Schrift. Doch in der Praxis sieht alles anders aus.
Auf Stack Overflow hat die Frage "Image Processing: Algorithm Improvement for 'Coca-Cola Can' Recognition" Tausende von Aufrufen und Dutzende von Antworten gesammelt. Programmierer kämpften mit dem Problem: Wie kann man die Dose zuverlässig von anderen roten Gegenständen (Feuerlöscher, rote Tasse, Plastikstück) bei unterschiedlichen Lichtverhältnissen unterscheiden?
In diesem Artikel geben wir nicht nur einen fertigen C++-Code mit OpenCV. Wir analysieren Schritt für Schritt die Bildverarbeitungsalgorithmen, die einen rohen Videostream in eine sichere Erkennung verwandeln. Sie erfahren, wie Sie die Erkennungsgenauigkeit verbessern, Fehlalarme vermeiden und Code schreiben, der in Echtzeit funktioniert.
Das Problem: Warum einfache Methoden nicht funktionieren
Ein typischer Anfängerfehler ist es, ein Objekt nur anhand der Farbe zu finden. Zum Beispiel alle roten Pixel zu isolieren und darunter den größten Kontur zu suchen. Aber:
- Die Beleuchtung ändert sich – Rot sieht unter Tageslichtlampe und unter Sonne anders aus.
- Glanzlichter auf Metall – Die Dose reflektiert Licht, und ihre Farbe kann weiß oder orange erscheinen.
- Der Hintergrund rauscht – Rote T-Shirts, Stühle, Werbetafeln verwirren den Detektor.
- Die Form verzerrt sich – Die Dose kann gedreht, teilweise verdeckt oder deformiert sein.
Daher ist die Verbesserung des Erkennungsalgorithmus nicht nur das Einstellen von Schwellwerten, sondern eine Kombination von Methoden: Farbfilterung, Kontursuche, Form- und Texturanalyse.
Lösungsarchitektur: Von Pixeln zur Entscheidung
Wir erstellen eine Pipeline aus drei Schritten:
- Vorverarbeitung – Weichzeichnung, Umwandlung in HSV, Morphologie.
- Segmentierung – Identifizierung von Kandidaten nach Farbe und Konturen.
- Verifikation – Filterung nach Seitenverhältnis, Fläche, Texturmerkmalen.
Dieser Ansatz wird im maschinellen Sehen mit C++ für industrielle Aufgaben verwendet – von der Teilesortierung bis zur Qualitätskontrolle.
Schritt 1: Farbfilterung in HSV
Der erste und wichtigste Schritt ist die Umwandlung des Bildes von RGB in HSV (Hue, Saturation, Value). Warum? Weil HSV die Farbe (Farbton) von der Helligkeit trennt. Dies ermöglicht es, einen Bereich für die rote Farbe festzulegen, der bei unterschiedlicher Beleuchtung funktioniert.
#include <opencv2/opencv.hpp>using namespace cv;
Mat hsv, mask;cvtColor(src, hsv, COLOR_BGR2HSV);
// Bereich für die rote Farbe (zwei Intervalle aufgrund der HSV-Zyklizität)Scalar lower_red1 = Scalar(0, 70, 50);Scalar upper_red1 = Scalar(10, 255, 255);Scalar lower_red2 = Scalar(170, 70, 50);Scalar upper_red2 = Scalar(180, 255, 255);
Mat mask1, mask2;inRange(hsv, lower_red1, upper_red1, mask1);inRange(hsv, lower_red2, upper_red2, mask2);mask = mask1 | mask2;Beachten Sie: Die rote Farbe liegt an der Grenze des HSV (0 und 180 Grad), daher benötigen wir zwei Bereiche. Die Parameter Saturation (70) und Value (50) schließen zu blasse oder zu dunkle Pixel aus.
Schritt 2: Morphologie und Kontursuche
Nach der Maske erhalten wir ein binäres Bild, das jedoch Rauschen enthält. Wir wenden morphologisches Schließen (closing) an, um Löcher in der Dose zu füllen, und Öffnen (opening), um kleine Punkte zu entfernen.
Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));morphologyEx(mask, mask, MORPH_CLOSE, kernel);morphologyEx(mask, mask, MORPH_OPEN, kernel);