Simulate rolling shutter effects
Simulate the effects of a rolling shutter, the most common type of shutter in a CMOS imager.
See also: sceneRotate, sensorCompute, ipCompute
Copyright Imageval, LLC, 2014
Contents
- Set the parameters needed to make a rotating series of star patterns
- This is the scene we will rotate
- Make the pattern with sceneRotate, then acquire with sensorCompute
- These are the individual sensor frames
- Create the final sensor image by summing appropriate sensor images
- Image process and then show the final color image
ieInit; ieSessionSet('wait bar','off');
Set the parameters needed to make a rotating series of star patterns
iSize = 128; nLines = 4; fov = 3; scene = sceneCreate('star pattern',iSize,'ee',nLines); scene = sceneSet(scene,'fov',fov); oi = oiCreate; % Create a sensor whose field of view matches the scene size sensor = sensorCreate; pixelSize = [1.4 1.4]*1e-6; % Pixel size of 1.4 um sensor = sensorSet(sensor,'pixel size constant fill factor',pixelSize); sensor = sensorSet(sensor,'fov',sceneGet(scene,'fov')/2,oi); sz = sensorGet(sensor,'size'); % Exposure time of the complete image (all rows). As we increase the % exposure time, the rotating line turns into a wedge. The width of the % wedge increases with exposure time. expTime = 1e-4; % Millisecond regime sensor = sensorSet(sensor,'exp time',expTime); % Read out time per row (should be microsecond range). % % The delay between reading the first and last row is % % perRow * (number of rows) % % At the end of this routine, we assemble the final image by assuming that % the reset time is delayed in the same way that the read out time is % delayed. This gives every row the same exposure duration, but the % acquisition period of each of the rows is delayed in time. % To see a bigger effect of the rolling shutter, make this number bigger. perRow = 10e-6; % How many total captures do we need? Number of rows plus enough additional % captures for last row nFrames = sz(1) + round(expTime/perRow); % Store the sensor volts from each capture separately, before we assemble. v = zeros(sz(1),sz(2),nFrames); % The number of degrees the rays rotate between each row capture (perRow). % The deg per second is rate/perRow or in total rotations per second % rate/perRow/360. The faster the rotation, the more the curvature. rate = 0.3; fprintf('Computing %i frames\nRotation rate: %.2f (cycles per sec)\n',nFrames,rate/perRow/360);
Computing 70 frames Rotation rate: 83.33 (cycles per sec)
This is the scene we will rotate
sceneWindow(scene); oi = oiCompute(oi,scene); oiWindow(oi);


Make the pattern with sceneRotate, then acquire with sensorCompute
w = waitbar(0,'Rotating scenes'); S = 160; % This is the size of the cropped oi for ii=1:nFrames waitbar(ii/nFrames,w,sprintf('Scene %i',ii)); % Rotation shrink the image at the boundary by adding in zero values % where there is an unknown extrapolation. We remove this by the % cropping below. deg = ii*rate; s = sceneRotate(scene,deg); % ieAddObject(s); sceneWindow; % Compute and crop to keep just the center oi = oiCompute(oi,s); cp = oiGet(oi,'center pixel'); rect = round([cp(1) - S/2, cp(2) - S/2, S, S]); oiC = oiCrop(oi,rect); % ieAddObject(oiC); oiWindow; sensor = sensorCompute(sensor,oiC); if ii==1 % After first capture, set noise to photon only sensor = sensorSet(sensor,'noise flag',1); end v(:,:,ii) = sensorGet(sensor,'volts'); end close(w)
These are the individual sensor frames
ieNewGraphWin; colormap(gray(64)); axis image; axis off fps = 7; for ii=1:nFrames imagesc(v(:,:,ii)); pause(1/fps); end

Create the final sensor image by summing appropriate sensor images
% This is the final, summed voltages for each row. final = zeros(sz); % Each row is read out for some proportion of the capture. % This is the list of sensor rows that are read out from each image. % we will add these in to the final image. slist = 1:round(expTime/perRow); z = zeros(nFrames,1); z(slist) = 1; % Sum across a sliding temporal range ieNewGraphWin; colormap(gray(64)); axis image; axis off fps = 7; for rr = 1:sz(1) slist = slist+1; z = zeros(nFrames,1); z(slist) = 1; tmp = squeeze(v(rr,:,:)); final(rr,:) = tmp*z; imagesc(final); pause(1/fps); end % ieNewGraphWin; imagesc(final);

Image process and then show the final color image
srs = sensorSet(sensor,'volts',final);
ip = ipCreate;
ip = ipCompute(ip,srs);
ieAddObject(ip);
ipWindow;
