From 5c24299518be724eb96d308aaacca082330af4fb Mon Sep 17 00:00:00 2001 From: Apostolof Date: Fri, 22 Mar 2019 23:45:00 +0200 Subject: [PATCH] Execution time improvements, Various fixes, Init bilinear interpolation --- Assignment_1/bayer2rgb.m | 349 ++++++++++++++++++++++++++++++++------- 1 file changed, 290 insertions(+), 59 deletions(-) diff --git a/Assignment_1/bayer2rgb.m b/Assignment_1/bayer2rgb.m index 3acd870..f853c70 100644 --- a/Assignment_1/bayer2rgb.m +++ b/Assignment_1/bayer2rgb.m @@ -16,75 +16,257 @@ function xc = bayer2rgb(xb, M, N, method) gridPointsStepLengthY = (bayerPatternDimY - 1) / (M - 1); gridPointsStepLengthX = (bayerPatternDimX - 1) / (N - 1); % Calculates the coordinates of the grid points for both axes - gridPointsCoordinatesY = 1:gridPointsStepLengthY:bayerPatternDimY; - gridPointsCoordinatesX = 1:gridPointsStepLengthX:bayerPatternDimX; + gridPointsCoordinatesY = (1:gridPointsStepLengthY:bayerPatternDimY)'; + gridPointsCoordinatesX = (1:gridPointsStepLengthX:bayerPatternDimX)'; 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 - % Determines the index of the even row of the original image - % that is closest to this ordinate (currentRow) of the new - % image - idx = mod(gridPointsCoordinatesY(currentRow), 2) >= 1; - nearestEvenRow = floor(gridPointsCoordinatesY(currentRow)); - nearestEvenRow(idx) = nearestEvenRow(idx)+1; - if (nearestEvenRow > bayerPatternDimY) - nearestEvenRow = nearestEvenRow - 2; + for currentCol = 1:N + if ((mod(totalNearestRow(currentRow), 2) == 0 && ... + mod(totalNearestCol(currentCol), 2)) ~= 0 || ... + (mod(totalNearestRow(currentRow), 2) ~= 0 && ... + mod(totalNearestCol(currentCol), 2) == 0)) + % This point of the original image doesn't contain + % information about the green colour + + % 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); + + % Checks the relative position between the point and + % the two diagonals + if (gridPointsCoordinatesY(currentRow) >= y1 && ... + gridPointsCoordinatesY(currentRow) >= y2) + fixedNearestRow = totalNearestRow(currentRow) - 1; + elseif (gridPointsCoordinatesY(currentRow) < y1 && ... + gridPointsCoordinatesY(currentRow) < y2) + 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 + 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; + + % Calculates the abscissa of the left couple of nearest points that + % will be used in the interpolation for the red colour + leftRedX = flooredCoordinatesX; + 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); - % Determines the index of the odd row of the original image - % that is closest to this ordinate (currentRow) of the new - % image - idx = mod(gridPointsCoordinatesY(currentRow), 2) < 1; - nearestOddRow = floor(gridPointsCoordinatesY(currentRow)); - nearestOddRow(idx) = nearestOddRow(idx)+1; - if (nearestOddRow > bayerPatternDimY) - nearestOddRow = nearestOddRow - 2; - end + 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; - % Determines the index of the row (even or odd) of the original - % image that is closest to this ordinate (currentRow) of the - % new image - totalNearestRow = round(gridPointsCoordinatesY(currentRow)); - for currentCol = 1:N - % Determines the index of the even column of the original - % image that is closest to this abscissa (currentCol) of - % the new image - idx = mod(gridPointsCoordinatesX(currentCol), 2) >= 1; - nearestEvenCol = floor(gridPointsCoordinatesX(currentCol)); - nearestEvenCol(idx) = nearestEvenCol(idx)+1; - if (nearestEvenCol > bayerPatternDimX) - nearestEvenCol = nearestEvenCol - 2; - end - - % Determines the index of the even column of the original - % image that is closest to this abscissa (currentCol) of - % the new image - idx = mod(gridPointsCoordinatesX(currentCol), 2) < 1; - nearestOddCol = floor(gridPointsCoordinatesX(currentCol)); - nearestOddCol(idx) = nearestOddCol(idx)+1; - if (nearestOddCol > bayerPatternDimX) - nearestOddCol = nearestOddCol - 2; - end - - % Determines the index of the column (even or odd) of the - % original image that is closest to this abscissa - % (currentCol) of the new image - totalNearestCol = round(gridPointsCoordinatesX(currentCol)); - if (mod(totalNearestRow, 2) == 0 && mod(totalNearestCol, 2) ~= 0) - totalNearestCol = totalNearestCol + 1; - elseif (mod(totalNearestRow, 2) ~= 0 && mod(totalNearestCol, 2) == 0) - totalNearestCol = totalNearestCol - 1; + if ((mod(centerPointRow(currentRow), 2) == 0 && ... + mod(centerPointCol(currentCol), 2)) == 0 || ... + (mod(centerPointRow(currentRow), 2) ~= 0 && ... + mod(centerPointCol(currentCol), 2) ~= 0)) + % This point of the original image DOES contain + % information about the green colour + + % Calculates the vertical displacement of the two + % diagonal lines that cross this point + b1 = centerPointRow(currentRow) - ... + centerPointCol(currentCol); + b2 = centerPointRow(currentRow) + ... + centerPointCol(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 center + fixedCenterPointRow = centerPointRow(currentRow); + 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 + + if (fixedCenterPointRow < 1) + % Fix for the marginal first row case + fixedCenterPointRow = 1; + fixedCenterPointCol = fixedCenterPointCol - 1; + 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 - - % Closest neighbors per colour can be determined by - % observing the Bayer pattern - xc.red(currentRow, currentCol) = xb(nearestOddRow, nearestEvenCol); - xc.blue(currentRow, currentCol) = xb(nearestEvenRow, nearestOddCol); - xc.green(currentRow, currentCol) = xb(totalNearestRow, totalNearestCol); end end - elseif (strcmp(method, 'linear')) end % Combines colours to a single image array and shows the result @@ -92,3 +274,52 @@ function xc = bayer2rgb(xb, M, N, method) figure(); imshow(rgbImage); 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 + + + + + + + + + + + + + +