Blank Pixels When Correcting Wide-Angle (Barrel-Distortion) Images Using Polynomial Model
조회 수: 2 (최근 30일)
이전 댓글 표시
Hi everyone.
I have implemented a barrel-distotion correction algorithm (currently only experimenting with one radial-distortion coefficient, k1) to correct an image taken from a wide-angle (fish-eye) lens. However, the resulting corrected picture appears to have a pattern of blank pixels. I assume this is because the pixels get translated outwards rather than inwards. I can not seem to find any resource that faces this problem hence I am asking here. If anyone has faced this issue before, kindly explain where my algorithm is flawed. Comments in my code may help in understanding the steps I am taking. Original distorted photo and corrected photo are also shown to clarify what I mean. Thank you in advance.
Original Photo (3840x2160):
Resulting Corrected photo(7640x4480):
% imshow(a(:,:,1));
param =[0.0000002 0 0 0 0];
%param =[0.0000004 0 0 0 0];
%param = [0.0000002 -0.0000000000002 0 0 0];
%param = [0.0000002 -0.0000000000001 0 0 0];
k1 = param(1);
k2 = param(2);
k3 = param(3);
p1 = param(4);
p2 = param(5);
%get image and dimensions and rgb values
pic_in = imread('city.jpg');
[yres, xres, ch] = size(pic_in);
%xtrax and xtray are extra pixels that enlarge the corrected image
%frame such that some of the corrected pixel locations that exceed
%original picture dimensions are still visible
xtrax = 3800;
xtray = 2320;
corrected_pic = zeros( yres + xtray, xres + xtrax, ch);
%undistort
tic;
for yi = 1:1:yres
for xi = 1:1:xres
%get pixel value
pixel = pic_in(yi,xi,:);
%convert matrix index to coordinate
x1 = cx(xi, xres);
y1 = cy(yi, yres);
%get coordinate of distortion
x2 = floor(correct_x(x1,y1,k1,k2,k3,p1,p2));
y2 = floor(correct_y(x1,y1,k1,k2,k3,p1,p2));
%convert coordinate into matrix index
x3 = mx(x2, xres, xtrax);
y3 = my(y2, yres, xtray);
%place pixel in new distorted coordinate
if( x3 > 0 && x3 <= xres+xtrax && y3 > 0 && y3 <= yres+xtray )
corrected_pic(y3,x3,:) = pixel;
end
end
end
toc;
figure();
corrected_pic = uint8(corrected_pic);
image(corrected_pic);
title('corrected');
figure();
imshow(pic_in);
title('distorted input');
%% calculate corrected coordinates based on lens parameters and actual coordinate
function x2 = correct_x(x1,y1,k1,k2,k3,p1,p2)
x2 = (x1*(1+(k1*((radius(x1,y1))^2))+(k2*((radius(x1,y1))^4))))+(2*p1*x1*y1)+(p2*(((radius(x1,y1))^2)+ 2*(x1^2)));
end
function y2 = correct_y(x1,y1,k1,k2,k3,p1,p2)
y2 = (y1*(1+(k1*((radius(x1,y1))^2))+(k2*((radius(x1,y1))^4))))+(2*p2*x1*y1)+(p1*(((radius(x1,y1))^2)+ 2*(y1^2)));
end
%% converts matrix index x to x coordinate(image center as origin)
function x = cx(xi, xres)
x = xi - (xres/2);
end
%% converts matrix index y to y coordinate(image center as origin)
function y = cy(yi, yres)
y = -1*yi + (yres/2);
end
%% gets radius
function r = radius(x,y)
r = abs(sqrt((x^2)+(y^2)));
end
%% converts x coordinate to matrix index x
function x = mx(xi, xres, xtrax)
x = xi + (xres/2) + xtrax/2;
end
%% converts y coordinate to matrix index y
function y = my(yi, yres, xtray)
y = -1*yi + (yres/2) + xtray/2;
end
% %% finds extra frame space needed such that no pixel is outside frame after correction
% function xtrax = find_xtrax( xres, yres, k1, k2, k3, p1, p2)
% xmax = xres/2;
% ymax = yres/2;
% xmax = correct_x(xmax,ymax,k1,k2,k3,p1,p2);
% xtrax = ceil(xmax-(xres/2));
%
% end
%
% function xtray = find_xtray( xres, yres, k1, k2, k3, p1, p2)
% xmax = xres/2;
% ymax = yres/2;
% ymax = correct_y(xmax,ymax,k1,k2,k3,p1,p2);
% xtray = ceil(ymax-(yres/2));
% end
댓글 수: 0
답변 (1개)
Image Analyst
2019년 11월 10일
You have holes in your image, because you're scanning the input image and deciding where the input pixel should go to in the output image. This is an intuitive, but wrong, approach that many beginners make. What happens is that you have some output pixels that never got an input pixel sent to them.
What you need to do is to scan the output image and decide where to pull the input pixel from. This will be a floating point number (between 4 input pixels) so you will have to use interpolation to figure out what the input pixel value would be at that location, since it most likely does not line up perfectly with an input pixel.
By the way, you might speed up the algorithm some by swapping the x and y loops. If y is the inside loop, you are scanning the memory in column major order (down rows in a particular column first, then move to to the next column) which is the way matrices are stored in memory in MATLAB.
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!