Automatische Folienextraktion
Entstehung
Die Vorlesungsfolien für die Vorlesung Grundlagen der Bildverarbeitung und Mustererkennung wahren nur im Copy Shop in schlechter Qualität und zu überteuerten Preise erhältlich. Das führte dazu das wir uns entschieden die Folien während der Vorlesung mit Hilfe eine Digital Kamera mitzuschneiden. Schnell stellte sich dann aber heraus das die Korrektur der Folien (ausschneiden und perspektivisch Korrigieren) eine mühsame und eintönige Arbeit ist. Schnell kam der Gedanke das sich das auch irgendwie automatisieren lassen müsste. Es dauerte dann aber noch eine ganze Weile bis dann das Matlab-Skript welches unten zu finden ist fertig war.
Benutzung des Scriptes
Das Matlabscript ist einfach in die Datei correct_image.m zu kopieren und im Verzeichnis mit den zu korrigierenden Folien abzulegen. Anschließend muss man Matlab starten und in das entsprechende Verzeichnis wechseln. Ist dies geschehen wird das Script einfach mit "correct_image" aufgerufen. Daraufhin ließt das Script die Fotos von der Festplatte ein und versucht die Folien zu extrahieren. Während der automatischen Verarbeitung wird zu erst das Bild angezeigt welches gerade verarbeitet wird. Anschließend blendet Matlab die gefundene Folie ein mit dem ermittelten Folieneckpunkten. Sollte das Script eine ungereimtheit bei den Eckpunkten entdecken so wird der Benutzer aufgefordert die Eckpunkte mit Hand zu setzen. (Das Fenster hat keinen OK Button ... einfach die Eckpunkte hinziehen und dann aufs Kreuz oben rechts klicken). Zum Schluss blendet Matlab die extrahierte Folie ein. Alle korrigierten Folien werden mit einem "p" vor dem Dateinamen abgespeichert. Auf diese weiße wird verhindert das die Originalfolien überschrieben werden.
Sollte das Ergebnis nicht "zufriedenstellend" sein so kann ein automatischer Histogrammausgleich, vor der Bearbeitung mit dem Script, das Ergebnis deutlich verbessern.
Das Script
close all; clear all; img=regexp((ls('*.jpg')), '[\s]+', 'split'); images=size(img); for image=1:images(2)-1 I=imread(char(img(:,image))); imshow(I); drawnow; hold on; I2=rgb2gray(I); I2=im2bw(I2); %Create Black White Image from grayscale I2=imfill(I2,'holes'); %Fill all holes in the image boundaries = bwboundaries(I2); %find all bundarys tmp = size(boundaries); bound=[0 0]; for i=1:tmp(1,1) tmp2=size(boundaries{i}); if(tmp2(1,1)>bound(1,1)) bound(1,1)=tmp2(1,1); bound(1,2)=i; end end b = boundaries{bound(1,2)}; %take the largest boundary (thats the foile) plot(b(:,2),b(:,1),'g','LineWidth',3); s=size(b); %Caluculate the center of the folie mx = sum(b(:,1))/s(1); my = sum(b(:,2))/s(1); plot(my,mx,'+r','LineWidth',3); edges = zeros(4,3); % 1 = x, 2= y, 3 = dist for i = 1:s(1) if b(i,1)>=mx && b(i,2)>=my quad=1; elseif b(i,1)>=mx && b(i,2)<my quad=2; elseif b(i,1)<mx && b(i,2)>=my quad=3; elseif b(i,1)<mx && b(i,2)<my quad=4; end dist =(b(i,1)-mx)^2 + (b(i,2)-my)^2; if dist>edges(quad,3) edges(quad,3) = dist; edges(quad,1) = b(i,1); edges(quad,2) = b(i,2); end end plot(edges(1,2),edges(1,1),'+b','LineWidth',3); plot(edges(2,2),edges(2,1),'+b','LineWidth',3); plot(edges(3,2),edges(3,1),'+b','LineWidth',3); plot(edges(4,2),edges(4,1),'+b','LineWidth',3); drawnow; for i = 1:4 input_points(i,2) = edges(i,1); input_points(i,1) = edges(i,2); end %input_points(5,2) = mx; %input_points(5,1) = my; imsize = size(I); base_points(1,1) = imsize(2); base_points(1,2) = imsize(1); base_points(2,1) = 1; base_points(2,2) = imsize(1); base_points(3,1) = imsize(2); base_points(3,2) = 1; base_points(4,1) = 1; base_points(4,2) = 1; %base_points(5,1) = imsize(2)/2; %base_points(5,2) = imsize(1)/2; %[input_points, base_points]=cpselect(I, I, input_points, base_points,'wait',true); if(((edges(1,2)-edges(2,2))^2+(edges(1,1)-edges(2,1))^2)<500^2 ||((edges(1,2)-edges(3,2))^2+(edges(1,1)-edges(3,1))^2)<500^2 || ((edges(1,2)-edges(4,2))^2+(edges(1,1)-edges(4,1))^2)<500^2 ) [input_points, base_points]=cpselect(I, I, input_points, base_points,'wait',true); end TFORM = cp2tform( input_points,base_points, 'projective'); B = imtransform(I,TFORM,'XData',[1 imsize(2)],'YData',[1 imsize(1)]); hold off; %figure; imshow(B); drawnow; imwrite(B,char(strcat('p',img(:,image))),'jpg','Quality',50); end