Beberapa bergerak­gerakan berbasis objek pelacakan
Contoh ini menunjukkan bagaimana melakukan deteksi otomatis dan
pelacakan bergerak­gerakan berbasis objek bergerak dalam sebuah
video dari kamera stasioner.
Deteksi bergerak objek dan bergerak­gerakan berbasis pelacakan merupakan komponen penting dari banyak
komputer visi aplikasi, termasuk kegiatan pengakuan, pemantauan lalu lintas, dan keselamatan otomotif. Masalah
bergerak­gerakan berbasis objek pelacakan dapat dibagi menjadi dua bagian:
1. Mendeteksi bergerak objek di setiap bingkai
2. Bergaul pendeteksian yang sesuai dengan objek yang sama dari waktu ke waktu
Deteksi benda bergerak menggunakan algoritma pengurangan latar belakang yang berdasarkan model Gaussian
campuran. Operasi morfologi diterapkan dihasilkan latar depan topeng untuk menghilangkan kebisingan. Akhirnya,
gumpalan analisis mendeteksi rombongan terhubung piksel, yang mungkin sesuai dengan objek bergerak.
Asosiasi pendeteksian untuk objek yang sama didasarkan semata­mata pada gerak.Gerakan dari setiap lagu
diperkirakan oleh penyaring Kalman. Penyaring digunakan untuk memprediksi lokasi dalam lagu di setiap bingkai,
dan menentukan kemungkinan setiap deteksi yang diberikan kepada setiap lagu.
Pemeliharaan lagu menjadi aspek penting dari contoh ini. Di setiap bingkai yang diberikan, pendeteksian beberapa
dapat ditetapkan ke trek, sementara pendeteksian dan trek lain mungkin tetap belum ditugaskan. Trek ditugaskan
diperbarui menggunakan pendeteksian sesuai. Trek unassigned ditandai terlihat. Deteksi unassigned mulai trek baru.
Setiap lagu menyimpan jumlah banyaknya frame berturut­turut, yang mana tetap belum ditugaskan. Jika jumlah yang
melebihi ambang batas yang ditentukan, contoh mengasumsikan bahwa objek meninggalkan bidang pandang dan
menghapus trek.
Untuk informasi lebih lanjut silakan lihat Beberapa objek pelacakan.
Contoh ini adalah fungsi dengan tubuh utama di atas dan penolong rutinitas dalam bentuk fungsi bersarang di bawah
ini.
function multiObjectTracking() 
% Create System objects used for reading video, detecting moving objects,
% and displaying the results. 
obj = setupSystemObjects(); 
tracks = initializeTracks(); % Create an empty array of tracks. 
nextId = 1; % ID of the next track
% Detect moving objects, and track them across video frames. 
while ~isDone(obj.reader) 
    frame = readFrame(); 
    [centroids, bboxes, mask] = detectObjects(frame); 
    predictNewLocationsOfTracks();
    [assignments, unassignedTracks, unassignedDetections] = ... 
        detectionToTrackAssignment(); 
    updateAssignedTracks(); 
    updateUnassignedTracks(); 
    deleteLostTracks(); 
    createNewTracks(); 
    displayTrackingResults(); 
end 
Open Script
Membuat sistem objek
Menciptakan objek sistem yang digunakan untuk membaca frame video, mendeteksi objek di latar depan, dan
menampilkan hasil.
    function obj = setupSystemObjects() 
        % Initialize Video I/O 
        % Create objects for reading a video from a file, drawing the tracked
        % objects in each frame, and playing the video. 
        % Create a video file reader. 
        obj.reader = vision.VideoFileReader('atrium.mp4'); 
        % Create two video players, one to display the video, 
        % and one to display the foreground mask. 
        obj.videoPlayer = vision.VideoPlayer('Position', [20, 400, 700, 400]);
        obj.maskPlayer = vision.VideoPlayer('Position', [740, 400, 700, 400]);
        % Create System objects for foreground detection and blob analysis
        % The foreground detector is used to segment moving objects from
        % the background. It outputs a binary mask, where the pixel value
        % of 1 corresponds to the foreground and the value of 0 corresponds
        % to the background. 
        obj.detector = vision.ForegroundDetector('NumGaussians', 3, ...
            'NumTrainingFrames', 40, 'MinimumBackgroundRatio', 0.7);
        % Connected groups of foreground pixels are likely to correspond to moving
        % objects.  The blob analysis System object is used to find such groups
        % (called 'blobs' or 'connected components'), and compute their
        % characteristics, such as area, centroid, and the bounding box.
        obj.blobAnalyser = vision.BlobAnalysis('BoundingBoxOutputPort', true, 
            'AreaOutputPort', true, 'CentroidOutputPort', true, ... 
            'MinimumBlobArea', 400); 
    end 
Menginisialisasi trek
Fungsi initializeTracks menciptakan array trek, dimana setiap trek merupakan struktur yang mewakili sebuah
objek bergerak dalam video. Tujuan dari struktur adalah untuk mempertahankan keadaan benda yang
dilacak. Negara bagian terdiri dari informasi yang digunakan untuk deteksi untuk melacak tugas, melacak
penghentian, dan menampilkan.
Struktur berisi bidang­bidang berikut:
id : ID integer trek
bbox : kotak melompat­lompat saat ini objek; digunakan untuk menampilkan
kalmanFilter : Kalman objek filter yang digunakan untuk bergerak­gerakan berbasis pelacakan
age : jumlah bingkai sejak trek pertama kali terdeteksi
totalVisibleCount : jumlah total frame di mana jalur yang terdeteksi (terlihat)
consecutiveInvisibleCount : jumlah bingkai berturut­turut yang trek tidak terdeteksi (terlihat).
Pendeteksian bising cenderung mengakibatkan lagu pendek. Untuk alasan ini, contoh hanya menampilkan object
setelah itu dilacak untuk beberapa jumlah bingkai. Hal ini terjadi ketika totalVisibleCount melebihi ambang batas
yang ditentukan.
Ketika pendeteksian tidak terkait dengan trek untuk beberapa frame berturut­turut, contoh mengasumsikan bahwa
objek telah meninggalkan bidang pandang dan menghapus trek. Hal ini terjadi
ketika consecutiveInvisibleCount melebihi ambang batas yang ditentukan. Lintasan mungkin juga bisa dihapus
sebagai kebisingan jika dilacak untuk waktu yang singkat, dan ditandai terlihat untuk sebagian besar frame.
    function tracks = initializeTracks() 
        % create an empty array of tracks 
        tracks = struct(... 
            'id', {}, ... 
            'bbox', {}, ... 
            'kalmanFilter', {}, ... 
            'age', {}, ... 
            'totalVisibleCount', {}, ... 
            'consecutiveInvisibleCount', {}); 
    end 
Membaca Video bingkai
Membaca frame video berikutnya dari video file.
    function frame = readFrame() 
        frame = obj.reader.step();
    end 
Mendeteksi objek
Fungsi detectObjects kembali centroids dan kotak yang melompat­lompat objek terdeteksi. Itu juga kembali
masker biner, yang memiliki ukuran yang sama sebagai bingkai masukan. Pixel dengan nilai 1 sesuai dengan latar
depan, dan pixel dengan nilai 0 sesuai dengan latar belakang.
Fungsi melakukan segmentasi gerak menggunakan detektor latar depan. Kemudian melakukan operasi morfologi
pada topeng biner dihasilkan untuk menghilangkan bising piksel dan untuk mengisi lubang­lubang di gumpalan
tersisa.
    function [centroids, bboxes, mask] = detectObjects(frame) 
        % Detect foreground. 
        mask = obj.detector.step(frame); 
        % Apply morphological operations to remove noise and fill in holes.
        mask = imopen(mask, strel('rectangle', [3,3])); 
        mask = imclose(mask, strel('rectangle', [15, 15])); 
        mask = imfill(mask, 'holes'); 
        % Perform blob analysis to find connected components. 
        [~, centroids, bboxes] = obj.blobAnalyser.step(mask); 
    end 
Memprediksi lokasi rel yang sudah ada
Menggunakan Kalman filter untuk memprediksi centroid setiap lagu dalam rangka saat ini, dan memperbarui
kotaknya melompat­lompat sesuai.
    function predictNewLocationsOfTracks() 
        for i = 1:length(tracks) 
            bbox = tracks(i).bbox;
            % Predict the current location of the track. 
            predictedCentroid = predict(tracks(i).kalmanFilter); 
            % Shift the bounding box so that its center is at 
            % the predicted location. 
            predictedCentroid = int32(predictedCentroid) ‐ bbox(3:4) / 2;
            tracks(i).bbox = [predictedCentroid, bbox(3:4)]; 
        end 
    end 
Menetapkan pendeteksian ke trek
Menetapkan objek pendeteksian dalam bingkai saat ini ke trek yang ada dilakukan dengan meminimalkan
biaya. Biaya didefinisikan sebagai negatif log­kemungkinan deteksi sesuai dengan trek.
Algoritma melibatkan dua langkah:
Langkah 1: Menghitung biaya menugaskan deteksi setiap untuk setiap lagu yang menggunakan
metode distance visi vision.KalmanFilter objek sistem™. Biaya memperhitungkan jarak Euclidean antara
centroid diperkirakan trek dan centroid deteksi. Ini juga mencakup kepercayaan dari prediksi, yang dijaga oleh
Kalman filter.Hasil disimpan dalam matriks MxN, dimana M adalah jumlah trek, dan N adalah jumlah pendeteksian.
Langkah 2: Memecahkan masalah tugas yang diwakili oleh matriks biaya menggunakan
fungsi assignDetectionsToTracks . Fungsi mengambil matriks biaya dan biaya tidak menetapkan pendeteksian
apapun ke trek.
Nilai untuk biaya tidak menentukan deteksi untuk melacak tergantung pada berbagai nilai­nilai kembali dengan
metode distance visi vision.KalmanFilter. Nilai ini harus disetel secara eksperimental. Pengaturan terlalu
rendah meningkatkan kemungkinan membuat baru melacak, dan dapat mengakibatkan trek fragmentasi. Pengaturan
itu terlalu tinggi mengakibatkan satu lagu sesuai dengan serangkaian benda bergerak terpisah.
Fungsi assignDetectionsToTracks menggunakan Munkres' versi dari Hungaria algoritma untuk menghitung
sebuah tugas yang meminimalkan biaya total. Itu kembali M x 2 matriks yang mengandung indeks yang terkait
ditugaskan trek dan pendeteksian dalam dua kolom. Itu juga kembali indeks trek dan pendeteksian yang tetap belum
ditugaskan.
    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 ditugaskan trek
Fungsi updateAssignedTracks update setiap lagu yang ditugaskan dengan deteksi sesuai. Ini panggilan metode
yang correct visi vision.KalmanFilter untuk memperbaiki perkiraan lokasi. Selanjutnya, itu toko kotak
melompat­lompat baru, dan meningkatkan usia trek dan jumlah total terlihat oleh 1. Akhirnya, fungsi menetapkan
menghitung terlihat ke 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 
Memperbarui Unassigned trek
Tandai setiap lagu yang belum ditugaskan sebagai terlihat, dan meningkatkan umur 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 
Menghapus trek yang hilang
deleteLostTracks fungsi menghapus trek yang telah terlihat untuk terlalu banyak frame berturut­turut. Namun juga
menghapus trek yang baru saja dibuat yang telah terlihat untuk frame yang terlalu banyak secara keseluruhan.
    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 
Menciptakan lagu baru
Membuat lagu baru dari unassigned pendeteksian. Menganggap bahwa setiap unassigned deteksi awal lagu
baru. Dalam praktek, Anda dapat menggunakan isyarat lain untuk menghilangkan bising pendeteksian, seperti
ukuran, lokasi, atau penampilan.
    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 
Tampilan hasil pelacakan
Fungsi displayTrackingResults menarik melompat­lompat kotak dan label ID untuk setiap lagu video bingkai dan
latar depan topeng. Ini kemudian menampilkan frame dan topeng dalam pemutar video mereka masing­masing.
    function displayTrackingResults() 
        % Convert the frame and the mask to uint8 RGB. 
        frame = im2uint8(frame); 
        mask = uint8(repmat(mask, [1, 1, 3])) .* 255; 
        minVisibleCount = 8; 
        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(int2str(ids')); 
                predictedTrackInds = ... 
                    [reliableTracks(:).consecutiveInvisibleCount] > 0; 
                isPredicted = cell(size(labels)); 
                isPredicted(predictedTrackInds) = {' predicted'}; 
                labels = strcat(labels, isPredicted); 
                % Draw the objects on the frame. 
                frame = insertObjectAnnotation(frame, 'rectangle', ... 
                    bboxes, labels); 
                % Draw the objects on the mask. 
                mask = insertObjectAnnotation(mask, 'rectangle', ... 
                    bboxes, labels); 
            end 
        end 
        % Display the mask and the frame. 
        obj.maskPlayer.step(mask);
        obj.videoPlayer.step(frame); 
    end 
Ringkasan
Contoh ini menciptakan sebuah sistem berbasis gerakan untuk mendeteksi dan melacak beberapa objek
bergerak. Coba gunakan video yang berbeda untuk melihat apakah Anda dapat mendeteksi dan melacak
benda. Mencoba memodifikasi parameter untuk deteksi, tugas, dan langkah­langkah penghapusan.
Pelacakan dalam contoh ini semata­mata didasarkan pada gerak dengan asumsi bahwa semua benda bergerak
dalam garis lurus dengan kecepatan konstan. Ketika gerakan objek secara signifikan menyimpang dari model ini,
contoh mungkin menghasilkan pelacakan kesalahan. Perhatikan kesalahan dalam pelacakan orang berlabel #12,
ketika dia adalah tersumbat oleh pohon.
Kemungkinan pelacakan kesalahan dapat dikurangi dengan menggunakan model gerak yang lebih kompleks, seperti
akselerasi konstan, atau dengan menggunakan beberapa Kalman filter untuk setiap objek. Juga, Anda dapat
menggabungkan lain isyarat untuk bergaul pendeteksian dari waktu ke waktu, seperti ukuran, bentuk dan warna.
end 
Apakah topik ini berman

Motion based multiple object tracking - matlab &amp; simulink example