Walkthrough for using the overlay method:
1) Get an application that can permanently overlay an image over the screen. On MacOS, I used Uberlayer.
2) Make a good photo of the display with completely white background. The camera should be roughly at the position, from which you commonly look at the screen. Also, we want to take a longer exposition (e.g.: 1 second) in order to avoid capturing the display refresh deformations (they look like a moire pattern on my display). Hence, a stative can be handy. Finally, it can be better to take a photo in a darkened room in order to avoid capturing reflections on the display.
3) Convert the photo to shades of shade.
4) Write down the position of the bright spots on the photo in pixels.
5) Write down the position of the bright spots on your display in pixels. I used Ruler.
6) Align the photo to the screen with a combination of RANSAC and projective transformation.
7) Homogenize the illumination of the photo.
8) Invert the color of the image - bright spots will become dark spots.
9) Set the transparency.
10) Use the generated image as the screen overlay.
The script in Matlab:
% Load data
original = rgb2gray(imread('photo.tif'));
% Location of spots on the photo (as read from: imshow(original))
% From: left x top.
photo = [
556 1125 % the brightest speckel
101 961 % the single speckel on the left
61 1578 % the bottom left single pixel
2422 1161 % right: the top bright spot
2465 1216 % right: the lowest bright spot on right
1065 698 % middle: the brightest speckel (north west)
15 31 % corners...
2545 1637
22 1630
2548 67
];
% Location of bright points on the display
% Averaged from 2 measures
screen = [
302.5 611 % the brightest speckel
47 523 % the single speckel on the left
23 870 % the bottom left single pixel
1367.5 627 % right: the top bright spot
1393.5 658.5 % right: the lowest bright spot on right
589 368 % middle: the brightest speckel (north west)
1 1 % corners...
1440 900
1 900
1440 1
];
% Visualization
figure('Name', 'Photo')
imshow(original);
hold on
plot(photo(:,1), photo(:,2), 'or')
% Map photo to screen coordinates
rng(2001); % RANSAC is stochastic (it may exclude outliers) -> set seed
[tform, inlierpoints1, inlierpoints2] = estimateGeometricTransform(photo, screen, 'projective', 'MaxDistance', 3);
% Transform the photo
outputView = imref2d(size(original));
image = imwarp(original, tform, 'OutputView', outputView, 'FillValues', 255);
% Crop the image to the size of the screen
image = image(1:900, 1:1440);
% Plot the aligned photo
figure('Name', 'Photo after transformation')
imshow(image)
hold on
plot(screen(:,1), screen(:,2), 'ob')
%% Illumination homogenization
% First, we remove the white speckles. See:
% https://www.mathworks.com/help/images/correcting-nonuniform-illumination.html
se = strel('disk', 25);
background = imopen(image, se);
% Gaussian smoothing creates nicely smooth transitions (at least with doubles)
smoothed = imgaussfilt(double(background), 25);
% Subtract background illumination from the image to get the foreground
foreground = double(image) - smoothed;
% Remove too dark pixels (essentially the leaking border)
threshold = median(foreground(:)) + std(foreground(:));
borderless = max(threshold, foreground);
imagesc(borderless)
%% Invert the colors
result = uint8(255-(borderless-threshold));
imshow(result)
%% Set transparency
black = uint8(ones(900, 1440));
maximum = max(borderless(:));
minimum = min(borderless(:));
alpha = (borderless-minimum)/(maximum-minimum);
%% Store the image
imwrite(black, 'overlay.png', 'alpha', alpha)
Žádné komentáře:
Okomentovat