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 Kalibrierung anhand eines Referenzmusters

%% Initialisierung

clear all;
close all;
clc;

%% Eingabe der Daten

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

%% Aufnehmen der Kalibrierungsbilder mittels Webcam

cam = webcam;   % Einlesen 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

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

images = imageDatastore(fullfile('/Users/madlen/Desktop/DSB/User/SoSe2018/Madlen Bartnick/Kalibrierung'));
imageFileNames = images.Files;  % Einlesen der gespeicheten Kalibrierungsbilder

 
    [imagePoints, boardSize,imagesUsed] = detectCheckerboardPoints(imageFileNames);      % MATLAB Funktion zur automatischen Erkennung der Schachbrettecken in Pixelkoordinaten
                                                                                         % imagePoints -> Bildpunkte der Schachbrettecken
                                                                                         % boardSize -> Anzahl der Schachbrettquadrate in X- & Y-Richtung

                                                                                         
    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);
                                  
%% 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

%% Bearbeitung des Bildes zur Segmentierung einer Münze

    % Eliminieren der Linsenverzerrung
    image=imread(imageFileNames{1});    
    [correctedImage, newOrigin] = undistortImage(image, cameraParams, 'OutputView', 'full'); % MATLAB Funktion zur Beseitigung von Linsenverzerrung
    
    % Umwandlung des Bildes vom RGB Farbraum in den HSV Farbraum 
    HSVImage= rgb2hsv(correctedImage);    

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

    % Umwandlung in ein Binärbild mittels Schwellwertoperation
    threshold = graythresh(saturationImage);
    binaryImage = (saturationImage > threshold);
   
%% 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

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')

ax(2)= subplot(2,2,2);
imshow(correctedImage);
title('Verzerrungsfreies Bild')

ax(3)= subplot(2,2,3);
imshow(binaryImage);
hold on;
title('Binärbild')

ax(4)= subplot(2,2,4);
imshow(coinImage);
title('Erkannte Münze')

fprintf('Tatsächlicher Durchmesser der Münze: 29 mm\n');
fprintf('Gemessener Durchmesser der Münze: %0.2f mm\n', diameterInMillimeter);


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