How to prevent colors changing when appending new frames to a video

조회 수: 5 (최근 30일)
Peter van der Kamp
Peter van der Kamp 2025년 7월 8일
댓글: Peter van der Kamp 2025년 7월 10일
When I read a video and write the frames back into another video the colours change slightly (red turns to orange).
How to prevent this from happening?
Here is code I have used:
Vid = VideoReader('ZV.mp4'); % Video (we want to append to)
v = VideoWriter('ZVC','MPEG-4'); % Create new video file
open(v)
% Iterate on all frames in Video and write one frame at a time
nf=0; %number-of-frames counter
while hasFrame(Vid)
Vidf = readFrame(Vid); % read each frame
writeVideo(v,Vidf); % write each frame
nf=nf+1;
end
%next we create (31) more frames
figure('Position', [0 0 600 600]);
set(gca,'visible','off')
set(gcf,'color','k')
o=-15/2+nf/ft; %ft is a fixed number
b=o+15;
[X,Y] = meshgrid(l:1/ft:r,o:1/ft:b); %l and r are fixed numbers
for i=0:30
Y=Y+1/ft;
o=o+1/ft;
b=b+1/ft;
Z=Ze(nf+1+i:nf+15*ft+1+i,:); %Ze is a precalculated matrix
clf
camroll(-90)
hold on
contourf(X,Y,Z,L,'LineWidth',1); %L is a list of values
contour(X,Y,Z,L,'color',[0 0 0],'LineWidth',1);
colormap(col) %col is a matrix of colours
clim([-15/2 25/2])
xlim([l r])
ylim([o b])
hold off
frame = getframe(gcf);
writeVideo(v,frame)
end
close(v)
%you can't run this code unless you have ZV.mp4 and set ft,l,r,Ze,L and col
%snapshots of a detail from the video are given below
The original colour is
after 1 read-and-write it becomes
after 2 read-and-writes it becomes
after 3 read-and-writes it becomes
  댓글 수: 1
Benjamin Kraus
Benjamin Kraus 2025년 7월 8일
There seem to be two mostly unrelated sections in the code above.
  1. The first section is reading one frame at a time from one file ("ZV.mp4") and writing them to another video file ("ZVC.mp4").
  2. The second section is generating a contour plot and appending those frames to the same video file ("ZVC.mp4").
Is the issue you are facing with the frames from the first section or frames from the second section?
Based on your wording, and the fact that the picture doesn't look like a contour plot, I'm assuming you are talking about the first section of code, but that leaves me wondering why you included the second section of the code (the code starting with "next we create (31) more frames").

댓글을 달려면 로그인하십시오.

답변 (1개)

Benjamin Kraus
Benjamin Kraus 2025년 7월 8일
편집: Benjamin Kraus 2025년 7월 8일
I'm not an exepert in MPEG-4 video compression, but my understanding is that MPEG-4 is a lossy video compression technology, so every time you write your video file you are losing a bit of information, and the video quality will continue to degrade every time you read/write the video. This is not due to MATLAB, but due to the nature of the compression used by MPEG-4 files.
If you look at the documentation for VideoWriter, you can see the name/value pair called LosslessCompression, and the description below it, which includes: "The LosslessCompression property is available only for objects used for writing Motion JPEG 2000 files."
How much information is lost can be tweaked by adjusting the name/value pairs you specify when you create your VideoWriter object. For example, it looks like the Quality property can be used to specify the quality of MPEG-4 videos. Increasing the quality won't prevent you from having degredation of the picture, but it may reduce how bad the impact is.
If your goal is that your picture is perfectly preserved across read/write cycles, then you will need to switch to a lossless compression. MATLAB's VideoWriter supports a few video profiles that include lossless compression. Looking at the documentation, it explicitly states that Archival is lossless, I'm not sure about the other.
  댓글 수: 5
Benjamin Kraus
Benjamin Kraus 2025년 7월 9일
Also: Upon further digging into your code:
contourf(X,Y,Z,L,'LineWidth',1); %L is a list of values
contour(X,Y,Z,L,'color',[0 0 0],'LineWidth',1);
From what I can tell, this looks like you are trying to draw the same contour twice (once filled and once not filled). Because the filled contour also has black edge lines, the second call to contour looks like it is just drawing black lines along the exact same contour as the first call to contour. I can't see why the second call to contour would change the picture in any meaningful way. Why are you calling contour twice? Does the picture change at all if you remove the second call to contour?
Peter van der Kamp
Peter van der Kamp 2025년 7월 10일
To start with your last question, the answer is no, it doesn't change.
As to why that was done that way, I don't know. I made the picture some time ago, and am now making a video about it.
Removing the second contour plot speeds up the process quite a bit, roughly 30% faster, so thanks heaps for your dig!
Now the other thing. I have found that there is actually no difference between mp4 and mj2 in that respect, as expected. What happened is that I moved axis off out of the (frame-creating) loop in which I clear the figure (clf), and clf resets the axis back on. The other thing that I moved out is set(gcf,'color','k'), but this is not undone by clf. The reason that I had clf in the loop is that I have seen remnants of lines at edges of videos before. I have now tested the difference (with or without clf in the loop): there is no visual difference, however, having it in the loop is much much faster than not having it in the loop.
Finally, about the workflow at a higher level, this video is (going to be) a long term project. I am visualising zeros of the Riemann zeta function in a kind of arty way (see below). It takes a lot of time to calculate the data, and also a lot of time to create the frames/video. As there are infinitely many zeros, the video is going to be infinitely long (bounded by memory I guess). Although I enjoy watching the video while it is being created, this quite slow-motion, and I want to show finite parts of the infinite video to other people at proper speed.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Audio and Video Data에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by