How do I change line thickness and color on a video

This code provides a video output of two videos for comparison purposes side by side. From the second line of code, I get a black line across the specified pixel (517). I would like to be able to change the thickness and the color of the line. I know how to do this for plots but not sure how to do that for this example.
%% Create Movie
img=cat(2,video,uint8(video_translated)); %videos put side to side for comparison purposes
img(517,:,:,:)=0; %change thickness of line and color
vidname= ['stabilize' fname '.mp4']
vidObj = VideoWriter(vidname,'MPEG-4'); %any name can be given to this
vidObj.FrameRate = 15;
open(vidObj);
for i=1:size(img,3) %Number of frames
writeVideo(vidObj,img);
end
close (vidObj)

 Accepted Answer

img(517:517+LineWidth-1, :, :, :) = 0;
to change the width of the line (while still leaving it black)
You are doing 4 dimensional indexing there, but it is difficult for us to figure out what the four indices represent. You have the line
for i=1:size(img,3) %Number of frames
implying that the third dimension is frames. But videowriter expects one of:
  • a 2D array, for grayscale or indexed images
  • a rows x columns x 1 x frames array for multiple grayscale or indexed images
  • a rows x columns x 3 x frames array for multiple rgb images
Number of frames is never the third dimension for writeVideo
Furthermore, you loop 1 : size(img,3) but you send all of img to writeVideo(), repeating the same information multiple times.
Can we get a hint from the way you cat() the two videos? Unfortunately, no. That cat() does restrict the situation to either being one single frame consisting of a single merged image, or else to two multi-frame videos that happen to have the same number of frames... but we cannot tell whether they are rows x columns x 3 x frames or rows x columns x 1 x frames
If they happen to be rows x columns x 3 x frames then for colour you would do
img(517:517+LineWidth-1, :, 1, :) = RedComponent;
img(517:517+LineWidth-1, :, 2, :) = GreenComponent;
img(517:517+LineWidth-1, :, 3, :) = BlueComponent;
If they happen to be rows x columns x 1 x frames then you would first do
img = repmat(img, 1, 1, 3, 1);
and then do the R G B assignment.

7 Comments

Hi Walter. I am sorry for not including the entire code. I did not think it would be neccesary and thought it would be an easy solution fix. The indices represent Y:X:RGB:number of frames. Earlier in the code, I converted the original RGB move to grayscale which left me with three indices for the movie which is probably why I did "img(:,:,3)". Could number of frames be the third dimension when the video is in grayscale? Are you suggesting, it should technically not be written that way because we would need 4 indices for video writer to work?
"Furthermore, you loop 1 : size(img,3) but you send all of img to writeVideo(), repeating the same information multiple times." - This would probably explain why I have the video repeated multiple times and length of video is longer.
They do happen to be rows x columns x 3 x frames. Cat allows me to show two multi-frame videos.
writeVideo cannot handle rows x columns x frames for grayscale, only rows x columns x 1 x frames for grayscale.
When you have multiple frames, you have two choices:
  • a single call, writeVideo(vidObj,img) with no looping, which will write all of the frames at the same time; OR
  • loop over the number of rames and writeVideo(vidObj,img(:,:,:,FRAMENUMBER)))
I would expect the single call to be more efficient and to have more opportunities for compressing the video well; I would recommend that approach whenever all of the data is already available. (Writing individual frames is fine for the case where you are generating the frames as you go.)
img(517:517+'LineWidth'-1,:,:,:)=0;
I am not sure if I did this correctly. The output gives me an extremely large line. How can I modify the thickness of it? I initially thought it was due to the "-1" but that does not happen to do anything to the line.
img=cat(2,video,uint8(video_translated));
%img(517,:,:,:)=0; %Original thin black line
img(517:517+'LineWidth'-1,:,1,:)=0; %change thickness of line and color. Line too large
vidname= ['stabilize' fname '.mp4'];
vidObj = VideoWriter(vidname,'MPEG-4'); %any name can be given to this
vidObj.FrameRate = 15;
open(vidObj);
for i=1:size(img,3) %Number of frames
writeVideo(vidObj,img(:,:,:,i)); % <<<-------
end
close (vidObj)
I attempted to do the loop format but the output only yields a one frame video. I think I am bit lost on your instructuctions on how to improve the code. How would you do the single call? Would this be how? I am also not sure how to prevent the video writing to repeat the same information multiple times.
img=uint8(video_translated);
img(517,:,:,:)=0;
vidname= ['stabilize' fname '.mp4'];
vidObj = VideoWriter(vidname,'MPEG-4');
vidObj.FrameRate = 15;
open(vidObj);
writeVideo(vidObj,img);
close (vidObj)
You asked for a wider line, but you did not specify how wide. If I had put in any particular numeric value, that might have been the wrong value for your purpose. So I put in a variable named LineWidth. Assign LineWidth the width of the line you want, in pixels.
LineWidth = 7; %for example
%linecolor... You didn't say that either. So why not hotpink?
LineColorRGB = [255,105,180] ./ 255;
RedComponent = LineColorRGB(1);
GreenComponent = LineColorRGB(2);
BlueComponent = LineColorRGB(3);
img(517:517+LineWidth-1,:,1,:) = RedComponent;
img(517:517+LineWidth-1,:,2,:) = GreenComponent;
img(517:517+LineWidth-1,:,3,:) = BlueComponent;
Then
open(vidObj);
writeVideo(vidObj,img);
close (vidObj)
Thank you so much Walter. My last question. What does "-1" do following LineWidth? Is this necessary?
If I want a vector starting with 0 containing 7 elements (each element 1 greater than the previous), what's the last element of the vector? Is it 7 or 6? See the Wikipedia page for off-by-one error.

Sign in to comment.

More Answers (0)

Products

Release

R2022b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!