clear all,
close all
clc
%% Video laden
video = VideoReader('GeradeInKurve_IPT.mp4');
n = video.NumFrames;
% Video Writer initialisieren
outputVideoFile = 'GeradeInKurve_Segmente.mp4';
outputVideo = VideoWriter(outputVideoFile, 'MPEG-4');
outputVideo.FrameRate = video.FrameRate; % gleiche Bildrate wie das Originalvideo
open(outputVideo);
centerX = 450;
centerY = 325;
areaDistance = 150;
% Frames extrahieren, bearbeiten und in das neue Video schreiben
while hasFrame(video)
frame = readFrame(video);
% Frame bearbeiten
%grayFrame = rgb2gray(frame);
processedFrame = markRoadway(frame, centerX, centerY, areaDistance);
% Bearbeitete Frames in das neue Video schreiben
writeVideo(outputVideo, im2uint8(processedFrame));
end
% Video Writer schließen
close(outputVideo);
function markedIm = markRoadway(image, centerX, centerY, areaDistance)
binIm = imbinarize(image);
CC = bwconncomp(binIm);
imSize = CC.ImageSize;
n = CC.NumObjects;
centerArea = [centerX-areaDistance, centerX; centerY-areaDistance, centerY+areaDistance];
nearestLeft = Inf;
leftObject = [];
nearestRight = Inf;
rightObject = [];
middleObjects = {};
arrayLength = 0;
for i = 1:n
object = CC.PixelIdxList{i};
[x, y] = ind2sub(imSize, object);
[~, maxIndex] = max(x);
maxY = y(maxIndex);
distanceY = centerY - maxY;
if inBetweenArea(centerArea, x, y)
arrayLength = arrayLength + 1;
middleObjects{arrayLength} = object;
disp("BETWEEN");
elseif distanceY > 0 && distanceY < nearestLeft && touchingArea(centerArea, x, y)
nearestLeft = distanceY;
leftObject = object;
%disp("FOUND LEFT " + num2str(distanceY));
elseif distanceY < 0 && abs(distanceY) < nearestRight && touchingArea(centerArea, x, y)
nearestRight = abs(distanceY);
rightObject = object;
%disp("FOUND RIGHT " + num2str(distanceY));
end
end
leftY = 0;
rightY = 100;
if ~isempty(rightObject)
[x, y] = ind2sub(imSize, rightObject);
[~, maxIndex] = max(x);
rightY = y(maxIndex);
end
if ~isempty(leftObject)
[x, y] = ind2sub(imSize, leftObject);
[~, maxIndex] = max(x);
leftY = y(maxIndex);
end
%% Darstellung
markedIm = drawRectangle(image, centerArea(1,1), centerArea(1,2), centerArea(2,1), centerArea(2,2), 0, 0, 255);
for i = 1:arrayLength
object = middleObjects{i};
[x, y] = ind2sub(imSize, object);
[~, maxIndex] = max(x);
maxY = y(maxIndex);
if maxY >= leftY && maxY <= rightY
markedIm = paintArea(markedIm, x, y, 255, 0, 0);
disp("FOUND MIDDLE");
else
disp(["[FAILED] maxY:", num2str(maxY), " leftY:", num2str(leftY), " rightY:", num2str(rightY)]);
end
end
if ~isempty(rightObject)
[x, y] = ind2sub(imSize, rightObject);
markedIm = paintArea(markedIm, x, y, 255, 255, 0);
end
if ~isempty(leftObject)
[x, y] = ind2sub(imSize, leftObject);
markedIm = paintArea(markedIm, x, y, 0, 255, 0);
end
end
function result = inBetweenArea(area, objectX, objectY)
resX = all(objectX >= area(1, 1) & objectX <= area(1, 2));
resY = all(objectY >= area(2, 1) & objectY <= area(2, 2));
result = resX & resY;
end
function result = touchingArea(area, objectX, objectY)
resX = any(objectX >= area(1, 1) & objectX <= area(1, 2));
resY = any(objectY >= area(2, 1) & objectY <= area(2, 2));
result = resX & resY;
end
function outImage = drawRectangle(image, x1, x2, y1, y2, r, g, b)
imSize = size(image);
sizeX = imSize(1);
sizeY = imSize(2);
if x1 < 0
x1 = 0;
end
if y1 < 0
y1 = 0;
end
if x2 > sizeX
x2 = sizeX;
end
if y2 > sizeY
y2 = sizeY;
end
outImage = image;
for x = x1:x2
for y = y1:y2
%disp([num2str(x), num2str(y)]);
outImage = paintPixel(outImage, x, y, r, g, b);
end
end
end
function outImage = paintArea(image, xArr, yArr, r, g, b)
for i = 1:length(xArr)
image = paintPixel(image, xArr(i), yArr(i), r, g, b);
end
outImage = image;
end
function image = paintPixel(image, x, y , r, g, b)
if x >= 1 && x <= size(image, 1) && y >= 1 && y <= size(image, 2)
image(x, y, 1) = r;
image(x, y, 2) = g;
image(x, y, 3) = b;
else
%disp(['Ungültiger Index: x=', num2str(x), ', y=', num2str(y)]);
end
end