Automatische Kamera Kalibrierung

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen

Autor: Madlen Bartnick
Betreuer: Prof. Schneider

Motivation

Kameras haben intrinsische und extrinsische Parameter, welche kalibriert werden müssen.

Ziel

Matlab hat bereits eine Kalibriertoolbox. Diese soll nun so automatisiert werden, dass bei fester Kameraposition die intrinsischen und extrinsischen Parameter automatisch kalibriert werden.

Anforderungen

  1. Machen Sie sich mit der Kalibriertoolbox von Matlab bekannt.
  2. Anhand eines Referenzmusters, welches vor der Kamera an verschiedene Positionen bewegt wird, sollen die Kameraparameter bestimmt werden.
  3. Transformieren Sie das Referenzmuster aus der Kameraperspektive in Weltkoordinaten.
  4. Stellen Sie die Objekte im Sichtfeld in 3D metrisch dar.
  5. Schätzen Sie die Genauigkeit Ihres Algorithmus ab.
  6. Zeigen Sie, dass Objekte Bekannter Größe mit Ihrer Kalibrierung metrisch vermessen werden können.
  7. Wissenschaftliche Dokumentation als HSHL-Wiki Artikel
  8. Softwareentwicklung nach SDE Standard in SVN
  9. Funktionsnachweis als YouTube-Video (vgl. Veranstaltungsregeln)

Lösungen

Automatische Kamerakalibrierung anhand eines Referenzmusters

Zu Beginn des Matlab-Skripts wird eine Initialisierung vorgenommen, sodass alle Variablen im Workspace gelöscht, offene Fenster geschlossen und das Command Window geleert wird.


%% Initialisierung

clear all;
close all;
clc;


Der nachfolgende Bereich enthält Variablen, die die zur automatischen Kalibrierung verwendeten Daten enthalten. Dazu gehört die Anzahl der aufzunehmenden Bilder, die Zeit zwischen der Aufnahme dieser Bilder und die Größe der Schachbrettquadrate des verwendeten Referenzmusters.


%% Eingabe der Daten zur automatischen Kamerakalibrierung

amountOfImages = 5; % Anzahl der zur Kalibrierung aufzunehmenden Bilder
delaytime = 5;  % Verzögerung zwischen der Aufnahme der Kalibrierungsfotos
squareSize = 21;    % Größe der Schachbrettquadrate in mm


Im nächsten Schritt werden die Kalibrierungsbilder mittels Webcam erstellt. Dazu wird die Webcam aktiviert und in einen vorher erstellten Ordner gewechselt, in dem die Kalibrierungsbilder gespeichert werden sollen. In einer For-Schleife über die Anzahl der Bilder werden diese aufgenommen, auf dem Bildschirm ausgegeben und in dem zuvor erwähnten Ordner als .png Datei gespeichert.


%% Aufnehmen der Kalibrierungsbilder mittels Webcam

cam = webcam;   % Starten der Webcam
cd('Kalibrierung')  % Ordner zur Speicherung der Kalibrierungsbilder
    
for i= 1:amountOfImages
    
    img = snapshot(cam);    % Aufnahme des Webcam-Bildes
    imagesc(img);    % Ausgabe des Bildes
    axis image;  % Achsen an Größe des Bildes anpassen
    axis off;    % Skalierung der Achsen nicht anzeigen 
    
    char = int2str(i);   % Umwandeln des Bildindex in Text
    filename = (['image' char '.png']); % Zusammensetzen des Speichernamen des Bildes
    imwrite (img,filename)   % Speichern des Bildes
                            
    pause (delaytime);   % Zeit bis zur Aufnahme des nächsten Webcam-Bildes
    
end


Es folgt die Kalibrierung der zur Aufnahme verwendeten Webcam durch Erkennung des Referenzmusters auf den Kalibrierungsbildern. Dazu werden die Kalibrierungsbilder zuerst als Datastore eingelesen, sodass sie nachfolgenden Funktionen als eine Einheit übergeben werden können. Die nachfolgende Funktion "detectCheckerboardPoints" der Camera Calibration Toolbox von Matlab erkennt für jedes im Datastore eingelesene Bild die Ecken auf dem Referenzmuster sowie die Größe dieses Referenzmusters in Schachbrettquadraten. In der darauffolgenden Funktion "generateCheckerboardPoints" werden über die ermittelte Größe des Referenzmusters und die Größe der darauf enthaltenen Schachbrettquadrate die Weltkoordinaten der Ecken dieser Quadrate ermittelt. Zuletzt wird die Webcam mit der Funktion "estimateCameraParameters" über die Größe der Kalibrierungsbilder,und die Lage der darauf befindlichen Schachbrettecken, sowohl in Pixel- als auch in Weltkoordinaten kalibriert. Dabei werden die intrinsischen und extrinsischen Kameraparameter, die Linsenverzerrungskoeffizienten sowie die Genauigkeit des Kalibrierungsalgorithmus bestimmt.


%% Kalibrieren der Webcam durch Erkennung des Schachbrettmusters in den Kalibrierungsbildern

images = imageDatastore(fullfile('/Users/madlen/Desktop/DSB/User/SoSe2018/Madlen Bartnick/Kalibrierung'));  % Einrichten eines Datastores für die Kalibrierungsbilder

imageFileNames = images.Files;  % Einlesen der gespeicheten Kalibrierungsbilder

[imagePoints, boardSize ] = detectCheckerboardPoints(imageFileNames); % MATLAB Funktion zur automatischen Erkennung der Schachbrettecken in Pixelkoordinaten   
                                                                                      
worldPoints = generateCheckerboardPoints(boardSize,squareSize); % MATLAB Funktion zur Transformation der Schachbrettecken in Weltkoordinaten    
        
imageSize = [size(images, 1), size(images, 2)]; % Berechnung der Bildgröße

cameraParams = estimateCameraParameters(imagePoints, worldPoints, ...   % MATLAB Funktion zur Errechnung der Kameraparameter
                                      'ImageSize', imageSize);
Abb. 1 Bildschirmausgabe der Kalibrationsergebnisse



Im nachfolgenden Programmabschnitt wird die Ausgabe der Kalibrationsergebnisse in einem gemeinsamen Fenster realisiert. Dazu werden zum einen ein zur Kalibrierung aufgenommenes Bild, zum anderen dieses Bild mit den vom Kalibrierungsalgorithmus erkannten und reproduzierten Schachbrettecken ausgegeben. Eine weitere Grafik zeigt die extrinsischen Kameraparameter als 3D metrische Darstellung der Lage von Kamera und Kalibrierungsbilder zueinander. Ebenfalls wird ein Balkendiagramm ausgegeben, welches die Genauigkeit des Kalibrierungsalgorithmus für jedes Bild sowie den Durchschnitt aller verwendeten Bilder visualisiert.


Abb. 1 Zeigt die auf dem Bildschirm ausgegebenen Kalibrationsergebnisse.


%% Ausgabe der Kalibrationsergebnisse
    
figure('units','normalized','outerposition',[0 0 1 1]); % Ausgabe auf dem gesamten Bildschirm

% Ausgabe eines zur Kalibrierung verwendeten Bildes
ax(1)= subplot(2,2,1);
imshow(imageFileNames{1}); 
title('Erstes Kalibrationsbild');

% Ausgabe eines Kalibrierungsbildes mit erkannten und reproduzierten Schachbildecken
ax(2)= subplot(2,2,2);
imshow(imageFileNames{1}); 
hold on
plot(imagePoints(:, 1, 1), imagePoints(:, 2, 1), 'go');
plot(cameraParams.ReprojectedPoints(:, 1, 1), cameraParams.ReprojectedPoints(:, 2, 1), 'r+');
legend('Detected Points', 'ReprojectedPoints');
hold off
title('Erkanntes Schachbrett')

imagePoints = zeros; % Zurücksetzen der Bildpunktmatrix

% Ausgabe der extrinsischen Kameraparameter
ax(3)= subplot(2,2,3);
showExtrinsics(cameraParams);
title('Extrinsische Kameraparameter')
drawnow;

% Ausgabe der errechneten Genauigkeit in Pixel
ax(4)= subplot(2,2,4);
showReprojectionErrors(cameraParams);
title('Fehler bei Schachbrettreproduktion');


Metrische Vermessung einer Münze neben dem Referenzmuster

Zur metrischen Vermessung einer Münze wird das erste Kalibrierungsbild aus dem Datastore eingelesen. Es folgen mehrere Schritte der Bildverarbeitung, um die Münze im Bild zu segmentieren. Zuerst wird durch die Funktion " undistortImage " über die durch die Kalibration ermittelten Kameraparameter die Linsenverzerrung des Bildes korrigiert. Im nächsten Schritt wird das Bild vom RGB- in den HSV-Farbraum gewandelt, um es anschließend in ein Farbsättigungsbild umzuwandeln. Über die Farbsättigung lässt sich die Münze sehr gut vom schwarz-weißen Referenzmuster unterscheiden. Über die Funktion " graythresh " wird der optimale Schwellwert für Grauwerte in dem vorliegenden Farbsättigungsbild ermittelt. Mit Hilfe dieses Schwellwerts wird das Farbsättigungsbild in ein Binärbild gewandelt und damit die Segmentierung abgeschlossen.


%% Bearbeitung des Bildes zur Segmentierung einer Münze

image=imread(imageFileNames{1});    % Einlesen des ersten Kalibrierungbildes

correctedImage = undistortImage(image, cameraParams );    % MATLAB Funktion zur Beseitigung der Linsenverzerrung 

HSVImage= rgb2hsv(correctedImage);  % Umwandlung des Bildes vom RGB Farbraum in den HSV Farbraum     

saturationImage = HSVImage (:, :, 2);   % Umwandlung in ein Farbsättigungsbild    

threshold = graythresh(saturationImage);    % Automatische Bestimmung eines Schwellwerts für Grauwerte

binaryImage = (saturationImage > threshold);    % Umwandlung in ein Binärbild mittels Schwellwertoperation


Nach der Segmentierung der Münze im Bild muss diese im nächsten Programmabschnitt erkannt werden. Dazu wird zuerst eine Blob-Analyse durchgeführt, die zusammenhängende Segmente im Binärbild erkennt und die dazugehörigen Flächeninhalte und Positionen ausgibt. Die Blob-Analyse ist hier so konfiguriert, dass die Position der Segmente durch die Ecken eines an allen Seiten anliegenden Rechtecks beschrieben werden. Zudem ist eine Mindestgröße für zu die zu erkennenden Segmente von 200 Pixeln festgelegt. Pixel die


   
%% Erkennung der Münze im Bild   

blobAnalysis = vision.BlobAnalysis('AreaOutputPort', true,...   % MATLAB Funktion zur Erkennung von Segmenten
    'CentroidOutputPort', false,...
    'BoundingBoxOutputPort', true,...
    'MinimumBlobArea', 200, 'ExcludeBorderBlobs', true);

[areas, positions] = step(blobAnalysis, binaryImage);    % Fläche und Position der Segmente

[~, index] = sort(areas, 'Descend'); % Sortierung nach Größe der Fläche

positionOfCoin=positions(index(1:1),:); % Position des größten Elements ist Position der Münze

areaOfCoin= areas(index(1:1),:);    % Fläche des größten Elements ist Fläche der Münze

coinImage = insertObjectAnnotation(correctedImage, 'rectangle', ... % Hinzufügen eines Labels für die erkannte Münze
    positionOfCoin, 'Münze');


%% Vermessung der Münze

[imagePoints, boardSize] = detectCheckerboardPoints(image); % Erkennung der Schachbrettquadrate

[R, t] = extrinsics(imagePoints, worldPoints, cameraParams);    % Ermittlung der extrinsischen Kameraparameter bei Aufnahme des Bildes

upperLeftCornerX = positionOfCoin(1); 
upperLeftCornerY = positionOfCoin(2);
upperLeftCorner = [upperLeftCornerX,upperLeftCornerY];  % Labelecke oben links in Pixel

upperRightCornerX = positionOfCoin(1)+positionOfCoin(3); 
upperRightCornerY = positionOfCoin (2);
upperRightCorner = [upperRightCornerX, upperRightCornerY];  % Labelecke oben rechts in Pixel

upperCornersInPixel = [upperLeftCorner;upperRightCorner]; % Obere Labelecken in Pixel

upperCornersInWorld = pointsToWorld(cameraParams, R, t, upperCornersInPixel);   %  Transformieren der Labelecken in Weltkoordinaten

diffWorld = upperCornersInWorld(2, :) - upperCornersInWorld(1, :);  % Differenz zwischen oberen Labelecken in Weltkoordinaten

diameterInMillimeter = hypot(diffWorld(1), diffWorld(2));    % Euklidische Distanz zwischen oberen Labelecken entspricht dem Durchmesser der Münze in Weltkoordinaten (mm)


%% Ausgabe der Vermessungsergebnisse

% Ausgabe des Originalbildes bevor der Verarbeitung
figure('units','normalized','outerposition',[0 0 1 1]); % Ausgabe auf dem gesamten Bildschirm
ax(1)= subplot(2,2,1);
imshow(imageFileNames{1});
title('Original Bild')

% Ausgabe des Bildes nachdem die Linsenverzerrung korrigiert wurde
ax(2)= subplot(2,2,2);
imshow(correctedImage);
title('Verzerrungsfreies Bild')

% Ausgabe des zur Erkennung verwendeten Binärbildes
ax(3)= subplot(2,2,3);
imshow(binaryImage);
hold on;
title('Binärbild')

% Ausgabe des Bildes mit Label für die erkannte Münze
ax(4)= subplot(2,2,4);
imshow(coinImage);
title('Erkannte Münze')

% Ausgabe des Messergebnisses sowie des erwarteten Ergebnisses im Command Window
fprintf('Tatsächlicher Durchmesser der Münze: 29 mm\n');
fprintf('Gemessener Durchmesser der Münze: %0.2f mm\n', diameterInMillimeter);

%% Beenden 

cd('/Users/madlen/Desktop/DSB/User/SoSe2018/Madlen Bartnick')
delete(cam);

Weblinks

BSD-Lizenzbedingung BSD-Lizenz

Copyright (c) 2014, Hochschule Hamm-Lippstadt, Dep. Lip. 1, Prof. Schneider
Hochschule Hamm-Lippstadt. Alle Rechte vorbehalten.



→ zurück zum Hauptartikel: Digitale Signal- und Bildverarbeitung SoSe2018