How to use adapthisteq on an AVI video

13 views (last 30 days)
I am trying to increase the contrast of the frames within my AVI video file. I understand that adapthisteq can be used to increase contrast of single images so i want to adapt this code to cycle through each frame of my video and apply the contrast enhacement to each frame. I need the output to be an AVI video of equal resolution to the input AVI. Below is the code I have adapted from adaphisteq but I am running into the following errors. Any help would be appreciated. Thanks.
my code:
inputFullFileName = fullfile('file_x.avi');
% opening the videoreader for reading an input video file
inputVideoReaderObject = VideoReader(inputFullName)
% creating a videowriter object to write the video out to a new, different file
outputFullFileName = fullfile(pwd, 'file_x.avi');
outputVideoWriterObject = VideoWriter(outputFullFileName);
open(outputVideoWriterObject);
%running the adapthiseq code from: https://uk.mathworks.com/help/images/ref/adapthisteq.html
[X, MAP] = imread('file_x.avi');
RGB = ind2rgb(X, MAP);
LAB = rgb2lab(RGB);
L = LAB(:,:,1)/100;
L = adapthisteq(L, 'NumTiles', [8 8], 'ClipLimit', 0.005);
LAB(:,:,1) = L*100;
J = lab2rgb(LAB);
figure
imshowpair(RGB,J,'montage')
% loop through the movie, writing all frames out
for frame = 1 : numberOfFrames
% extracting the frame from the movie structure
thisInputFrame = read(inputVideoReaderObject, frame);
end
errors:
Error using imread>get_format_info
Unable to determine file format.
error in imread
fmt_s = get_format_info(fullname);
error in contrast_enhancer
[X, MAP] = imread('file_x.avi')

Accepted Answer

Image Analyst
Image Analyst on 22 Nov 2022
Yes good idea but you have a number of errors in there. Mainly that your histogram equalization is not inside your loop over all frames. See my attached demo.
% Demo to extract frames from a input video, and build a new movie where each frame is histogram equalized.
% Illustrates the use of the VideoReader and VideoWriter classes.
% A Mathworks demo (different than mine) is located here http://www.mathworks.com/help/matlab/examples/convert-between-image-sequences-and-video.html
%-------------------------------------------------------------------------------------------------------------------------------------------
% Initialization steps
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures.
clear; % Erase all existing variables.
workspace; % Make sure the workspace panel is showing.
fontSize = 15;
%-------------------------------------------------------------------------------------------------------------------------------------------
% Open the rhino.avi demo movie that ships with MATLAB.
% First get the folder that it lives in.
folder = fileparts(which('rhinos.avi')); % Determine where demo folder is (works with all versions).
% Pick one of the two demo movies shipped with the Image Processing Toolbox.
% Comment out the other one.
inputFullFileName = fullfile(folder, 'rhinos.avi');
% movieFullFileName = fullfile(folder, 'traffic.avi');
% Check to see that it exists.
if ~exist(inputFullFileName, 'file')
strErrorMessage = sprintf('File not found:\n%s\nYou can choose a new one, or cancel', inputFullFileName);
response = questdlg(strErrorMessage, 'File not found', 'OK - choose a new movie.', 'Cancel', 'OK - choose a new movie.');
if strcmpi(response, 'OK - choose a new movie.')
[baseFileName, folderName, FilterIndex] = uigetfile('*.avi');
if ~isequal(baseFileName, 0)
inputFullFileName = fullfile(folderName, baseFileName);
else
return;
end
else
return;
end
end
%-------------------------------------------------------------------------------------------------------------------------------------------
% Open up the VideoReader for reading an input video file.
inputVideoReaderObject = VideoReader(inputFullFileName)
% Determine how many frames there are.
numberOfFrames = inputVideoReaderObject.NumberOfFrames;
inputVideoRows = inputVideoReaderObject.Height
inputVideoColumns = inputVideoReaderObject.Width
%-------------------------------------------------------------------------------------------------------------------------------------------
% Create an output VideoWriter object to write the video out to a new, different file.
outputFullFileName = fullfile(pwd, 'NewRhinos.avi');
outputVideoWriterObject = VideoWriter(outputFullFileName);
open(outputVideoWriterObject);
% Specify the output video size.
shrinkFactor = 4; % Shrink by a factor of 4 in both directions.
outputVideoRows = round(inputVideoRows / shrinkFactor)
outputVideoColumns = round(inputVideoColumns / shrinkFactor)
numberOfFramesWritten = 0;
% Prepare a figure to show the images.
hFig = figure('Name', 'Demo by Image Analyst', 'NumberTitle', 'off');
%-------------------------------------------------------------------------------------------------------------------------------------------
% Loop through the movie, writing all frames out.
for frame = 1 : numberOfFrames
% Extract the frame from the movie structure.
thisInputFrame = read(inputVideoReaderObject, frame);
% Histogram equalize the image.
% First convert the image to LAB color space because to make it look natural
% we want to only filter the overall brightness, not each individual color channel.
LAB = rgb2lab(thisInputFrame);
L = LAB(:, :, 1); % Get the brightness or luminance channel.
% L is floating point in the range 0-100. If we are to use adapthisteq,
% it must be in the range 0-1.
L = L / 100;
% Do the histogram equalization on this frame.
L = adapthisteq(L, 'NumTiles', [8 8], 'ClipLimit', 0.005);
% Undo the scaling to get it back into its original range.
L = L * 100;
% Put the filtered result back into the LAB array.
LAB(:, :, 1) = L;
% Turn it from LAB color space back into RGB colorspace.
outputFrame = 255 * lab2rgb(LAB);
% Make it uint8 so we can put side by side with the original frame.
outputFrame = uint8(outputFrame);
imshowpair(thisInputFrame, outputFrame,'montage');
progressIndication = sprintf('Processed frame %4d of %d.', frame, numberOfFrames);
title(progressIndication, 'FontSize', fontSize);
drawnow;
% Write this new, resized frame out to the new video file.
writeVideo(outputVideoWriterObject, outputFrame);
% 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
% Close the output video object. You don't need to close the input video reader.
close(outputVideoWriterObject);
%================================================================================
% NOW WE'RE DONE!
%================================================================================
% Alert user that we're done.
finishedMessage = sprintf('Done! It processed %d frames of\n"%s" and created output video\n%s.\nClick OK to see the output video.', numberOfFramesWritten, inputFullFileName, outputFullFileName);
fprintf('%s\n', finishedMessage); % Write to command window.
uiwait(msgbox(finishedMessage)); % Also pop up a message box.
% OPTIONAL: Play the movie in the default Windows program that plays videos.
winopen(outputFullFileName);
  8 Comments
David Gill
David Gill on 23 Nov 2022
assuming I would change the following line of code to acheive this? I changed 1 to 10 to test if it displayed every ten frames instead but still displaying count with an increment of 1.
proressIndication = sprintf('processed frame %4 of %4.', frame, numberOfFrames);
disp(progressIndication);
%increment frame count (should eventually = numberOfFrames unless error happens)
numberOfFramesWritten = numberOfFramesWritten + 1;
Image Analyst
Image Analyst on 23 Nov 2022
I don't see anything there that executes those lines only every 10 frames. Where did you use rem or mod like I suggested? You need to do
numberOfFrames = 100;
for frame = 1 : numberOfFrames
if rem(frame, 10) == 0 % Only print every 10th frame
progressIndication = sprintf('Processed frame #%4d of %4d.', frame, numberOfFrames);
disp(progressIndication);
end
end
Processed frame # 10 of 100. Processed frame # 20 of 100. Processed frame # 30 of 100. Processed frame # 40 of 100. Processed frame # 50 of 100. Processed frame # 60 of 100. Processed frame # 70 of 100. Processed frame # 80 of 100. Processed frame # 90 of 100. Processed frame # 100 of 100.

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!