Software des NXT 3D Laser Scanners: Unterschied zwischen den Versionen

Aus HSHL Mechatronik
Zur Navigation springen Zur Suche springen
(Die Seite wurde neu angelegt: „= Matlab code = %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Lego NXT Laser3DScanner % In Dieser Progra…“)
 
 
Zeile 1: Zeile 1:
= Matlab code =
= Matlab code =


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
%                    Lego NXT Laser3DScanner
                    Lego NXT Laser3DScanner
%    In Dieser Programmierung soll ein NXT angesteuert werden der     
    In Dieser Programmierung soll ein NXT angesteuert werden der     
%    ein Objekt dreht & eine Webcam, die das Objektaufnimmt um es  
    ein Objekt dreht & eine Webcam, die das Objektaufnimmt um es  
%    am Computer als 3D Figur anzeigt.
    am Computer als 3D Figur anzeigt.
%
 
% *  Authoren: Christoph Dörner & Michael Deitel
*  Authoren: Christoph Dörner & Michael Deitel
% *  Date: 01/12/2013 - 12/01/2014
*  Date: 01/12/2013 - 12/01/2014
% *  Hochschule Hamm-Lippstadt, www.hshl.de
*  Hochschule Hamm-Lippstadt, www.hshl.de
% *  basierend auf RWTH - Mindstorms NXT Toolbox:  
*  basierend auf RWTH - Mindstorms NXT Toolbox:  
% *  http://www.mindstorms.rwth-aachen.de
*  http://www.mindstorms.rwth-aachen.de
% *  MATLAB Image Acquisition Toolbox:
*  MATLAB Image Acquisition Toolbox:
% *  www.mathworks.com/products/imaq/?
*  www.mathworks.com/products/imaq/?
%
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 




Zeile 22: Zeile 22:




%Hauptprogramm:  
%Programm:  
 
% 1. Sicherstellung der Installation der RWTH-Mindstorm NXT Toolbox
% 1. Sicherstellung der Installation der RWTH-Mindstorm NXT Toolbox
% 2. Schließen aller bestehender Handle (falls diese existieren)
% 2. Schließen aller bestehender Handle (falls diese existieren)
% 3. NXT Verbindung herstellen
% 3. NXT Verbindung herstellen
% 4. Globale Bekanntmachung des NXT Handle
% 4. Globale Bekanntmachung des NXT Handle
% 5. Körper Rotieren lassen, Kamera aktivieren und Film aufnehmen
% 5. Körper Rotieren lassen, Kamera aktivieren und Film aufnehmen
% 6. Kamerawinkel wird gesetzt
% 6. Kamerawinkel wird gesetzt
% 7. Farbe des Lasers wird gesetzt
% 7. Farbe des Lasers wird gesetzt
% 8. Kalibrirungsbild wird zum ausgleichen der Kameraposition genommen,
% 8. Kalibrirungsbild wird zum ausgleichen der Kameraposition genommen,
%    falls diese schief zum Objekt steht
%    falls diese schief zum Objekt steht
% 9. Den Motormittelpunkt auswählen
% 9. Den Motormittelpunkt auswählen
%10. Den Bildbereich des Objektes auswählen
%10. Den Bildbereich des Objektes auswählen
%11. Bilder werden nach und nach in einer for-Schleife verarbeitet
%11. Bilder werden nach und nach in einer for-Schleife verarbeitet
%12. Dazu wird jedes in ein Binärbild von der Laserfarbe konvertiert
%12. Dazu wird jedes in ein Binärbild von der Laserfarbe konvertiert
%    und die Position der Laserlinie analysiert
%    und die Position der Laserlinie analysiert
%13. Nach der Schleife werden die Werte verechnet und in der
%13. Nach der Schleife werden die Werte verechnet und in der
%    3D-Grafik angezeigt
%    3D-Grafik angezeigt
Zeile 45: Zeile 59:


% Sicherstellung, dass die RWTH - Mindstorms NXT Toolbox installiert ist
% Sicherstellung, dass die RWTH - Mindstorms NXT Toolbox installiert ist
if verLessThan('RWTHMindstormsNXT', '2.00');
if verLessThan('RWTHMindstormsNXT', '2.00');
     error(strcat('This program requires the RWTH - Mindstorms NXT Toolbox ' ...
     error(strcat('This program requires the RWTH - Mindstorms NXT Toolbox ' ...
Zeile 52: Zeile 67:


% Schliessen alle bestehender Handle, falls diese existieren
% Schliessen alle bestehender Handle, falls diese existieren
COM_CloseNXT all
COM_CloseNXT all


% Vorbereitung des Arbeitsplatzes indem sicherheitshalber alle  
% Vorbereitung des Arbeitsplatzes indem sicherheitshalber alle  
% Variablen gelöscht und alle Fenster geschlossen werden
% Variablen gelöscht und alle Fenster geschlossen werden
close all
close all
clear all
clear all


% Öffnen der NXT Bluetooth Verbindung anhand der Initialisierungsdatei  
% Öffnen der NXT Bluetooth Verbindung anhand der Initialisierungsdatei  
  'bluetooth.ini'
  'bluetooth.ini'
handle = COM_OpenNXT('bluetooth.ini');
handle = COM_OpenNXT('bluetooth.ini');
Zeile 65: Zeile 83:
% Globale bekanntmachung des NXT Handle, damit alle nachfolgenden
% Globale bekanntmachung des NXT Handle, damit alle nachfolgenden
% Funktionen auf dieses Handle zugreifen können.
% Funktionen auf dieses Handle zugreifen können.
COM_SetDefaultNXT(handle);
COM_SetDefaultNXT(handle);


% Motoreinstellung (Grad der Umdrehung & Geschwindigkeit)
% Motoreinstellung (Grad der Umdrehung & Geschwindigkeit)
Fahrgeschwindigkeit    = -10;                  % Prozent
Fahrgeschwindigkeit    = -10;                  % Prozent
UmdrehungenInDeg        = 360;                    % Grad
UmdrehungenInDeg        = 360;                    % Grad
Zeile 78: Zeile 98:


% Initialisierung des Motors
% Initialisierung des Motors
Objekt.Stop('off');
Objekt.Stop('off');




% Öffnen der WebCam
% Öffnen der WebCam
vid = videoinput('winvideo',1,'YUY2_640x480');
vid = videoinput('winvideo',1,'YUY2_640x480');


% Bildrate festlegen
% Bildrate festlegen
framerate = 30;
framerate = 30;




% Aufnahmezeit und Anzahl der Bilder festlegen
% Aufnahmezeit und Anzahl der Bilder festlegen
set(vid,'FrameGrabInterval',1);
set(vid,'FrameGrabInterval',1);
capturetime = 5.5;
capturetime = 5.5;
Zeile 101: Zeile 125:


% Hier wird die Fahrt gestartet
% Hier wird die Fahrt gestartet
Objekt.SendToNXT();
Objekt.SendToNXT();


% Warte bis die Aufnahme beendet ist und dann fortfahren
% Warte bis die Aufnahme beendet ist und dann fortfahren
wait(vid,Inf);
wait(vid,Inf);
avi = get(vid,'DiskLogger');
avi = get(vid,'DiskLogger');
Zeile 111: Zeile 137:


%------------------Ende des Scanvorgangs------------------------
%------------------Ende des Scanvorgangs------------------------
%--------------Auswerten der .avi Videodatei in 3D---------------
%--------------Auswerten der .avi Videodatei in 3D---------------


Zeile 117: Zeile 144:


% Videodatei die analysiert werden soll
% Videodatei die analysiert werden soll
filename = 'Objekt.avi';
filename = 'Objekt.avi';


% Festlegung des Kamerawinkels (pi/4 (45°) wobei pi=180°)
% Festlegung des Kamerawinkels (pi/4 (45°) wobei pi=180°)
camAngle = pi/9;
camAngle = pi/9;


% Festlegung der Laserfarbe zum Orientieren Rot=1 Gruen=2 Blau=3
% Festlegung der Laserfarbe zum Orientieren Rot=1 Gruen=2 Blau=3
laserInd = 1;
laserInd = 1;


% Kalibrierungsframe
% Kalibrierungsframe
calFrame = 1;
calFrame = 1;




% Den Scanfilm aufrufen und den Laser herausfiltern
% Den Scanfilm aufrufen und den Laser herausfiltern
m = aviread(filename, calFrame);
m = aviread(filename, calFrame);
calImg = m.cdata(:,:,laserInd);
calImg = m.cdata(:,:,laserInd);


%Kalibrierungsbild anzeigen
%Kalibrierungsbild anzeigen
figure(1);
figure(1);
imshow(calImg);
imshow(calImg);
Zeile 141: Zeile 174:


% Bild rotieren
% Bild rotieren
figure(1);clf;
figure(1);clf;
calImg = imrotate(calImg, rotAngle);
calImg = imrotate(calImg, rotAngle);
Zeile 146: Zeile 180:


% Zentrierung bestimmen
% Zentrierung bestimmen
xlabel('Click mouse for center line');
xlabel('Click mouse for center line');
set(gcf, 'Pointer', 'fullcrosshair');
set(gcf, 'Pointer', 'fullcrosshair');
Zeile 152: Zeile 187:


% Zu interessierende Region lokalisieren
% Zu interessierende Region lokalisieren
xlabel('Draw rectangle over region of interest');
xlabel('Draw rectangle over region of interest');
rect = getrect;
rect = getrect;
Zeile 164: Zeile 200:
% Unschärfefilter erstellen um das Bild zu glätten
% Unschärfefilter erstellen um das Bild zu glätten
% bevor der Laser gefunden wird
% bevor der Laser gefunden wird
h = ones(5,1)/5;
h = ones(5,1)/5;


% Schwelle einstellen zum finden der Laserlinie
% Schwelle einstellen zum finden der Laserlinie
threshold = 0.1;
threshold = 0.1;


% Laserlinie finden
% Laserlinie finden
nfo = aviinfo(filename);
nfo = aviinfo(filename);
Nframes = 1;
Nframes = 1;
Zeile 175: Zeile 214:
for k=1:length(frameTab)
for k=1:length(frameTab)
     disp(sprintf('Analyzing frame #%d', frameTab(k)));
     disp(sprintf('Analyzing frame #%d', frameTab(k)));
     % Form vom Scanfilm erkennen
     % Form vom Scanfilm erkennen
     m = aviread(filename,frameTab(k));
     m = aviread(filename,frameTab(k));


     % Alles rausfiltern außer die Laserlinie & rotieren des Bildes
     % Alles rausfiltern außer die Laserlinie & rotieren des Bildes
     img = imrotate(m.cdata(:,:,laserInd), rotAngle);
     img = imrotate(m.cdata(:,:,laserInd), rotAngle);
      
      
     % Bild auf die uns interessierende Region schneiden
     % Bild auf die uns interessierende Region schneiden
     imgCrop = imcrop(img, rect);
     imgCrop = imcrop(img, rect);
      
      
Zeile 187: Zeile 230:
     % eine große zahl an Bildern haben und die Funktionen mit double
     % eine große zahl an Bildern haben und die Funktionen mit double
     % arbeiten
     % arbeiten
     imgFilt = filter2(h,im2double(imgCrop));
     imgFilt = filter2(h,im2double(imgCrop));
      
      
     % für jede Zeile maximale Bildintensität finden & dessen x-Position
     % für jede Zeile maximale Bildintensität finden & dessen x-Position
     [mx(k,:), rtmp(k,:)] = max(imgFilt');
     [mx(k,:), rtmp(k,:)] = max(imgFilt');


     % Sollten in der Laserlinie Löcher sein werden diese ausgefüllt
     % Sollten in der Laserlinie Löcher sein werden diese ausgefüllt
     if (length(find(mx(k,:)>threshold))>=2)
     if (length(find(mx(k,:)>threshold))>=2)
         r(k,:)=interp1(find(mx(k,:)>threshold),...
         r(k,:)=interp1(find(mx(k,:)>threshold),...
Zeile 201: Zeile 247:
      
      
     % Bild Zeichnen und Laserlinie berechnen
     % Bild Zeichnen und Laserlinie berechnen
     figure(2);clf;
     figure(2);clf;
     imshow(imgFilt);
     imshow(imgFilt);
Zeile 209: Zeile 256:
% X-Position der Laserlinie und des Bildes zum realen Radius  
% X-Position der Laserlinie und des Bildes zum realen Radius  
% konvertieren
% konvertieren
if xoffset>0
if xoffset>0
     R = (r+xoffset)./sin(camAngle);
     R = (r+xoffset)./sin(camAngle);
Zeile 217: Zeile 265:


% Konvertieren zu den Oberflächenkoordinaten
% Konvertieren zu den Oberflächenkoordinaten
X = R.*repmat(cos(theta),1,size(imgFilt,1));
X = R.*repmat(cos(theta),1,size(imgFilt,1));
Y = R.*repmat(sin(theta),1,size(imgFilt,1));
Y = R.*repmat(sin(theta),1,size(imgFilt,1));
Zeile 222: Zeile 271:


% Resultat (Scan) anzeigen
% Resultat (Scan) anzeigen
figure(22);
figure(22);
S = surf(X,Y,Z,R);
S = surf(X,Y,Z,R);
set(S, 'LineStyle', 'none');
set(S, 'LineStyle', 'none');
axis square;
axis square;

Aktuelle Version vom 24. Januar 2014, 15:40 Uhr

Matlab code

                   Lego NXT Laser3DScanner
    In Dieser Programmierung soll ein NXT angesteuert werden der     
    ein Objekt dreht & eine Webcam, die das Objektaufnimmt um es 
    am Computer als 3D Figur anzeigt.
*  Authoren: Christoph Dörner & Michael Deitel
*  Date: 01/12/2013 - 12/01/2014
*  Hochschule Hamm-Lippstadt, www.hshl.de
*  basierend auf RWTH - Mindstorms NXT Toolbox: 
*  http://www.mindstorms.rwth-aachen.de
*  MATLAB Image Acquisition Toolbox:
*  www.mathworks.com/products/imaq/?



%--------------------------Beginn Programm------------------------


%Programm:

% 1. Sicherstellung der Installation der RWTH-Mindstorm NXT Toolbox

% 2. Schließen aller bestehender Handle (falls diese existieren)

% 3. NXT Verbindung herstellen

% 4. Globale Bekanntmachung des NXT Handle

% 5. Körper Rotieren lassen, Kamera aktivieren und Film aufnehmen

% 6. Kamerawinkel wird gesetzt

% 7. Farbe des Lasers wird gesetzt

% 8. Kalibrirungsbild wird zum ausgleichen der Kameraposition genommen,

% falls diese schief zum Objekt steht

% 9. Den Motormittelpunkt auswählen

%10. Den Bildbereich des Objektes auswählen

%11. Bilder werden nach und nach in einer for-Schleife verarbeitet

%12. Dazu wird jedes in ein Binärbild von der Laserfarbe konvertiert % und die Position der Laserlinie analysiert

%13. Nach der Schleife werden die Werte verechnet und in der % 3D-Grafik angezeigt


%----------------Anfang des Scanvorgangs---------------------------


% Sicherstellung, dass die RWTH - Mindstorms NXT Toolbox installiert ist

if verLessThan('RWTHMindstormsNXT', '2.00');

   error(strcat('This program requires the RWTH - Mindstorms NXT Toolbox ' ...
       ,'version 2.00 or greater. Go to http://www.mindstorms.rwth-aachen.de' ...
       ,' and follow the installation instructions!'));

end

% Schliessen alle bestehender Handle, falls diese existieren

COM_CloseNXT all

% Vorbereitung des Arbeitsplatzes indem sicherheitshalber alle % Variablen gelöscht und alle Fenster geschlossen werden

close all clear all

% Öffnen der NXT Bluetooth Verbindung anhand der Initialisierungsdatei

'bluetooth.ini'

handle = COM_OpenNXT('bluetooth.ini');

% Globale bekanntmachung des NXT Handle, damit alle nachfolgenden % Funktionen auf dieses Handle zugreifen können.

COM_SetDefaultNXT(handle);

% Motoreinstellung (Grad der Umdrehung & Geschwindigkeit)

Fahrgeschwindigkeit = -10;  % Prozent UmdrehungenInDeg = 360;  % Grad

Objekt = NXTMotor(MOTOR_A);  % Motor A wird angesteuert Objekt.SpeedRegulation = false;  % Kein Sync Mode Objekt.Power = Fahrgeschwindigkeit; % Fahrgeschwindigkeit in Prozent Objekt.TachoLimit = UmdrehungenInDeg;  % Umdrehungen in Deg Objekt.ActionAtTachoLimit = 'Brake';  % Nicht auslaufen

% Initialisierung des Motors

Objekt.Stop('off');


% Öffnen der WebCam

vid = videoinput('winvideo',1,'YUY2_640x480');

% Bildrate festlegen

framerate = 30;


% Aufnahmezeit und Anzahl der Bilder festlegen

set(vid,'FrameGrabInterval',1); capturetime = 5.5; interval = get(vid,'FrameGrabInterval'); numframes = floor(capturetime * framerate / interval) set(vid,'FramesPerTrigger',numframes); set(vid,'LoggingMode','disk'); avi = avifile('Objekt','fps',framerate); set(vid,'DiskLogger',avi); start(vid); pause(1.2);

% Hier wird die Fahrt gestartet

Objekt.SendToNXT();

% Warte bis die Aufnahme beendet ist und dann fortfahren

wait(vid,Inf); avi = get(vid,'DiskLogger'); avi = close(avi);

pause(5);

%------------------Ende des Scanvorgangs------------------------

%--------------Auswerten der .avi Videodatei in 3D---------------


% Parameter

% Videodatei die analysiert werden soll

filename = 'Objekt.avi';

% Festlegung des Kamerawinkels (pi/4 (45°) wobei pi=180°)

camAngle = pi/9;

% Festlegung der Laserfarbe zum Orientieren Rot=1 Gruen=2 Blau=3

laserInd = 1;

% Kalibrierungsframe

calFrame = 1;


% Den Scanfilm aufrufen und den Laser herausfiltern

m = aviread(filename, calFrame); calImg = m.cdata(:,:,laserInd);

%Kalibrierungsbild anzeigen

figure(1); imshow(calImg); xlabel({'Calibrate rotation of image.','Draw line from top to bottom that should be verticle.', 'Left click to start. Right click to end.'}); [rotX, rotY] = getline(1); rotAngle = 180/pi*atan2(rotY(2)-rotY(1),rotX(2)-rotX(1))-90;

% Bild rotieren

figure(1);clf; calImg = imrotate(calImg, rotAngle); imshow(calImg);

% Zentrierung bestimmen

xlabel('Click mouse for center line'); set(gcf, 'Pointer', 'fullcrosshair'); [x,y]=ginput(1); line([x, x], [1,size(calImg,2)]);

% Zu interessierende Region lokalisieren

xlabel('Draw rectangle over region of interest'); rect = getrect; if rect(1)>x

   xoffset = rect(1)-x;

else

   xoffset = (rect(1)+rect(3))-x;

end; rectangle('Position', rect, 'EdgeColor', [1,0,0]); set(gcf, 'Pointer', 'arrow');

% Unschärfefilter erstellen um das Bild zu glätten % bevor der Laser gefunden wird

h = ones(5,1)/5;

% Schwelle einstellen zum finden der Laserlinie

threshold = 0.1;

% Laserlinie finden

nfo = aviinfo(filename); Nframes = 1; frameTab = 1:Nframes:nfo.NumFrames; for k=1:length(frameTab)

   disp(sprintf('Analyzing frame #%d', frameTab(k)));
   % Form vom Scanfilm erkennen
   m = aviread(filename,frameTab(k));
   % Alles rausfiltern außer die Laserlinie & rotieren des Bildes
   img = imrotate(m.cdata(:,:,laserInd), rotAngle);
   
   % Bild auf die uns interessierende Region schneiden
   imgCrop = imcrop(img, rect);
   
   % Bild filtern & von uint8 nach double convertieren, da wir
   % eine große zahl an Bildern haben und die Funktionen mit double
   % arbeiten
   imgFilt = filter2(h,im2double(imgCrop));
   
   % für jede Zeile maximale Bildintensität finden & dessen x-Position
   [mx(k,:), rtmp(k,:)] = max(imgFilt');
   % Sollten in der Laserlinie Löcher sein werden diese ausgefüllt
   if (length(find(mx(k,:)>threshold))>=2)
       r(k,:)=interp1(find(mx(k,:)>threshold),...
           rtmp(k,find(mx(k,:)>threshold)),1:size(rtmp,2));
   else
       r(k,:)=zeros(1,size(rtmp,2));
   end;
   
   % Bild Zeichnen und Laserlinie berechnen
   figure(2);clf;
   imshow(imgFilt);
   hold on;
   plot(r(k,:),1:size(r,2),'r');

end;

% X-Position der Laserlinie und des Bildes zum realen Radius % konvertieren

if xoffset>0

   R = (r+xoffset)./sin(camAngle);

else

   R = (rect(3)-r-xoffset)./sin(camAngle);

end; theta = linspace(0,2*pi,length(frameTab))';

% Konvertieren zu den Oberflächenkoordinaten

X = R.*repmat(cos(theta),1,size(imgFilt,1)); Y = R.*repmat(sin(theta),1,size(imgFilt,1)); Z = -repmat(1:size(imgFilt,1),length(theta),1);

% Resultat (Scan) anzeigen

figure(22); S = surf(X,Y,Z,R); set(S, 'LineStyle', 'none'); axis square;