Browse Source

Execution time improvements, Various fixes, Init bilinear interpolation

master
Apostolos Fanakis 6 years ago
parent
commit
5c24299518
  1. 343
      Assignment_1/bayer2rgb.m

343
Assignment_1/bayer2rgb.m

@ -16,75 +16,257 @@ function xc = bayer2rgb(xb, M, N, method)
gridPointsStepLengthY = (bayerPatternDimY - 1) / (M - 1); gridPointsStepLengthY = (bayerPatternDimY - 1) / (M - 1);
gridPointsStepLengthX = (bayerPatternDimX - 1) / (N - 1); gridPointsStepLengthX = (bayerPatternDimX - 1) / (N - 1);
% Calculates the coordinates of the grid points for both axes % Calculates the coordinates of the grid points for both axes
gridPointsCoordinatesY = 1:gridPointsStepLengthY:bayerPatternDimY; gridPointsCoordinatesY = (1:gridPointsStepLengthY:bayerPatternDimY)';
gridPointsCoordinatesX = 1:gridPointsStepLengthX:bayerPatternDimX; gridPointsCoordinatesX = (1:gridPointsStepLengthX:bayerPatternDimX)';
if (strcmp(method, 'nearest')) if (strcmp(method, 'nearest'))
% Determines the indeces of the even rows of the original image
% that are closest to each ordinate of the new image grid
gridPointYmod2 = mod(gridPointsCoordinatesY, 2) >= 1;
nearestEvenRow = floor(gridPointsCoordinatesY);
nearestEvenRow(gridPointYmod2) = nearestEvenRow(gridPointYmod2)+1;
nearestEvenRow(nearestEvenRow > bayerPatternDimY) = ...
nearestEvenRow(nearestEvenRow > bayerPatternDimY) - 2;
% Determines the indeces of the odd rows of the original image that
% are closest to each ordinate of the new image grid
nearestOddRow = floor(gridPointsCoordinatesY);
nearestOddRow(~gridPointYmod2) = nearestOddRow(~gridPointYmod2)+1;
nearestOddRow(nearestOddRow > bayerPatternDimY) = ...
nearestOddRow(nearestOddRow > bayerPatternDimY) - 2;
% Determines the indeces of the even columns of the original image
% that are closest to each abscissa of the new image grid
gridPointXmod2 = mod(gridPointsCoordinatesX, 2) >= 1;
nearestEvenCol = floor(gridPointsCoordinatesX);
nearestEvenCol(gridPointXmod2) = nearestEvenCol(gridPointXmod2)+1;
nearestEvenCol(nearestEvenCol > bayerPatternDimX) = ...
nearestEvenCol(nearestEvenCol > bayerPatternDimX) - 2;
% Determines the indeces of the odd columns of the original image
% that are closest to each abscissa of the new image grid
nearestOddCol = floor(gridPointsCoordinatesX);
nearestOddCol(~gridPointXmod2) = nearestOddCol(~gridPointXmod2)+1;
nearestOddCol(nearestOddCol > bayerPatternDimX) = ...
nearestOddCol(nearestOddCol > bayerPatternDimX) - 2;
% Determines the indeces of the rows (even or odd) of the original
% image that are closest to each ordinate of the new image grid
totalNearestRow = round(gridPointsCoordinatesY);
% Determines the indeces of the columns (even or odd) of the
% original image that are closest to each abscissa of the new image
totalNearestCol = round(gridPointsCoordinatesX);
% Closest neighbors for red and blue can be determined by observing
% the Bayer pattern
xc.red = xb(nearestOddRow, nearestEvenCol);
xc.blue = xb(nearestEvenRow, nearestOddCol);
for currentRow = 1:M for currentRow = 1:M
% Determines the index of the even row of the original image for currentCol = 1:N
% that is closest to this ordinate (currentRow) of the new if ((mod(totalNearestRow(currentRow), 2) == 0 && ...
% image mod(totalNearestCol(currentCol), 2)) ~= 0 || ...
idx = mod(gridPointsCoordinatesY(currentRow), 2) >= 1; (mod(totalNearestRow(currentRow), 2) ~= 0 && ...
nearestEvenRow = floor(gridPointsCoordinatesY(currentRow)); mod(totalNearestCol(currentCol), 2) == 0))
nearestEvenRow(idx) = nearestEvenRow(idx)+1; % This point of the original image doesn't contain
if (nearestEvenRow > bayerPatternDimY) % information about the green colour
nearestEvenRow = nearestEvenRow - 2;
end % Calculates the vertical displacement of the two
% diagonal lines that cross this point
b1 = totalNearestRow(currentRow) - ...
totalNearestCol(currentCol);
b2 = totalNearestRow(currentRow) + ...
totalNearestCol(currentCol);
% Calculates the ordinate of the two diagonals at the
% abscissa of the current point (currentCol)
y1 = gridPointsCoordinatesX(currentCol) + b1;
y2 = -gridPointsCoordinatesX(currentCol) + b2;
% Initializes temporary coordinates of the point which
% will be selected as the closest one
fixedNearestRow = totalNearestRow(currentRow);
fixedNearestCol = totalNearestCol(currentCol);
% Determines the index of the odd row of the original image % Checks the relative position between the point and
% that is closest to this ordinate (currentRow) of the new % the two diagonals
% image if (gridPointsCoordinatesY(currentRow) >= y1 && ...
idx = mod(gridPointsCoordinatesY(currentRow), 2) < 1; gridPointsCoordinatesY(currentRow) >= y2)
nearestOddRow = floor(gridPointsCoordinatesY(currentRow)); fixedNearestRow = totalNearestRow(currentRow) - 1;
nearestOddRow(idx) = nearestOddRow(idx)+1; elseif (gridPointsCoordinatesY(currentRow) < y1 && ...
if (nearestOddRow > bayerPatternDimY) gridPointsCoordinatesY(currentRow) < y2)
nearestOddRow = nearestOddRow - 2; fixedNearestRow = totalNearestRow(currentRow) + 1;
elseif (gridPointsCoordinatesY(currentRow) >= y1 && ...
gridPointsCoordinatesY(currentRow) < y2)
fixedNearestCol = totalNearestCol(currentCol) - 1;
elseif (gridPointsCoordinatesY(currentRow) < y1 && ...
gridPointsCoordinatesY(currentRow) >= y2)
fixedNearestCol = totalNearestCol(currentCol) + 1;
end
if (fixedNearestRow < 1)
% Fix for the marginal first row case
xc.green(currentRow, currentCol) = ...
xb(1, fixedNearestCol - 1);
else
xc.green(currentRow, currentCol) = ...
xb(fixedNearestRow, fixedNearestCol);
end
else
xc.green(currentRow, currentCol) = ...
xb(totalNearestRow(currentRow), ...
totalNearestCol(currentCol));
end
end end
end
elseif (strcmp(method, 'linear'))
% Calculates helper variables
flooredCoordinatesY = floor(gridPointsCoordinatesY);
flooredCoordinatesX = floor(gridPointsCoordinatesX);
% Calculates the ordinate of the upper couple of nearest points
% that will be used in the interpolation for the blue colour
upperBlueY = flooredCoordinatesY;
upperBlueY(mod(upperBlueY, 2) ~= 0) = ...
upperBlueY(mod(upperBlueY, 2) ~= 0) - 1;
upperBlueY = upperBlueY + 2;
% Calculates the ordinate of the upper couple of nearest points
% that will be used in the interpolation for the red colour
upperRedY = flooredCoordinatesY;
upperRedY(mod(upperRedY, 2) == 0) = ...
upperRedY(mod(upperRedY, 2) == 0) - 1;
upperRedY = upperRedY + 2;
% Calculates the abscissa of the left couple of nearest points that
% will be used in the interpolation for the blue colour
leftBlueX = flooredCoordinatesX;
leftBlueX(mod(leftBlueX, 2) == 0) = ...
leftBlueX(mod(leftBlueX, 2) == 0) - 1;
leftBlueX = leftBlueX + 2;
% Determines the index of the row (even or odd) of the original % Calculates the abscissa of the left couple of nearest points that
% image that is closest to this ordinate (currentRow) of the % will be used in the interpolation for the red colour
% new image leftRedX = flooredCoordinatesX;
totalNearestRow = round(gridPointsCoordinatesY(currentRow)); leftRedX(mod(leftRedX, 2) ~= 0) = ...
leftRedX(mod(leftRedX, 2) ~= 0) - 1;
leftRedX = leftRedX + 2;
% Determines the indeces of the rows (even or odd) of the original
% image that are closest to each ordinate of the new image grid
centerPointRow = round(gridPointsCoordinatesY);
% Determines the indeces of the columns (even or odd) of the
% original image that are closest to each abscissa of the new image
centerPointCol = round(gridPointsCoordinatesX);
% Adds a padding to the original image, replicating the last two
% rows and columns of each egde
xbPadded = [xb(:, end - 1) xb(:, end - 2) xb xb(:, end - 2) ...
xb(:, end - 1)];
xbPadded = [xbPadded(1, :); xbPadded(2, :); xbPadded; ...
xbPadded(end - 2, :); xbPadded(end - 1, :)];
for currentRow = 1:M
lowerInterpPointBlue = ...
((leftBlueX + 2 - gridPointsCoordinatesX) / 2)' .* ...
xbPadded(upperBlueY(currentRow) + 2, leftBlueX) + ...
((gridPointsCoordinatesX - leftBlueX) / 2)' .* ...
xbPadded(upperBlueY(currentRow) + 2, leftBlueX + 2);
upperInterpPointBlue = ...
((leftBlueX + 2 - gridPointsCoordinatesX) / 2)' .* ...
xbPadded(upperBlueY(currentRow), leftBlueX) + ...
((gridPointsCoordinatesX - leftBlueX) / 2)' .* ...
xbPadded(upperBlueY(currentRow), leftBlueX + 2);
xc.blue(currentRow, :) = ...
((upperBlueY(currentRow) - ...
gridPointsCoordinatesY(currentRow)) / 2) * ...
lowerInterpPointBlue + ...
((gridPointsCoordinatesY(currentRow) - ...
upperBlueY(currentRow) + 2) / 2) * ...
upperInterpPointBlue;
lowerInterpPointRed = ...
((leftRedX + 2 - gridPointsCoordinatesX) / 2)' .* ...
xbPadded(upperRedY(currentRow) + 2, leftRedX) + ...
((gridPointsCoordinatesX - leftRedX) / 2)' .* ...
xbPadded(upperRedY(currentRow) + 2, leftRedX + 2);
upperInterpPointRed = ...
((leftRedX + 2 - gridPointsCoordinatesX) / 2)' .* ...
xbPadded(upperRedY(currentRow), leftRedX) + ...
((gridPointsCoordinatesX - leftRedX) / 2)' .* ...
xbPadded(upperRedY(currentRow), leftRedX + 2);
xc.red(currentRow, :) = ...
((upperRedY(currentRow) - gridPointsCoordinatesY(currentRow)) / 2) * ...
lowerInterpPointRed + ...
((gridPointsCoordinatesY(currentRow) - upperRedY(currentRow) + 2) / 2) * ...
upperInterpPointRed;
for currentCol = 1:N for currentCol = 1:N
% Determines the index of the even column of the original if ((mod(centerPointRow(currentRow), 2) == 0 && ...
% image that is closest to this abscissa (currentCol) of mod(centerPointCol(currentCol), 2)) == 0 || ...
% the new image (mod(centerPointRow(currentRow), 2) ~= 0 && ...
idx = mod(gridPointsCoordinatesX(currentCol), 2) >= 1; mod(centerPointCol(currentCol), 2) ~= 0))
nearestEvenCol = floor(gridPointsCoordinatesX(currentCol)); % This point of the original image DOES contain
nearestEvenCol(idx) = nearestEvenCol(idx)+1; % information about the green colour
if (nearestEvenCol > bayerPatternDimX)
nearestEvenCol = nearestEvenCol - 2;
end
% Determines the index of the even column of the original % Calculates the vertical displacement of the two
% image that is closest to this abscissa (currentCol) of % diagonal lines that cross this point
% the new image b1 = centerPointRow(currentRow) - ...
idx = mod(gridPointsCoordinatesX(currentCol), 2) < 1; centerPointCol(currentCol);
nearestOddCol = floor(gridPointsCoordinatesX(currentCol)); b2 = centerPointRow(currentRow) + ...
nearestOddCol(idx) = nearestOddCol(idx)+1; centerPointCol(currentCol);
if (nearestOddCol > bayerPatternDimX)
nearestOddCol = nearestOddCol - 2;
end
% Determines the index of the column (even or odd) of the % Calculates the ordinate of the two diagonals at the
% original image that is closest to this abscissa % abscissa of the current point (currentCol)
% (currentCol) of the new image y1 = gridPointsCoordinatesX(currentCol) + b1;
totalNearestCol = round(gridPointsCoordinatesX(currentCol)); y2 = -gridPointsCoordinatesX(currentCol) + b2;
if (mod(totalNearestRow, 2) == 0 && mod(totalNearestCol, 2) ~= 0)
totalNearestCol = totalNearestCol + 1; % Initializes temporary coordinates of the point which
elseif (mod(totalNearestRow, 2) ~= 0 && mod(totalNearestCol, 2) == 0) % will be selected as the center
totalNearestCol = totalNearestCol - 1; fixedCenterPointRow = centerPointRow(currentRow);
end fixedCenterPointCol = centerPointCol(currentCol);
% Checks the relative position between the point and
% the two diagonals
if (gridPointsCoordinatesY(currentRow) >= y1 && ...
gridPointsCoordinatesY(currentRow) >= y2)
fixedCenterPointRow = centerPointRow(currentRow) - 1;
elseif (gridPointsCoordinatesY(currentRow) < y1 && ...
gridPointsCoordinatesY(currentRow) < y2)
fixedCenterPointRow = centerPointRow(currentRow) + 1;
elseif (gridPointsCoordinatesY(currentRow) >= y1 && ...
gridPointsCoordinatesY(currentRow) < y2)
fixedCenterPointCol = centerPointCol(currentCol) - 1;
elseif (gridPointsCoordinatesY(currentRow) < y1 && ...
gridPointsCoordinatesY(currentRow) >= y2)
fixedCenterPointCol = centerPointCol(currentCol) + 1;
end
% Closest neighbors per colour can be determined by if (fixedCenterPointRow < 1)
% observing the Bayer pattern % Fix for the marginal first row case
xc.red(currentRow, currentCol) = xb(nearestOddRow, nearestEvenCol); fixedCenterPointRow = 1;
xc.blue(currentRow, currentCol) = xb(nearestEvenRow, nearestOddCol); fixedCenterPointCol = fixedCenterPointCol - 1;
xc.green(currentRow, currentCol) = xb(totalNearestRow, totalNearestCol); end
xc.green(currentRow, currentCol) = ...
tiltedInterp(gridPointsCoordinatesX(currentCol), ...
gridPointsCoordinatesY(currentRow), ...
fixedCenterPointCol, fixedCenterPointRow, xbPadded);
else
xc.green(currentRow, currentCol) = ...
tiltedInterp(gridPointsCoordinatesX(currentCol), ...
gridPointsCoordinatesY(currentRow), ...
centerPointCol(currentCol), ...
centerPointRow(currentRow), xbPadded);
end
end end
end end
elseif (strcmp(method, 'linear'))
end end
% Combines colours to a single image array and shows the result % Combines colours to a single image array and shows the result
@ -92,3 +274,52 @@ function xc = bayer2rgb(xb, M, N, method)
figure(); figure();
imshow(rgbImage); imshow(rgbImage);
end end
function value = tiltedInterp(xw, yw, xc, yc, xbPadded)
% Calculates the vertical displacement of the main diagonal that
% crosses this point
bw = yw - xw;
% Calculates the abscissas of the points of intersection
x1 = (yc + xc - 1 - bw) / 2;
%x2 = (yc + xc + 1 - bw) / 2;
% Calculates perpendicular distance of point w to the line connecting
% the lower point and the left point
dist = sqrt((x1 - xw) ^ 2 + (x1 + bw - yw) ^ 2);
% Calculates the lengths of the upper parts of the lines connecting the
% points
h1 = sqrt(((xc - 1 - xw) ^ 2 + (yc - yw) ^ 2) - dist ^ 2);
lowerLeftInterpPoint = ...
((sqrt(2) - h1) / sqrt(2)) * ...
xbPadded(yc + 2, xc - 1 + 2) + ...
(h1 / sqrt(2)) * ...
xbPadded(yc + 1 + 2, xc + 2);
upperRightInterpPoint = ...
((sqrt(2) - h1) / sqrt(2)) * ...
xbPadded(yc - 1 + 2, xc + 2) + ...
(h1 / sqrt(2)) * ...
xbPadded(yc + 2, xc + 1 + 2);
value = ...
(sqrt(2) - dist) / sqrt(2) * lowerLeftInterpPoint + ...
dist / sqrt(2) * upperRightInterpPoint;
end

Loading…
Cancel
Save