Kodu: hareket_analizi_projesi Kodu: hareket_analizi_ikinci_proje
%% %YAPILACAK İŞLEMLER %1-basket atan resimleri matlab klasöründe olmalıdır. %2-hareket_analizi_projesi() çalıştırılır. %3-kalibrasyonu resimden dinamik yapmak için kalibrasyon_konum_belirleme() % fonksiyonu altında bulunan aşağıdaki kodu aktif hale getiriniz. % img_kalibrasyon = imread('kalibrasyon_C001H001S0001000001.jpg'); % imshow(img_kalibrasyon); % I = ginput(8); %BİRİNCİ AŞAMA VİDEO OLUŞTURMA %HesaplamalardanSonraVideonunResmineIsleme() fonksiyonu kullanılarak %sağda ve solda olmak üzere iki video ortaya çıkacaktır. %sağdaki videoda maskeleme işlemleri uygulanarak % Omuz, Dirsek, El Bileği ve Orta Parmağı olmak üzere 4 nokta(marker) bulunur. % bu noktaların neler olduğu ilk resimde tanımlanmıştır. % sonraki resimlerde kalman sayesinde otomatik bulunur. % kalman hangi noktanın nereye ait olduğunu tespit etmesinin yanında % maskeleme sonunda bulunamayan herhangi bir noktayı(marker) yerini tahmin % etmek için de kullanılır ki son resimde orta parmak noktası tespit % edilememiş tahmin edilmiştir. %soldaki videoda yüklenen resimlerden hiçbir maskeleme veya başka bir şey % uygulanmadan sadece noktaların(marker) isimleri yazılarak % belirginleştirilmiş ve her bir nokta ayrı renklerle temsil edilmiştir: % Omuz: MAGENTA % Dirsek: MAVİ % El Bileği: YEŞİL % Orta Parmağı: KIRMIZI % bu noktaları birleştirilen eklemler: BEYAZ % sonuç olarak soldaki video "final.avi" olarak kaydedilmektedir. %KALMAN KULLANILARAK ELDE EDİLEN VERİLERİN İŞLENMESİ %video oluşturulduktan sonra HesaplamalardanSonraVideonunResmineIsleme() %fonksiyonu altında bulunan aşağıdaki kod kullanılarak her bir resimdeki %centroidler(Omuz, Dirsek, El Bileği ve Orta Parmağı) yatay(x) ve düşey(y) %resim konumları bilgisi tutulmaktadır: % tum_resimlerin_centroidleri_omuz = [tum_resimlerin_centroidleri_omuz;1024-xs(1) ys(1)]; % tum_resimlerin_centroidleri_dirsek = [tum_resimlerin_centroidleri_dirsek;1024-xs(2) ys(2)]; % tum_resimlerin_centroidleri_el_bilegi = [tum_resimlerin_centroidleri_el_bilegi;1024-xs(3) ys(3)]; % tum_resimlerin_centroidleri_orta_parmak = [tum_resimlerin_centroidleri_orta_parmak;1024-xs(4) ys(4)]; %bu cetroid bilgileri ve kalibrasyon resim bilgisi kullanılarak aşağıdaki %kod ile resim konum verisinden gerçek dünya konum verisi elde edilmektedir. % H_konum_omuz = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_omuz,Tx,Ty); % H_konum_dirsek = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_dirsek,Tx,Ty); % H_konum_el_bilegi = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_el_bilegi,Tx,Ty); % H_konum_orta_parmak = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_orta_parmak,Tx,Ty); %konum verisinin zamana göre değişiminden hız bulunur: %yatayda hız % v_omuz_x % v_dirsek_x % v_el_bilegi_x % v_orta_parmak_x %düşeyde hız % v_omuz_y % v_dirsek_y % v_el_bilegi_y % v_orta_parmak_y %hızın zamana göre değişiminden ivme bulunur: %yatayda ivme % a_omuz_x % a_dirsek_x % a_el_bilegi_x % a_orta_parmak_x %düşeyde ivme % a_omuz_y % a_dirsek_y % a_el_bilegi_y % a_orta_parmak_y %herhangi iki noktaya ait açıyı bulmak için tanjant matematiksel işlemi %uygulandı. tanjant=eğim=(y1-y2)/(x1-x2) şeklindedir. %açıyı da tanjant tersi olan arctan kullanarak buluruz.(matlab→atand): % aci_omuz_dirsek = filtfilt(b,a,atand((H_konum_omuz(:,2)-H_konum_dirsek(:,2))./(H_konum_omuz(:,1)-H_konum_dirsek(:,1)))); % aci_dirsek_el_bilegi = filtfilt(b,a,atand((H_konum_dirsek(:,2)-H_konum_el_bilegi(:,2))./(H_konum_dirsek(:,1)-H_konum_el_bilegi(:,1)))); % aci_el_bilegi_orta_parmak = filtfilt(b,a,atand((H_konum_el_bilegi(:,2)-H_konum_orta_parmak(:,2))./(H_konum_el_bilegi(:,1)-H_konum_orta_parmak(:,1)))); %açıdan çizgisel hıv ve ivme değerleri bulundu. %TÜM VERİLER GRAFİK OLARAK GÖSTERİLDİ. %1.Grafik:Omuz, Dirsek, El Bileği ve Orta Parmağı yeryüzündeki hareketi %2.Grafik:Omuz, Dirsek, El Bileği ve Orta Parmağı yeryüzündeki yatay hızı %3.Grafik:Omuz, Dirsek, El Bileği ve Orta Parmağı yeryüzündeki düşey hızı %4.Grafik:Omuz, Dirsek, El Bileği ve Orta Parmağı yeryüzündeki yatay ivmesi %5.Grafik:Omuz, Dirsek, El Bileği ve Orta Parmağı yeryüzündeki düşey ivmesi %6.Grafik:dirsek açılarının zamana göre değişimi: % burada açıların pozitiften ani bir şekilde negatife gitmesinin nedeni % eğimden açıyı bulmaya çalıştığımızdan tan(90) sonucu tanımsızdır ve bu % tanımsızlık bu değere yakın derecelerde sapmalara neden olmaktadır. bir % çok yöntem deneme rağmen şimdilik bir çözümünü bulamadım. 90 derece % üzerine çıktığında atand fonksiyonunun tanjant üzelliği kullandığından % eksi cevap vermektedir. aslında buradaki eksi değer başka bir % matematiksel anlam ifade etmektedir bizim için bu dezavantajı yok etmek % için 180 derece azaltmayı toplam olarak eklersek bir çözüm elde ederiz. %7.Grafik:dirsek açısal hızının zamana göre değişimi %8.Grafik:dirsek açısal ivmesinin zamana göre değişimi function hareket_analizi_projesi() %tüm verileri temizle ve pencereleri kapat. clear; close all; video = true; % false yaparak kapatabiliriz if video %video kaydı için dosya açılıyor aviobj = VideoWriter('final.avi', ... 'Uncompressed AVI'); aviobj.FrameRate = 25; open(aviobj); end % video gösterilecek pencere ayarlanıyor. obj = SistemHazirla(); % boş bir dizi oluşturur. tracks = DiziOlustur(); %bu diziler gerçek konum belirlemek için kullanılacaktır. tum_resimlerin_centroidleri_omuz = []; tum_resimlerin_centroidleri_dirsek = []; tum_resimlerin_centroidleri_el_bilegi = []; tum_resimlerin_centroidleri_orta_parmak = []; nextId = 1; % sonraki bulunacak nokta % resim dosylarının adını yükleme resimDosyaYolu = dir(strcat(pwd,'\ender_sut_C001H001S0001*.jpg')); % Her bir resim için aşağıdaki işlem tekrarlanmaktadır. for resim_index = 1 : length(resimDosyaYolu) % tek bir resim yükleme filename = strcat(pwd,'\',resimDosyaYolu(resim_index).name); frame_orijinal=imread(filename); frame = frame_orijinal; [satir_max, sutun_max] = size(frame); % orijinal resimi maskeleme % yansıyan cisimleri marker görmesini engelleme % kotrol için aşağıdaki kodu kullanabilirsiniz: % I = rgb2gray(frame_orijinal); % [level EM] = graythresh(I); % resim_mask = im2bw(I,EM); % imshow(resim_mask); frame(1:50,:) = 0; frame(:,1:100) = 0; frame(:,1024+1:1024+100) = 0; frame(:,2048+1:2048+100) = 0; frame(600:satir_max,:) = 0; % resim temizlenip mask olarak geri gönderilmektedir. % centroids ve metin kutusu yeri belirlenmektedir. [centroids, bboxes, mask] = detectObjects(frame); % sınırlayacı kutuya göre kalman kullanarak centroidler tahmin %ediliyor. predictNewLocationsOfTracks(); %kalman kullanılarak noktalar tahmin ediliyor % [yapay zeka kullanılmaktadır. ] [assignments, unassignedTracks, unassignedDetections] = ... detectionToTrackAssignment(); % noktalar güncelleniyor updateAssignedTracks(); % atanmamış noktalar güncelleniyor updateUnassignedTracks(); % belirtilen yaşın üstünde atanmamışlar siliniyor. deleteLostTracks(); % yeni noktalar oluşturuluyor. createNewTracks(); % bulunan sonuç bilgileri orijinal resime uygulanıp % çizim ve metin verisi eklenerek gösterilmektedir. HesaplamalardanSonraVideonunResmineIsleme(); % orijinal resime eklenen çizimler % video olarak final.avi kaydedilmektedir. writeVideo(aviobj,frame_orijinal); % w = waitforbuttonpress ; end if video % video oluşturma işleminden sonra açık olanı objeyi kapatır. close(aviobj); end %kalibrasyon yapılmaktadır. % bu şekilde resim satır ve sütun bilgisi % yeryüzündeki konum bilgisine dönüştürülmektedir. kalibrasyon_konum_belirleme(); %% sistem hazırlanır. function obj = SistemHazirla() % gösterilecek figür(pencere) ayarlanıyor. obj.videoPlayer = vision.VideoPlayer('Position', [20, 20, 800, 1000]); obj.videoPlayermask = vision.VideoPlayer('Position', [820, 20, 800, 1000]); % [centroids, bboxes, mask] değerlerini bulmak için kullanılır. obj.blobAnalyser = vision.BlobAnalysis('BoundingBoxOutputPort', true, ... 'AreaOutputPort', true, 'CentroidOutputPort', true, ... 'MinimumBlobArea', 1); end %% tracks dizisinin değerleri: % % * |id| : her bir noktanın id bilgisi % * |bbox| : nesneleri gösterecek sınırları bilgisi % * |kalmanFilter| : hareket bazlı izlemek için kullanılan kalman % * |age| : ilk tespit edilmesinden bu yana frame sayısı % * |totalVisibleCount| : görünen parça tespit edilen toplam frame sayısı % * |consecutiveInvisibleCount| : nokta tespit edilmeyen ardışık frame sayısı function tracks = DiziOlustur() % boş bir dizi oluşturmakta tracks = struct(... 'id', {}, ... 'bbox', {}, ... 'kalmanFilter', {}, ... 'age', {}, ... 'totalVisibleCount', {}, ... 'consecutiveInvisibleCount', {}); end %% resmi temizleme ve noktaları bulma % her bir fotoğraf için tek bir framede % centroids(bulunan noktaların merkez bilgisi) % bboxes(nesneleri sınırları bilgisi) % mask(framemin gri modda maskelenmiş ve temizlenmiş hali) function [centroids, bboxes, mask] = detectObjects(frame) %gri moda çevirme I = rgb2gray(frame); %eşik değeri belirleme [level EM] = graythresh(I); %belirlenen eşik değerine göre gereksiz noktaları temizleme mask = im2bw(I,EM); mask = medfilt2(mask,[3 3]); % 4 piksel den küçük kod topluluklarını sil mask = bwareaopen(mask,4); % blobAnalyser kullanarak [centroids, bboxes, mask] değerlerini % bulma [~, centroids, bboxes] = obj.blobAnalyser.step(mask); end %% Mevcut parçalardan yeni yerin tahmini % kalman filtresi kullanılarak geçmişteki nokların bilgisinden faydalanarak % framedeki noktaların yerlerini tespit etme. function predictNewLocationsOfTracks() for i = 1:length(tracks) bbox = tracks(i).bbox; % noktanın mevcut konumunu kalman ile tahmin etme. predictedCentroid = predict(tracks(i).kalmanFilter); % sınırı belirlenmiş kutu(bbox)kullanılarak merkezi konumunu tahim. predictedCentroid = int32(predictedCentroid) - bbox(3:4) / 2; tracks(i).bbox = [predictedCentroid, bbox(3:4)]; end end %% atanmış noktaları tespit etme function [assignments, unassignedTracks, unassignedDetections] = ... detectionToTrackAssignment() nTracks = length(tracks); nDetections = size(centroids, 1); % her bir izin değerini hesaplama cost = zeros(nTracks, nDetections); for i = 1:nTracks cost(i, :) = distance(tracks(i).kalmanFilter, centroids); end % yaratılan değerlerden atama yapılması işlemi. costOfNonAssignment = 20; [assignments, unassignedTracks, unassignedDetections] = ... assignDetectionsToTracks(cost, costOfNonAssignment); end %% atanmış izleri güncelliyor function updateAssignedTracks() numAssignedTracks = size(assignments, 1); for i = 1:numAssignedTracks trackIdx = assignments(i, 1); detectionIdx = assignments(i, 2); centroid = centroids(detectionIdx, :); bbox = bboxes(detectionIdx, :); % her bir noktanın yeri tanımlanıyor ve doğrulama işlemi % gerçekleştiriliyor. correct(tracks(trackIdx).kalmanFilter, centroid); % yeni sınır değerleri benirleniyor. tracks(trackIdx).bbox = bbox; % Update track's age. tracks(trackIdx).age = tracks(trackIdx).age + 1; % erişebilirlilik güncelleniyor. tracks(trackIdx).totalVisibleCount = ... tracks(trackIdx).totalVisibleCount + 1; tracks(trackIdx).consecutiveInvisibleCount = 0; end end %% Tespit edilemeyen izler güncelleniyor. % belli yaşın üstündekilerin silinmesi için bu izlerin yaşları atanıyor function updateUnassignedTracks() for i = 1:length(unassignedTracks) ind = unassignedTracks(i); tracks(ind).age = tracks(ind).age + 1; tracks(ind).consecutiveInvisibleCount = ... tracks(ind).consecutiveInvisibleCount + 1; end end %% Kayıp izler siliniyor % belli bir yaşın üstüne(bulunmama) çıkan izler silinmektedir. function deleteLostTracks() if isempty(tracks) return; end invisibleForTooLong = 20; ageThreshold = 8; % Compute the fraction of the track's age for which it was visible. ages = [tracks(:).age]; totalVisibleCounts = [tracks(:).totalVisibleCount]; visibility = totalVisibleCounts ./ ages; % Find the indices of 'lost' tracks. lostInds = (ages < ageThreshold & visibility < 0.6) | ... [tracks(:).consecutiveInvisibleCount] >= invisibleForTooLong; % Delete lost tracks. tracks = tracks(~lostInds); end %% yeni izler oluşturma % Create new tracks from unassigned detections. Assume that any unassigned % detection is a start of a new track. In practice, you can use other cues % to eliminate noisy detections, such as size, location, or appearance. function createNewTracks() centroids = centroids(unassignedDetections, :); bboxes = bboxes(unassignedDetections, :); for i = 1:size(centroids, 1) centroid = centroids(i,:); bbox = bboxes(i, :); % Create a Kalman filter object. kalmanFilter = configureKalmanFilter('ConstantVelocity', ... centroid, [200, 50], [100, 25], 100); % Create a new track. newTrack = struct(... 'id', nextId, ... 'bbox', bbox, ... 'kalmanFilter', kalmanFilter, ... 'age', 1, ... 'totalVisibleCount', 1, ... 'consecutiveInvisibleCount', 0); % Add it to the array of tracks. tracks(end + 1) = newTrack; % Increment the next id. nextId = nextId + 1; end end %% Tespit edilen noktaları işaretleme ve yazı ile belirme % her bir frame için tespit veya tahmin edilen noktalar işaretlenmektedir % bu noktaların ne olduğu yazılmaktadır. function HesaplamalardanSonraVideonunResmineIsleme() % kalibre etme dizisi vucut = {'Omuz', 'Dirsek', 'El Bilegi', 'Orta Parmak'}; % renklerin ingilizce olarak ilk harflerini kullan. renkler={'magenta', 'blue', 'green', 'red'}; % Convert the frame and the mask to uint8 RGB. frame = im2uint8(frame); mask = uint8(repmat(mask, [1, 1, 3])) .* 255; minVisibleCount = 0; if ~isempty(tracks) % Noisy detections tend to result in short-lived tracks. % Only display tracks that have been visible for more than % a minimum number of frames. reliableTrackInds = ... [tracks(:).totalVisibleCount] > minVisibleCount; reliableTracks = tracks(reliableTrackInds); % Display the objects. If an object has not been detected % in this frame, display its predicted bounding box. if ~isempty(reliableTracks) % Get bounding boxes. bboxes = cat(1, reliableTracks.bbox); % Get ids. % ids = int32([reliableTracks(:).id]); % Draw the objects on the mask. xs = bboxes(:,1) + round(bboxes(:,3)/2); ys = bboxes(:,2) + round(bboxes(:,4)/2); line_xy(1,:) = [xs(1) ys(1) xs(2) ys(2)]; line_xy(2,:) = [xs(2) ys(2) xs(3) ys(3)]; line_xy(3,:) = [xs(3) ys(3) xs(4) ys(4)]; % line_xy(2,:) = [bboxes(2,1:2) bboxes(3,1:2)]; % line_xy(3,:) = [bboxes(3,1:2) bboxes(4,1:2)]; koordinat1 = [' x:',int2str(xs(1)),' y:',int2str(ys(1))]; koordinat2 = [' x:',int2str(xs(2)),' y:',int2str(ys(2))]; koordinat3 = [' x:',int2str(xs(3)),' y:',int2str(ys(3))]; koordinat4 = [' x:',int2str(xs(4)),' y:',int2str(ys(4))]; labels = strcat(vucut, {koordinat1,koordinat2,koordinat3,koordinat4}); frame_orijinal = insertShape(frame_orijinal, 'line', line_xy, 'Color','white', 'LineWidth', 5); % mask = insertObjectAnnotation(mask, 'rectangle', ... % bboxes, labels,'Color',renkler(ids'),'TextColor','yellow','TextBoxOpacity', 0.5); frame_orijinal = insertObjectAnnotation(frame_orijinal, 'circle', ... [xs,ys, ones(length(xs),1)*3], labels,'Color',renkler,'TextColor','yellow','TextBoxOpacity', 0.5); mask = insertShape(mask, 'line', line_xy, 'Color','white', 'LineWidth', 5); % mask = insertObjectAnnotation(mask, 'rectangle', ... % bboxes, labels,'Color',renkler(ids'),'TextColor','yellow','TextBoxOpacity', 0.5); mask = insertObjectAnnotation(mask, 'circle', ... [xs,ys, ones(length(xs),1)*3], labels,'Color',renkler,'TextColor','yellow','TextBoxOpacity', 0.5); tum_resimlerin_centroidleri_omuz = [tum_resimlerin_centroidleri_omuz;1024-xs(1) ys(1)]; tum_resimlerin_centroidleri_dirsek = [tum_resimlerin_centroidleri_dirsek;1024-xs(2) ys(2)]; tum_resimlerin_centroidleri_el_bilegi = [tum_resimlerin_centroidleri_el_bilegi;1024-xs(3) ys(3)]; tum_resimlerin_centroidleri_orta_parmak = [tum_resimlerin_centroidleri_orta_parmak;1024-xs(4) ys(4)]; end end % videoyu göster. obj.videoPlayer.step(frame_orijinal); obj.videoPlayermask.step(mask); end %% hız ve ivme hesaplaması function P = calculate_conformal(I, S, method) %' Conformal Map Transformation '; %' Serdar Aritan 2009 BAG '; %' ---------------------------------- '; %' Image Coordinates of Calibration Points : I'; %' Space Coordinates of Calibration Points : S'; [rS, cS] = size(S); [rI, cI] = size(I); % check the matrix size if cS ~= cI || rS ~= rI error('matrix dimension'); end % Coefficients Matrix A =[I(:,1) -I(:,2) ones(rI,1) zeros(rI,1); I(:,2) I(:,1) zeros(rI,1) ones(rI,1)]; % There are two type of solutions for over determined systems of eq. % 1. Least Square Method [ \ ] % 2. Psedou Inverse [ pinv() ] if method == 1 P = A\S(:); %S = [S(:)]; % x(1), ... ,x(n) , y(1), ... , y(n) elseif method == 2 P = pinv(A)*S(:); else disp('missing method!!'); end end function H = calculate_reconformal(P, I,Tx,Ty) %' Conformal Map Transformation '; %' Serdar Aritan 2009 BAG '; %' ---------------------------------- '; %' Image Coordinates of Data Points : I'; %' Conformal Coefficients : P'; [rI, cI] = size(I); % Coefficients Matrix A =[I(:,1) -I(:,2) ones(rI,1) zeros(rI,1) ; I(:,2) I(:,1) zeros(rI,1) ones(rI,1)]; %buradaki veriler double veritipine dönüştürüldü. H = double(A)*double(P); H = [H(1:length(H)/2) H((length(H)/2)+1:end)]; % öteleme işlemi uygulanmaktadır. % H = [(H(:,1)+Tx) (H(:,2)+Ty)]; end function kalibrasyon_konum_belirleme() close all;clear; % kalibrasyon için sırasıyla belirtilen 8 noktayı seç % img_kalibrasyon = imread('kalibrasyon_C001H001S0001000001.jpg'); % imshow(img_kalibrasyon); % I = ginput(8); I =[ 151.1764 902.3097 149.6772 783.8675 148.1779 497.5073 140.6816 254.6259 576.9685 983.2701 573.9700 699.9085 573.9700 536.4883 569.4722 293.6069]; S = [2.5 30 2.5 60 2.5 130 2.5 190 108 10 108 80 108 120 108 180]; % kalibrasyon noktalarının gerçek konum değerleri bir diziye atılmaktadır. % S=dlmread('kalib_statik.txt'); diğer problem içindir bu % İki-Boyutlu Uyum Dönüşümü (2D Conformal Transformation) % Dört-parametreli benzerlik dönüşümü olarak da bilinir % Bu dönüşüm 3 basamaktan oluşmaktadır: uyum_donusumu = calculate_conformal(I, S, 1); % 1.Dönme : iki sistemin referans eksenlerini paralel yapmak için donme_acisi = atand(uyum_donusumu(2)/uyum_donusumu(1)); % 2.Ölçekleme : iki koordinat sisteminde denk boyut yaratmak için olceklendirme = uyum_donusumu(1)/cosd(donme_acisi); % 3.Öteleme: iki koordinat sisteminde ortak bir başlangıç noktası yaratmak için Tx = uyum_donusumu(3); Ty = uyum_donusumu(4); % konum, hız ve ivme hesaplamalarını yapalım. H_konum_omuz = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_omuz,Tx,Ty); H_konum_dirsek = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_dirsek,Tx,Ty); H_konum_el_bilegi = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_el_bilegi,Tx,Ty); H_konum_orta_parmak = calculate_reconformal(uyum_donusumu, tum_resimlerin_centroidleri_orta_parmak,Tx,Ty); % omuz hız ve ivme hesaplanması for i = 1 :length(H_konum_omuz)-1 % hız hesaplanması v_omuz_x(i) = H_konum_omuz(i+1,1) - H_konum_omuz(i,1); v_omuz_y(i) = H_konum_omuz(i+1,2) - H_konum_omuz(i,2); end for i = 1 :length(v_omuz_x)-1 % ivme hesaplanması a_omuz_x(i) = v_omuz_x(i+1) - v_omuz_x(i); a_omuz_y(i) = v_omuz_y(i+1) - v_omuz_y(i); end % dirsek hız ve ivme hesaplanması for i = 1 :length(H_konum_dirsek)-1 % hız hesaplanması v_dirsek_x(i) = H_konum_dirsek(i+1,1) - H_konum_dirsek(i,1); v_dirsek_y(i) = H_konum_dirsek(i+1,2) - H_konum_dirsek(i,2); end for i = 1 :length(v_dirsek_x)-1 % ivme hesaplanması a_dirsek_x(i) = v_dirsek_x(i+1) - v_dirsek_x(i); a_dirsek_y(i) = v_dirsek_y(i+1) - v_dirsek_y(i); end % el bileği hız ve ivme hesaplanması for i = 1 :length(H_konum_el_bilegi)-1 % hız hesaplanması v_el_bilegi_x(i) = H_konum_el_bilegi(i+1,1) - H_konum_el_bilegi(i,1); v_el_bilegi_y(i) = H_konum_el_bilegi(i+1,2) - H_konum_el_bilegi(i,2); end for i = 1 :length(v_el_bilegi_x)-1 % ivme hesaplanması a_el_bilegi_x(i) = v_el_bilegi_x(i+1) - v_el_bilegi_x(i); a_el_bilegi_y(i) = v_el_bilegi_y(i+1) - v_el_bilegi_y(i); end % orta parmak hız ve ivme hesaplanması for i = 1 :length(H_konum_orta_parmak)-1 % hız hesaplanması v_orta_parmak_x(i) = H_konum_orta_parmak(i+1,1) - H_konum_orta_parmak(i,1); v_orta_parmak_y(i) = H_konum_orta_parmak(i+1,2) - H_konum_orta_parmak(i,2); end for i = 1 :length(v_orta_parmak_x)-1 % ivme hesaplanması a_orta_parmak_x(i) = v_orta_parmak_x(i+1) - v_orta_parmak_x(i); a_orta_parmak_y(i) = v_orta_parmak_y(i+1) - v_orta_parmak_y(i); end % Buuterworth süzgeç parametrelerini belirle. [b,a]= butter(2,6/25,'low'); % Verileri suzgecten gecir. tan_omuz_dirsek = (H_konum_omuz(:,2)-H_konum_dirsek(:,2))./(H_konum_omuz(:,1)-H_konum_dirsek(:,1)); tan_dirsek_el_bilegi = (H_konum_dirsek(:,2)-H_konum_el_bilegi(:,2))./(H_konum_dirsek(:,1)-H_konum_el_bilegi(:,1)); tan_bilegi_orta_parmak = (H_konum_el_bilegi(:,2)-H_konum_orta_parmak(:,2))./(H_konum_el_bilegi(:,1)-H_konum_orta_parmak(:,1)); aci_omuz_dirsek = filtfilt(b,a,atand(tan_omuz_dirsek)); aci_dirsek_el_bilegi = filtfilt(b,a,atand(tan_dirsek_el_bilegi)); aci_el_bilegi_orta_parmak = filtfilt(b,a,atand(tan_bilegi_orta_parmak)); %eklemlerin geri hareklerinde oluşan hatayı yok etme. % onceki_isaret_omuz_dirsek=sign(aci_omuz_dirsek(1)); % onceki_isaret_dirsek_el_bilegi=sign(aci_dirsek_el_bilegi(1)); % onceki_isaret_el_bilegi_orta_parmak=sign(aci_el_bilegi_orta_parmak(1)); kritik_derece_omuz_dirsek = 0; kritik_derece_dirsek_el_bilegi = 0; kritik_derece_el_bilegi_orta_parmak = 0; % isaret_degistir_omuz_dirsek = 0; % isaret_degistir_dirsek_el_bilegi = 0; % isaret_degistir_el_bilegi_orta_parmak = 0; for i=2:length(aci_omuz_dirsek) if(aci_omuz_dirsek(i)>= 90) kritik_derece_omuz_dirsek = 1; end if(aci_dirsek_el_bilegi(i)>= 90) kritik_derece_dirsek_el_bilegi = 1; end if(aci_el_bilegi_orta_parmak(i)>= 90) kritik_derece_el_bilegi_orta_parmak = 1; end if(kritik_derece_omuz_dirsek) aci_omuz_dirsek(i) = aci_omuz_dirsek(i)+180; end if(kritik_derece_dirsek_el_bilegi) aci_dirsek_el_bilegi(i) = aci_dirsek_el_bilegi(i)+180; end if(kritik_derece_el_bilegi_orta_parmak) aci_el_bilegi_orta_parmak(i) = aci_el_bilegi_orta_parmak(i)+180; end end % Açısal hızın fizikteki tanımı; açısal yer değiştirmenin zaman içersindeki değişimidir. % Açısal hız bir cismin bir eksen üzerindeki dönüş yönünü ve süratini verir. % Açısal hızın SI birimi radyan/saniyedir ancak elbette başka birimlerdede ölçülebilir % (açı/saniye, açı/saat gibi). Açısal hız genellikle omega sembolü (?, bazen ?) ile gösterilir. % Açısal hızın yönü genellikle dönüş düzlemine diktir ve sağ el kuralı ile bulunabilir. % Açısal hız for i=1:length(aci_omuz_dirsek)-1 v_omuz_dirsek(i) = aci_omuz_dirsek(i+1) - aci_omuz_dirsek(i); v_dirsek_el_bilegi(i) = aci_dirsek_el_bilegi(i+1) - aci_dirsek_el_bilegi(i); v_el_bilegi_orta_parmak(i) = aci_el_bilegi_orta_parmak(i+1) - aci_el_bilegi_orta_parmak(i); end % Açısal İvme for i=1:length(v_omuz_dirsek)-1 a_omuz_dirsek(i) = v_omuz_dirsek(i+1) - v_omuz_dirsek(i); a_dirsek_el_bilegi(i) = v_dirsek_el_bilegi(i+1) - v_dirsek_el_bilegi(i); a_el_bilegi_orta_parmak(i) = v_el_bilegi_orta_parmak(i+1) - v_el_bilegi_orta_parmak(i); end %konum close all; hold on; axis equal; grid on; figure(1), plot(H_konum_omuz(:,1),H_konum_omuz(:,2), 'mo'); hold on; axis equal; grid on; figure(1), plot(H_konum_dirsek(:,1),H_konum_dirsek(:,2), 'b+'); figure(1), plot(H_konum_el_bilegi(:,1),H_konum_el_bilegi(:,2), 'g*'); figure(1), plot(H_konum_orta_parmak(:,1),H_konum_orta_parmak(:,2), 'r.'); % Grafiğe başlık ekleyelim: xlabel('düşeyde aldığı yol (x)') ylabel('yatayda aldığı yol (y)') title('Konum Grafiği') legend('Omuz', 'Dirsek', 'El Bileği', 'Orta Parmağı'); %yatayda hız figure(2), plot(v_omuz_x, 'mo'); hold on; axis equal; grid on; figure(2), plot(v_dirsek_x, 'b+'); figure(2), plot(v_el_bilegi_x, 'g*'); figure(2), plot(v_orta_parmak_x, 'r.'); % Grafiğe başlık ekleyelim: xlabel('zaman') ylabel('hız') title('Yatayda Hız Grafiği') legend('Omuz', 'Dirsek', 'El Bileği', 'Orta Parmağı'); %düşeyde hız figure(3), plot(v_omuz_y, 'mo'); hold on; axis equal; grid on; figure(3), plot(v_dirsek_y,'b+'); figure(3), plot(v_el_bilegi_y, 'g*'); figure(3), plot(v_orta_parmak_y, 'r.'); % Grafiğe başlık ekleyelim: xlabel('zaman') ylabel('hız') title('Düşeyde Hız Grafiği') legend('Omuz', 'Dirsek', 'El Bileği', 'Orta Parmağı'); %yatayda ivme figure(4), plot(a_omuz_x, 'mo'); hold on; axis equal; grid on; figure(4), plot(a_dirsek_x, 'b+'); figure(4), plot(a_el_bilegi_x, 'g*'); figure(4), plot(a_orta_parmak_x, 'r.'); % Grafiğe başlık ekleyelim: xlabel('zaman') ylabel('ivme') title('Yatayda İvme Grafiği') legend('Omuz', 'Dirsek', 'El Bileği', 'Orta Parmağı'); %düşeyde ivme figure(5), plot(a_omuz_y, 'mo'); hold on; axis equal; grid on; figure(5), plot(a_dirsek_y, 'b+'); figure(5), plot(a_el_bilegi_y, 'g*'); figure(5), plot(a_orta_parmak_y, 'r.'); xlabel('zaman') ylabel('ivme') title('Düşeyde İvme Grafiği') legend('Omuz', 'Dirsek', 'El Bileği', 'Orta Parmağı'); % parçaların açıları figure(6), plot(aci_omuz_dirsek, 'mo'); hold on; axis equal; grid on; %dirsek figure(6), plot(aci_dirsek_el_bilegi, 'b+'); % el bileği figure(6), plot(aci_el_bilegi_orta_parmak, 'g*'); xlabel('zaman') ylabel('derece') title('Eklemlerin Açı Grafiği') legend('Omuz Dirsek','Dirsek El bilegi','El bilegi Orta parmak'); % açısal hız grafiği figure(7), plot(v_omuz_dirsek, 'mo'); hold on; axis equal; grid on; %dirsek figure(7), plot(v_dirsek_el_bilegi, 'b+'); % el bileği figure(7), plot(v_el_bilegi_orta_parmak, 'g*'); xlabel('zaman') ylabel('derece') title('Eklemlerin Hız Grafiği') legend('Omuz Dirsek','Dirsek El bilegi','El bilegi Orta parmak'); % açısal ivme figure(8), plot(a_omuz_dirsek, 'mo'); hold on; axis equal; grid on; %dirsek figure(8), plot(a_dirsek_el_bilegi, 'b+'); % el bileği figure(8), plot(a_el_bilegi_orta_parmak, 'g*'); xlabel('zaman') ylabel('derece') title('Eklemlerin İvme Grafiği'); legend('Omuz Dirsek','Dirsek El bilegi','El bilegi Orta parmak'); end displayEndOfDemoMessage(mfilename) end
function hareket_analizi_projesi()
clear; close all; video = true; % false yaparak kapatabiliriz if video %video kaydı için dosya açılıyor aviobj = VideoWriter('final_sonuç.avi', ... 'Uncompressed AVI'); aviobj.FrameRate = 25; open(aviobj); end % video olarak alınıp pencere boyutu ayarlanıyor. obj = setupSystemObjects(); tracks = initializeTracks(); % boş bir dizi oluşturur. nextId = 1; % sonraki bulunacak nokta % Her bir video frame için aşağıdaki işlem tekrarlanmaktadır. srcFiles = dir(strcat(pwd,'\ender_sut_C001H001S0001*.jpg')); for resim_index = 1 : length(srcFiles) filename = strcat(pwd,'\',srcFiles(resim_index).name); frame_orijinal=imread(filename); frame = frame_orijinal; [satir_max, sutun_max] = size(frame); %resim maskeleme frame(1:50,:) = 0; frame(:,1:100) = 0; frame(:,1024+1:1024+100) = 0; frame(:,2048+1:2048+100) = 0; frame(600:satir_max,:) = 0; [centroids, bboxes, mask] = detectObjects(frame); predictNewLocationsOfTracks(); [assignments, unassignedTracks, unassignedDetections] = ... detectionToTrackAssignment(); updateAssignedTracks(); updateUnassignedTracks(); deleteLostTracks(); createNewTracks(); displayTrackingResults(); writeVideo(aviobj,frame_orijinal); % w = waitforbuttonpress ; end if video close(aviobj); end %kalibrasyon yapılmaktadır. % otelenmis_centroids kalibrasyon_konum_belirleme(); %% function toplu_resim_isleme_fonksiyonu() % tüm her şeyi resetliyoruz clear; close all; video = true; % false yaparak kapatabiliriz if video aviobj = VideoWriter('final.avi','Uncompressed AVI'); aviobj.FrameRate = 25; open(aviobj); end %video yüklenecek resimleri matlab klasörün altından alıyoruz srcFiles = dir(strcat(pwd,'\ender_sut_C001H001S0001*.jpg')); hold off; for i = 1 : length(srcFiles) filename = strcat(pwd,'\',srcFiles(i).name); RGB=imread(filename); % resmin belirli bir bölgesi tek alınıyor % resim_frame = imcrop(RGB, [350 30]); I = rgb2gray(RGB); [rows columns] = size(I ); %eşik değeri belirleme I(1:50,1:300) = 0; I(1:50,columns-300:columns) = 0; I(:,1:100) = 0; I(600:rows,:) = 0; [level EM] = graythresh(I); %belirlenen eşik değerine göre gereksiz noktaları temizleme resim_mask = im2bw(I,EM); resim_mask = medfilt2(resim_mask,[1 1]); % 4 piksel den küçük kod topluluklarını sil resim_mask = bwareaopen(resim_mask,4); imshow(resim_mask); if video matlab_grafik_penceresi_resmi= getframe(gcf); writeVideo(aviobj,matlab_grafik_penceresi_resmi); end end if video close(aviobj); clear; close all; end end %% function obj = setupSystemObjects() % obj.reader = vision.VideoFileReader('final.avi'); % gösterilecek figür(pencere) ayarlanıyor. obj.videoPlayer = vision.VideoPlayer('Position', [20, 20, 800, 1000]); % [centroids, bboxes, mask] değerlerini bulmak için kullanılır. obj.blobAnalyser = vision.BlobAnalysis('BoundingBoxOutputPort', true, ... 'AreaOutputPort', true, 'CentroidOutputPort', true, ... 'MinimumBlobArea', 1); end %% tracks dizisinin değerleri: % % * |id| : her bir noktanın id bilgisi % * |bbox| : nesneleri gösterecek yazının sınırları bilgisi % * |kalmanFilter| : hareket bazlı izlemek için kullanılan kalman % * |age| : ilk tespit edilmesinden bu yana frame sayısı % * |totalVisibleCount| : görünen parça tespit edilen toplam frame sayısı % * |consecutiveInvisibleCount| : nokta tespit edilmeyen ardışık frame sayısı function tracks = initializeTracks() % create an empty array of tracks tracks = struct(... 'id', {}, ... 'bbox', {}, ... 'kalmanFilter', {}, ... 'age', {}, ... 'totalVisibleCount', {}, ... 'consecutiveInvisibleCount', {}); end %% videonun bir sonraki frame alma function frame = readFrame() frame = obj.reader.step(); end %% noktarı bulma % videonun her bir frame için tek bir framede % centroids(bulunan noktaların merkez bilgisi) % bboxes(nesneleri gösterecek yazının sınırları bilgisi) % mask(framemin gri modda temizlenmiş hali) function [centroids, bboxes, mask] = detectObjects(frame) %gri moda çevirme I = rgb2gray(frame); %eşik değeri belirleme [level EM] = graythresh(I); %belirlenen eşik değerine göre gereksiz noktaları temizleme mask = im2bw(I,EM); mask = medfilt2(mask,[3 3]); % 4 piksel den küçük kod topluluklarını sil mask = bwareaopen(mask,5); % blobAnalyser kullanarak [centroids, bboxes, mask] değerlerini % bulma [~, centroids, bboxes] = obj.blobAnalyser.step(mask); end %% Mevcut parçalardan yeni yerin tahmini % kalman filtresi kullanılarak geçmişteki nokların bilgisinden faydalanarak % framedeki noktaların yerlerini tespit etme. function predictNewLocationsOfTracks() for i = 1:length(tracks) bbox = tracks(i).bbox; % noktanın mevcut konumunu kalman ile tahmin etme. predictedCentroid = predict(tracks(i).kalmanFilter); % sınırı belirlenmiş kutu(bbox)kullanılarak merkezi konumunu tahim. predictedCentroid = int32(predictedCentroid) - bbox(3:4) / 2; tracks(i).bbox = [predictedCentroid, bbox(3:4)]; end end %% Assign Detections to Tracks % Assigning object detections in the current frame to existing tracks is % done by minimizing cost. The cost is defined as the negative % log-likelihood of a detection corresponding to a track. % % The algorithm involves two steps: % % Step 1: Compute the cost of assigning every detection to each track using % the |distance| method of the |vision.KalmanFilter| System object. The % cost takes into account the Euclidean distance between the predicted % centroid of the track and the centroid of the detection. It also includes % the confidence of the prediction, which is maintained by the Kalman % filter. The results are stored in an MxN matrix, where M is the number of % tracks, and N is the number of detections. % % Step 2: Solve the assignment problem represented by the cost matrix using % the |assignDetectionsToTracks| function. The function takes the cost % matrix and the cost of not assigning any detections to a track. % % The value for the cost of not assigning a detection to a track depends on % the range of values returned by the |distance| method of the % |vision.KalmanFilter|. This value must be tuned experimentally. Setting % it too low increases the likelihood of creating a new track, and may % result in track fragmentation. Setting it too high may result in a single % track corresponding to a series of separate moving objects. % % The |assignDetectionsToTracks| function uses the Munkres' version of the % Hungarian algorithm to compute an assignment which minimizes the total % cost. It returns an M x 2 matrix containing the corresponding indices of % assigned tracks and detections in its two columns. It also returns the % indices of tracks and detections that remained unassigned. function [assignments, unassignedTracks, unassignedDetections] = ... detectionToTrackAssignment() nTracks = length(tracks); nDetections = size(centroids, 1); % Compute the cost of assigning each detection to each track. cost = zeros(nTracks, nDetections); for i = 1:nTracks cost(i, :) = distance(tracks(i).kalmanFilter, centroids); end % Solve the assignment problem. costOfNonAssignment = 20; [assignments, unassignedTracks, unassignedDetections] = ... assignDetectionsToTracks(cost, costOfNonAssignment); end %% Update Assigned Tracks % The |updateAssignedTracks| function updates each assigned track with the % corresponding detection. It calls the |correct| method of % |vision.KalmanFilter| to correct the location estimate. Next, it stores % the new bounding box, and increases the age of the track and the total % visible count by 1. Finally, the function sets the invisible count to 0. function updateAssignedTracks() numAssignedTracks = size(assignments, 1); for i = 1:numAssignedTracks trackIdx = assignments(i, 1); detectionIdx = assignments(i, 2); centroid = centroids(detectionIdx, :); bbox = bboxes(detectionIdx, :); % Correct the estimate of the object's location % using the new detection. correct(tracks(trackIdx).kalmanFilter, centroid); % Replace predicted bounding box with detected % bounding box. tracks(trackIdx).bbox = bbox; % Update track's age. tracks(trackIdx).age = tracks(trackIdx).age + 1; % Update visibility. tracks(trackIdx).totalVisibleCount = ... tracks(trackIdx).totalVisibleCount + 1; tracks(trackIdx).consecutiveInvisibleCount = 0; end end %% Update Unassigned Tracks % Mark each unassigned track as invisible, and increase its age by 1. function updateUnassignedTracks() for i = 1:length(unassignedTracks) ind = unassignedTracks(i); tracks(ind).age = tracks(ind).age + 1; tracks(ind).consecutiveInvisibleCount = ... tracks(ind).consecutiveInvisibleCount + 1; end end %% Delete Lost Tracks % The |deleteLostTracks| function deletes tracks that have been invisible % for too many consecutive frames. It also deletes recently created tracks % that have been invisible for too many frames overall. function deleteLostTracks() if isempty(tracks) return; end invisibleForTooLong = 20; ageThreshold = 8; % Compute the fraction of the track's age for which it was visible. ages = [tracks(:).age]; totalVisibleCounts = [tracks(:).totalVisibleCount]; visibility = totalVisibleCounts ./ ages; % Find the indices of 'lost' tracks. lostInds = (ages < ageThreshold & visibility < 0.6) | ... [tracks(:).consecutiveInvisibleCount] >= invisibleForTooLong; % Delete lost tracks. tracks = tracks(~lostInds); end %% Create New Tracks % Create new tracks from unassigned detections. Assume that any unassigned % detection is a start of a new track. In practice, you can use other cues % to eliminate noisy detections, such as size, location, or appearance. function createNewTracks() centroids = centroids(unassignedDetections, :); bboxes = bboxes(unassignedDetections, :); for i = 1:size(centroids, 1) centroid = centroids(i,:); bbox = bboxes(i, :); % Create a Kalman filter object. kalmanFilter = configureKalmanFilter('ConstantVelocity', ... centroid, [200, 50], [100, 25], 100); % Create a new track. newTrack = struct(... 'id', nextId, ... 'bbox', bbox, ... 'kalmanFilter', kalmanFilter, ... 'age', 1, ... 'totalVisibleCount', 1, ... 'consecutiveInvisibleCount', 0); % Add it to the array of tracks. tracks(end + 1) = newTrack; % Increment the next id. nextId = nextId + 1; end end %% Tespit edilen noktaları işaretleme ve yazı ile belirme % her bir frame için tespit veya tahmin edilen noktalar işaretlenmektedir % bu noktaların ne olduğu yazılmaktadır. function displayTrackingResults() % kalibre etme dizisi vucut = {'Omuz', 'Dirsek', 'El Bilegi', 'Orta Parmak'}; % renklerin ingilizce olarak ilk harflerini kullan. renkler={'magenta', 'blue', 'green', 'red'}; % Convert the frame and the mask to uint8 RGB. frame = im2uint8(frame); mask = uint8(repmat(mask, [1, 1, 3])) .* 255; minVisibleCount = 0; if ~isempty(tracks) % Noisy detections tend to result in short-lived tracks. % Only display tracks that have been visible for more than % a minimum number of frames. reliableTrackInds = ... [tracks(:).totalVisibleCount] > minVisibleCount; reliableTracks = tracks(reliableTrackInds); % Display the objects. If an object has not been detected % in this frame, display its predicted bounding box. if ~isempty(reliableTracks) % Get bounding boxes. bboxes = cat(1, reliableTracks.bbox); % Get ids. ids = int32([reliableTracks(:).id]); % Create labels for objects indicating the ones for % which we display the predicted rather than the actual % location. labels = cellstr(vucut(ids')); predictedTrackInds = ... [reliableTracks(:).consecutiveInvisibleCount] > 0; isPredicted = cell(size(labels)); % tahmin edildiğinde tahmin edildi eklenecek isPredicted(predictedTrackInds) = {' <Tahmin Edildi>'}; labels = strcat(labels, isPredicted); % % Draw the objects on the frame. % frame = insertObjectAnnotation(frame, 'rectangle', ... % bboxes, labels); % Draw the objects on the mask. xs = bboxes(:,1) + round(bboxes(:,3)/2); ys = bboxes(:,2) + round(bboxes(:,4)/2); line_xy(1,:) = [xs(1) ys(1) xs(2) ys(2)]; line_xy(2,:) = [xs(2) ys(2) xs(3) ys(3)]; line_xy(3,:) = [xs(3) ys(3) xs(4) ys(4)]; koordinat1 = [' x:',int2str(xs(1)),' y:',int2str(ys(1))]; koordinat2 = [' x:',int2str(xs(2)),' y:',int2str(ys(2))]; koordinat3 = [' x:',int2str(xs(3)),' y:',int2str(ys(3))]; koordinat4 = [' x:',int2str(xs(4)),' y:',int2str(ys(4))]; labels = strcat(vucut, {koordinat1,koordinat2,koordinat3,koordinat4}); frame_orijinal = insertShape(frame_orijinal, 'line', line_xy, 'Color','white', 'LineWidth', 5); % mask = insertObjectAnnotation(mask, 'rectangle', ... % bboxes, labels,'Color',renkler(ids'),'TextColor','yellow','TextBoxOpacity', 0.5); frame_orijinal = insertObjectAnnotation(frame_orijinal, 'circle', ... [xs,ys, ones(length(xs),1)*3], labels,'Color',renkler(ids'),'TextColor','yellow','TextBoxOpacity', 0.5); end end % videoyu göster. obj.videoPlayer.step(frame_orijinal); end %% Summary % This example created a motion-based system for detecting and % tracking multiple moving objects. Try using a different video to see if % you are able to detect and track objects. Try modifying the parameters % for the detection, assignment, and deletion steps. % % The tracking in this example was solely based on motion with the % assumption that all objects move in a straight line with constant speed. % When the motion of an object significantly deviates from this model, the % example may produce tracking errors. Notice the mistake in tracking the % person labeled #12, when he is occluded by the tree. % % The likelihood of tracking errors can be reduced by using a more complex % motion model, such as constant acceleration, or by using multiple Kalman % filters for every object. Also, you can incorporate other cues for % associating detections over time, such as size, shape, and color. displayEndOfDemoMessage(mfilename) end