Skip to content

Instantly share code, notes, and snippets.

@OrganicIrradiation
Created February 8, 2015 14:04
Show Gist options
  • Save OrganicIrradiation/4d63a870c3ac852f4a0f to your computer and use it in GitHub Desktop.
Save OrganicIrradiation/4d63a870c3ac852f4a0f to your computer and use it in GitHub Desktop.
Magic Lantern HDR video to tonemapped video with MATLAB scripts
% Prerequisites (tested on Mac OS X 10.8.5):
% exiftool (tested with 9.37)
% http://www.sno.phy.queensu.ca/~phil/exiftool/
% Luminance HDR (tested with 2.3.1)
% http://qtpfsgui.sourceforge.net/
function ProcessHDRVideo(MOVIENAME,EVDIFF)
% Include the audio
% [y,Fs] = audioread(moviename);
% filename = fullfile(workingDir,'images','audioTrack.wav');
% audiowrite(filename,y,Fs);
% clear y Fs
inputVideo = VideoReader(MOVIENAME);
Step1MovieToInterpolatedFrames(inputVideo,EVDIFF)
Step2FramesToHDRFrames(inputVideo)
Step3HDRFramesToVideos(inputVideo)
end
function Step1MovieToInterpolatedFrames(INPUTVIDEO,EVDIFF)
mkdir(pwd,'frames');
% Grab the first and second frame and guess which is the light and dark
% frame based upon the average value. THis is crude, but seems to work
% reasonably well.
testFrame1 = read(INPUTVIDEO,1);
testFrame2 = read(INPUTVIDEO,2);
if mean(testFrame1(:)) < mean(testFrame2(:))
DARKFRAMEFIRST = true
else
DARKFRAMEFIRST = false
end
clear testFrame1 testFrame2
% Loop through the frames, export the light and dark frames
% Discard the first and last pair of frames because we will need those
% for interpolation
lastFrame = floor(INPUTVIDEO.NumberOfFrames/2)*2-2;
if DARKFRAMEFIRST
frames = 2:2:lastFrame;
else
frames = 1:2:lastFrame-1;
end
for frame = frames
fprintf('LIGHT - %03.2f%%n',frame/lastFrame*100)
imgLight = read(INPUTVIDEO,frame);
imgLightI = imfuse(read(INPUTVIDEO,frame),...
read(INPUTVIDEO,frame+2),'blend');
% Real frame
filename = fullfile(pwd,'frames',sprintf('frame%06uL.jpg',frame));
imwrite(imgLight,filename,'Quality',100);
% We are assuming the dark frame was captured at ISO 100
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="1.0" "' filename '"']);
% Interpolated frame
filename = fullfile(pwd,'frames',sprintf('frame%06uL.jpg',frame+1));
imwrite(imgLightI,filename,'Quality',100);
% We are assuming the dark frame was captured at ISO 100
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="1.0" "' filename '"']);
end
if DARKFRAMEFIRST
frames = 1:2:lastFrame-1;
else
frames = 2:2:lastFrame;
end
for frame = frames
fprintf('DARK - %03.2f%%n',frame/lastFrame*100)
imgDark = read(INPUTVIDEO,frame);
imgDarkI = imfuse(read(INPUTVIDEO,frame),...
read(INPUTVIDEO,frame+2),'blend');
% Real frame
filename = fullfile(pwd,'frames',sprintf('frame%06uD.jpg',frame));
imwrite(imgDark,filename,'Quality',100);
% The light frame is assumed to be relative to a dark frame with
% ISO 100. The apeture values writtenwith exiftool have been
% calculated from here: https://en.wikipedia.org/wiki/Exposure_value
if (EVDIFF == 1) % ISO 100 : ISO 200
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="1.4" "' filename '"']);
elseif (EVDIFF == 2) % ISO 100 : ISO 400
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="2.0" "' filename '"']);
elseif (EVDIFF == 3) % ISO 100 : ISO 800
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="2.8" "' filename '"']);
elseif (EVDIFF == 4) % ISO 100 : ISO 1600
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="4.0" "' filename '"']);
elseif (EVDIFF == 5) % ISO 100 : ISO 3200
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="5.6" "' filename '"']);
end
% Interpolated frame
filename = fullfile(pwd,'frames',sprintf('frame%06uD.jpg',frame+1));
imwrite(imgDarkI,filename,'Quality',100);
if (EVDIFF == 1) % ISO 100 : ISO 200
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="1.4" "' filename '"']);
elseif (EVDIFF == 2) % ISO 100 : ISO 400
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="2.0" "' filename '"']);
elseif (EVDIFF == 3) % ISO 100 : ISO 800
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="2.8" "' filename '"']);
elseif (EVDIFF == 4) % ISO 100 : ISO 1600
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="4.0" "' filename '"']);
elseif (EVDIFF == 5) % ISO 100 : ISO 3200
system(['exiftool -overwrite_original -ShutterSpeedValue="1" -ApertureValue="5.6" "' filename '"']);
end
end
end
function Step2FramesToHDRFrames(INPUTVIDEO)
mkdir(pwd,'framesHDR');
mkdir(pwd,'framesTonemapped');
% Because of conflicting DYLD paths on Mac OS X, need to do this:
libPath = getenv('DYLD_LIBRARY_PATH');
framePath = getenv('DYLD_FRAMEWORK_PATH');
setenv('DYLD_LIBRARY_PATH', '/usr/local/bin/');
setenv('DYLD_FRAMEWORK_PATH','')
lastFrame = floor(INPUTVIDEO.NumberOfFrames/2)*2-2;
for ii = 2:lastFrame
fprintf('%03.2f%%n',ii/lastFrame*100)
system(['"/Applications/Luminance HDR 2.3.1.app/Contents/MacOS/luminance-hdr-cli" '...
' -s "' fullfile(pwd,'framesHDR',sprintf('framesHDR%06u.hdr',ii)) '"'...
' -t mantiuk08 -o "' fullfile(pwd,'framesTonemapped',sprintf('frameTonemapped%06u.jpg',ii)) '"'...
' "' fullfile(pwd,'frames',sprintf('frame%06uD.jpg',ii)) '"'...
' "' fullfile(pwd,'frames',sprintf('frame%06uL.jpg',ii)) '"']);
end
% Restore the DYLD paths
setenv('DYLD_LIBRARY_PATH',libPath);
setenv('DYLD_FRAMEWORK_PATH',framePath)
end
function Step3HDRFramesToVideos(INPUTVIDEO)
% Open the individual output files
outputDark = VideoWriter('videoDark');
outputDark.FrameRate = INPUTVIDEO.FrameRate;
open(outputDark);
outputLight = VideoWriter('videoLight');
outputLight.FrameRate = INPUTVIDEO.FrameRate;
open(outputLight);
outputTonemapped = VideoWriter('videoTonemapped');
outputTonemapped.FrameRate = INPUTVIDEO.FrameRate;
open(outputTonemapped);
% Load the images, convert them to frames, and write them to the output
% streams.
lastFrame = floor(INPUTVIDEO.NumberOfFrames/2)*2-2;
for ii = 2:lastFrame
fprintf('%03.2f%%n',ii/lastFrame*100)
frameDark = im2frame(imread(fullfile(pwd,'frames',sprintf('frame%06uD.jpg',ii))));
frameLight = im2frame(imread(fullfile(pwd,'frames',sprintf('frame%06uL.jpg',ii))));
frameTonemapped = im2frame(imread(fullfile(pwd,'framesTonemapped',sprintf('frameTonemapped%06u.jpg',ii))));
writeVideo(outputDark,frameDark);
writeVideo(outputLight,frameLight);
writeVideo(outputTonemapped,frameTonemapped);
end
close(outputDark);
close(outputLight);
close(outputTonemapped);
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment