├── Arduino_Matlab_serial.ino ├── EyeTracking.m └── README.md /Arduino_Matlab_serial.ino: -------------------------------------------------------------------------------- 1 | 2 | 3 | //this code send outputs from matlab to arduino. Channel Available in arduino: 4 | // 2,3,4,5,6,7 5 | // this is becasue 0 and 1 doesen't works, and from 8 to 13 neither.Don't know why 6 | 7 | // in order to use these ports on matlab, see the matlab code in the folder 8 | 9 | int ledPin2 = 2; 10 | int ledPin3 = 3; 11 | int ledPin4 = 4; 12 | int ledPin5 = 5; 13 | int ledPin6 = 6; 14 | int ledPin7 = 7; 15 | 16 | int matlabData; 17 | 18 | void setup() 19 | { 20 | pinMode(ledPin2,OUTPUT); 21 | pinMode(ledPin3,OUTPUT); 22 | pinMode(ledPin4,OUTPUT); 23 | pinMode(ledPin5,OUTPUT); 24 | pinMode(ledPin6,OUTPUT); 25 | pinMode(ledPin7,OUTPUT); 26 | 27 | Serial.begin(9600); 28 | } 29 | 30 | void loop() 31 | { 32 | 33 | if(Serial.available()>0) // if there is data to read 34 | { 35 | matlabData=Serial.read(); // read data 36 | 37 | // pin da 2 a 4 38 | if (matlabData==3) 39 | digitalWrite(ledPin2,HIGH); // turn light on 40 | else if(matlabData==4) 41 | digitalWrite(ledPin2,LOW); // turn light off 42 | if(matlabData==5) 43 | analogWrite(ledPin3,255); // turn light on 44 | else if(matlabData==6) 45 | analogWrite(ledPin3,0); // turn light off 46 | else if (matlabData==7) 47 | digitalWrite(ledPin4,HIGH); // turn light on 48 | else if(matlabData==8) 49 | digitalWrite(ledPin4,LOW); // turn light off 50 | 51 | // pin da 5 a 7 52 | 53 | else if(matlabData==9) 54 | analogWrite(ledPin5,255); // turn light on 55 | else if(matlabData==10) 56 | analogWrite(ledPin5,0); // turn light off 57 | else if (matlabData==11) 58 | analogWrite(ledPin6,255); // turn light on 59 | else if(matlabData==12) 60 | analogWrite(ledPin6,0); // turn light off 61 | if(matlabData==13) 62 | digitalWrite(ledPin7,HIGH); // turn light on 63 | else if(matlabData=14) 64 | digitalWrite(ledPin7,LOW); // turn light off 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /EyeTracking.m: -------------------------------------------------------------------------------- 1 | 2 | % create an arduino object. instead of "/dev/cu.usbmodem1411','BaudRate" 3 | % use your serail port name. You can check it in arduino -> tools -> port. 4 | % Write the name of your port before the command 'BaudRate' in the 5 | % following string. 6 | 7 | ar = serial('/dev/cu.usbmodem1411','BaudRate',9600); 8 | % Check for the camera name with the command 9 | % webcamlist() in matlab. 10 | cameras= webcamlist(); 11 | % type "cameras" in the command window and see which camera correspond to your modified webcam. select that camera 12 | % just by entering the index within the curly brackets. 13 | % It could be 1, 2, 3... depends on hwo many webcams you have acctached on your computer 14 | mycamera = cameras{2} 15 | % create a 'cam' variable with your camera name 16 | cam = webcam(char(mycamera)) 17 | 18 | %check if the camera is positioned in the right way, with the focus on the 19 | %center of the eye. The "preview" command let you see what the camera see. 20 | preview(cam) 21 | 22 | %open arduino USB port 23 | fopen(ar); 24 | 25 | % send the pulse to the port number 2 of arduino 26 | fprintf(ar,'%s',char(3)); 27 | 28 | % preallocate the matrix with the cooridnates data 29 | coordinate = zeros(50,2); 30 | 31 | for i = 1:50; 32 | 33 | % take a snapshot 34 | img = snapshot(cam); 35 | 36 | % calculate the center of the image 37 | 38 | filas=size(img,1); 39 | columnas=size(img,2); 40 | % Center 41 | centro_fila=round(filas/2); 42 | centro_columna=round(columnas/2); 43 | figure(1); 44 | 45 | % transform the image in a BW image 46 | if size(img,3)==3 47 | la_imagen=rgb2gray(img); 48 | end 49 | 50 | piel=~im2bw(la_imagen,0.1); 51 | % -- 52 | piel=bwmorph(piel,'close'); 53 | piel=bwmorph(piel,'open'); 54 | piel=bwareaopen(piel,200); 55 | piel=imfill(piel,'holes'); 56 | 57 | % Tagged objects in BW image 58 | L=bwlabel(piel); 59 | % Get areas and tracking rectangle 60 | out_a=regionprops(L); 61 | % Count the number of objects 62 | N=size(out_a,1); 63 | while N < 1 || isempty(out_a) % Returns if no object in the image 64 | solo_cara=[ ]; 65 | continue 66 | end 67 | 68 | % Select the area 69 | areas=[out_a.Area]; 70 | [area_min pam_min]=min(areas); 71 | [area_max pam_max]=max(areas); 72 | 73 | % since there is a problem with the shades in the BW images (the algorithm detect the size of the black 74 | % shades in th eimage), we have to create an if statement where we declare that if the algorithm 75 | % detect a too big black area (threshold set on 10000), it has to consider the 76 | % smallest detected area as the pupil. 77 | % On the other hand, if the black area is below a treshold of 78 | % 10000 it considers the biggest black area as the pupil. 79 | 80 | if area_max > 10000; 81 | 82 | % show the BW image 83 | imagesc(la_imagen); 84 | colormap gray 85 | hold on 86 | % draw the red area around the pupil 87 | rectangle('Position',out_a(pam_min).BoundingBox,'EdgeColor',[1 0 0],... 88 | 'Curvature', [1,1],'LineWidth',2) 89 | centro=round(out_a(pam_min).Centroid); 90 | 91 | % detect the X and Y coordinates 92 | X=centro(1); 93 | Y=centro(2); 94 | 95 | % save X and Y coordinates in the coordinates matrix 96 | coordinate(i,1) = X; 97 | coordinate(i,2) = Y; 98 | 99 | % draw the cross at the center of the pupil 100 | plot(X,Y,'g+') 101 | % 102 | text(X+10,Y,['(',num2str(X),',',num2str(Y),')'],'Color',[1 1 1]) 103 | if Xcentro_columna && Ycentro_fila 108 | title('Bottom left') 109 | else 110 | title('Bottom right') 111 | end 112 | 113 | elseif area_max < 10000; 114 | 115 | % show the BW image 116 | imagesc(la_imagen); 117 | colormap gray 118 | hold on 119 | % draw the red area around the pupil 120 | rectangle('Position',out_a(pam_max).BoundingBox,'EdgeColor',[1 0 0],... 121 | 'Curvature', [1,1],'LineWidth',2) 122 | centro=round(out_a(pam_max).Centroid); 123 | 124 | % detect the X and Y coordinates 125 | X=centro(1); 126 | Y=centro(2); 127 | 128 | % save X and Y coordinates in the coordinates matrix 129 | coordinate(i,1) = X; 130 | coordinate(i,2) = Y; 131 | 132 | % draw the cross at the center of the pupil 133 | plot(X,Y,'g+') 134 | % 135 | text(X+10,Y,['(',num2str(X),',',num2str(Y),')'],'Color',[1 1 1]) 136 | if Xcentro_columna && Ycentro_fila 141 | title('Bottom left') 142 | else 143 | title('Bottom right') 144 | end 145 | 146 | end 147 | 148 | %% save current figure in a folder. IMPORTANT !!! Set your directory in the following command 149 | saveas(gcf,['name of your directory',sprintf('%03d', i),'.png']); 150 | 151 | end 152 | 153 | %close arduino port number 2 154 | fprintf(ar,'%s',char(4)); 155 | % close arduino USB port 156 | fclose(ar); 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Webcam_EyeTracker_Matlab_Arduino 2 | This is a tutorial for making a cheap eytracker with a webcam, Arduino and Matlab. Before running the matlab code connect Arduino to the computer and run the "Arduino_Matlab_serial.ino" file. This will allow you to make 3 | Arduino communicate with Matlab. Please follow the instructions in the Matlab code for 4 | tracking the eye movement. IMPORTANT NOTE: This is not a professional eyetracker, i just used it to monitor the position of the eye during an experiment. 5 | If you need to track a saccade, measure the number of fixations or a reaction time i suggest you to buy a professional eyetracker 6 | 7 | The youtube tutorial can be found at this link 8 | 9 | https://youtu.be/ztaJDjMQH68 10 | 11 | (Further info about Arduino Matlab communication without downloading any Matlab-Arduino toolbox 12 | can be found at this link https://www.youtube.com/watch?v=kr21ypVgb1M&t=13s) 13 | 14 | --------------------------------------------------------------------------------