Find brightest frame in video file

I need to import a video file (which contains 1000s or 10,000s of frames) and find the brightest frame; and isolate and save that frame.
The image can br happily converted to greyscale if that makes things easier.

 Accepted Answer

See my attached demo that runs through a video getting the mean R, G, and B, and gray scale brightness. Once you've run though the video you can look at the vector of brightnesses to determine which frame was the brightest and then copy that particular frame somewhere, like to disk with imwrite.

8 Comments

thanks so much, I will look at this later and report back.
So did it work? If you can't figure out how to adapt it, let me know. Otherwise if you could accept the answer I'd appreciate it.
I ran the code and it was very useful - thanks. However, I will have to lok through it and change becasue I think it is *too* good!.
I have batches of hundreds of videos, lasting from seconds to up to 1/2 hour or so and all I need to know is if there is a bright frame in each video and what number that frame is and save it. Watching through the video - as your script does - would be the same as me manually looking at the videos and confirming a bright frame (if that makes sense!).
thank you for your help
To process a sequence of files, see the FAQ:
Or you could use a GUI like
In the loop over all videos you would call a function that processed just one video.
To speed things up you could just skip displaying images and plots. But you definitely have to process each frame in advance. If you don't then how could you know which one was the brightest one?
thank you - that was what I was thinking - skipping the plots; throwing all the files at the script and saving the relevent frame (with a frame/time number).
Thanks again! This is the first time I've done any image processing with matlab - its all new!
I am having trouble displaying the brightest frame.
This seems to work
[max_brightness_value,max_brightness_image_frame] = max(meanGrayLevels)
% display brightest video frame
figure
image(read(videoObject, max_brightness_image_frame));
title(['brightest frame is frame ',num2str(max_brightness_image_frame)...
' and the brightness value is ',num2str(max_brightness_value)])
but when I want to display the frame before (i.e frame-1) and after (frame+1) that (just to do a visual check); then the image is blank...
figure
image(read(videoObject, max_brightness_image_frame-1));
title(['brightest frame is frame ',num2str(max_brightness_image_frame-1)...
' and the brightness value is ',num2str(max_brightness_value-1)])
seems something silly is missing?
Try this:
hFig = figure;
hFig.Name = 'Brightest Frame';
hFig.WindowState = 'maximized';
% Show brightest frame in the middle.
subplot(1, 3, 2);
thisFrame = read(videoObject, max_brightness_image_frame);
% IMPORTANT NOTE: convert to gray level if needed - if that's how you decided upong the brightest frame..
meanOfThisFrame = mean(thisFrame);
imshow(thisFrame);
impixelinfo; % Let user mouse around and see (x, y, RGB)
axis('on', 'image');
caption = sprintf('The brightest frame is #%d and the mean is %.3f', max_brightness_image_frame, meanOfThisFrame);
title(caption);
% Show frame before the brightest frame on the left.
subplot(1, 3, 1);
thisFrame = read(videoObject, max_brightness_image_frame - 1);
% IMPORTANT NOTE: convert to gray level if needed - if that's how you decided upong the brightest frame..
meanOfThisFrame = mean(thisFrame);
imshow(thisFrame);
impixelinfo; % Let user mouse around and see (x, y, RGB)
axis('on', 'image');
caption = sprintf('The frame before is #%d and the mean is %.3f', max_brightness_image_frame - 1, meanOfThisFrame);
title(caption);
% Show frame after the brightest frame on the right.
subplot(1, 3, 3);
thisFrame = read(videoObject, max_brightness_image_frame + 1);
% IMPORTANT NOTE: convert to gray level if needed - if that's how you decided upong the brightest frame..
meanOfThisFrame = mean(thisFrame);
imshow(thisFrame);
impixelinfo; % Let user mouse around and see (x, y, RGB)
axis('on', 'image');
caption = sprintf('The frame after is #%d and the mean is %.3f', max_brightness_image_frame + 1, meanOfThisFrame);
title(caption);
thanks for this; I'll give it a go. Image manipualtion is completely new to me, so this is very intersting. Thanks again. (then onto the GUI!)

Sign in to comment.

More Answers (1)

Bill White
Bill White on 19 Jan 2024
Edited: Bill White on 19 Jan 2024
I have got this working to find the single brightest frame, and the single frames either side; and then composite (merely add) these three frames to a single image that is useful.
However, how would I find an arbitrary number of frames (in videos of varying lengths) above an arbitrary brightness threshold? ( the brightness is mereley the mean gray value of the entire frame)
For example, say there are "x" number of frames in a video that are above a brightness threshold of "y" : "frame_a", "frame_b", "frame_c"...."frame_x"
I would want to find, make and save composite images so that
image a is
(frame_a-1) + (frame_a) + (frame_a+1)
image b is
(frame_b-1) + (frame_b) + (frame_b+1)
image x is
(frame_x1) + (frame_x) + (frame_x+1)
I was getting a bit lost making a loop with changing variable names depending on the loop iteration, and the documentation recommends cells?
I also am aware of an issue if "frame_a" is a bright frame but it is the first frame in the video; then there is no (frame_a-1)
so the composite image a would just be
(frame_a) + (frame_a+1)
or if frame_x is the last frame then there is no (frame_x+1) so image x would just be
(frame_x-1) + (frame_x)
even though this would be rare, it can happen and cause an error if looking for a frame that does not exist.
The images will be saved with a file name that is (for example) "bright frame_a of filename" where "filename" is the name of the video file imported
I have attached what (seems to) work for a single bright composite image.
thanks again
clc;
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear;
workspace; % show workspace
% fontSize = 8;
%%% open video file
[baseFileName, folderName, FilterIndex] = uigetfile('*.*', 'Select Video File');
if ~isequal(baseFileName, 0)
movieFullFileName = fullfile(folderName, baseFileName);
else
return;
end
try
videoObject = VideoReader(movieFullFileName)
% % Determine how many frames there are.
numberOfFrames = videoObject.NumberOfFrames;
% vidHeight = videoObject.Height;
% vidWidth = videoObject.Width;
%
numberOfFramesWritten = 0;
%
% % Loop through the movie, writing all frames out.
% % Each frame will be in a separate file with unique name.
meanGrayLevels = zeros(numberOfFrames, 1);
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
thisFrame = read(videoObject, frame);
% Calculate the mean gray level.
grayImage = rgb2gray(thisFrame);
meanGrayLevels(frame) = mean(grayImage(:));
% Update user with the progress. Display in the command window.
progressIndication = sprintf('Processed frame %4d of %d.', frame, numberOfFrames);
disp(progressIndication);
% Increment frame count (should eventually = numberOfFrames
% unless an error happens).
numberOfFramesWritten = numberOfFramesWritten + 1;
end
% Alert user that we're done. finishedMessage = sprintf('Done! It processed %d frames of\n"%s"', numberOfFramesWritten, movieFullFileName);
finishedMessage = sprintf('Done! It processed %d frames of\n"%s"', numberOfFramesWritten, movieFullFileName);
disp(finishedMessage); % Write to command window.
uiwait(msgbox(finishedMessage)); % Also pop up a message box.
catch ME
% Some error happened if you get here.
strErrorMessage = sprintf('Error extracting movie frames from:\n\n%s\n\nError: %s\n\n)', movieFullFileName, ME.message);
uiwait(msgbox(strErrorMessage));
end
% determine value and index (frame number) of brightest frame
[max_brightness_value,max_brightness_image_frame] = max(meanGrayLevels)
%%%% show composite of three frames
composite = ...
(read(videoObject, max_brightness_image_frame))+...
(read(videoObject, max_brightness_image_frame+1))+...
(read(videoObject, max_brightness_image_frame-1));
hFig = figure;
hFig.Name = 'Composite Frames';
hFig.WindowState = 'maximized';
imshow(composite);
% display title properly without underscores being coverted to subscript
file_name_title = strrep((num2str(baseFileName)), '_', '\_') % ensure underscores show properly in title
title(['composite of frames ',num2str(max_brightness_image_frame-1),...
' + ', num2str(max_brightness_image_frame) ,...
' + ', num2str(max_brightness_image_frame+1),...
' from file ',...
num2str(file_name_title) ]);

Products

Release

R2020b

Community Treasure Hunt

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

Start Hunting!