def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### filled, _ = copyutils.getWindow(filledImage, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) source = cv.cvtColor(inpaintedImage, cv.COLOR_BGR2GRAY) source, valid = copyutils.getWindow(source, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) # make points near the front to zero # to erase the invalid derivative filled = cv.erode(filled, np.ones((3, 3))) gX = cv.Scharr(source, cv.CV_32F, 1, 0) gY = cv.Scharr(source, cv.CV_32F, 0, 1) length = gX * gX + gY * gY length[filled == 0] = 0 # find the index of derivative with longest length x, y = np.unravel_index(np.argmax(length), length.shape) Dx = gX[x, y] Dy = gY[x, y] ######################################### return Dy, Dx
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code grey_img = cv.cvtColor(inpaintedImage, cv.COLOR_BGR2GRAY) inp_img, _ = copyutils.getWindow(grey_img, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) fill_img, _ = copyutils.getWindow(filledImage, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) for i in range(fill_img.shape[0]): for j in range(fill_img.shape[1]): if fill_img[i, j] == 0: inp_img[i, j] = 0 X = cv.Sobel(inp_img, cv.CV_64F, 1, 0) Y = cv.Sobel(inp_img, cv.CV_64F, 0, 1) XY = X * X + Y * Y index = np.unravel_index(np.argmax(XY), XY.shape) Dy = X[index[0], index[1]] Dx = Y[index[0], index[1]] ######################################### return Dy, Dx
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code front_img = copyutils.getWindow(fillFront, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) fill_img = copyutils.getWindow(filledImage, (psiHatP.row(), psiHatP.col()), psiHatP.radius())[0] / 255.00 valid_img = front_img * fill_img X = cv.Sobel(fill_img, cv.CV_64F, 1, 0) Y = cv.Sobel(fill_img, cv.CV_64F, 0, 1) XY = math.sqrt(X[psiHatP.radius(), psiHatP.radius()] * X[psiHatP.radius(), psiHatP.radius()] + Y[psiHatP.radius(), psiHatP.radius()] * Y[psiHatP.radius(), psiHatP.radius()]) Dy = X[psiHatP.radius(), psiHatP.radius()] Dx = Y[psiHatP.radius(), psiHatP.radius()] Ny = -(Dy / XY) Nx = (Dx / XY) ######################################### return Ny, Nx
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### filled, valid = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w, outofboundsvalue=False) conf, _ = copyutils.getWindow(confidenceImage, psiHatP._coords, psiHatP._w) filled_mask = filled / 255 C = np.sum(conf * filled_mask) / np.sum(valid) # print("conf:\n{}".format(conf)) # print("filled_mask:\n{}".format(filled_mask)) # print("sum(conf): {}".format(np.sum(conf))) # print("sum(conf*filled): {}".format(np.sum(conf*filled_mask))) # print("sum(valid): {}".format(np.sum(valid))) # print("C: {}".format(C)) ######################################### return C
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### pcord = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() fronti, frontb = copyutils.getWindow(fillFront, pcord, w) imagei, imageb = copyutils.getWindow(filledImage, pcord, w) xsize = imagei.shape[0] ysize = imagei.shape[1] for i in range(xsize): for j in range(ysize): if fronti[i, j] == 0: imagei[i, j] = 0 sobelx = cv.Sobel(imagei, cv.CV_64F, 1, 0, ksize=5) sobely = cv.Sobel(imagei, cv.CV_64F, 0, 1, ksize=5) i = np.sqrt(sobelx**2 + sobely**2) Nx = sobelx / i Ny = sobely / i ######################################### return Ny, Nx
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Sobel filter kernel size kw = 1 sobel_size = 2 * kw + 1 # Get target patch pixels inpainted, _ = copyutils.getWindow(inpaintedImage, psiHatP._coords, psiHatP._w) inpainted = cv.cvtColor(inpainted, cv.COLOR_BGR2GRAY) filled, _ = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) # Using Sobel/Scharr filter to calculate gradients at each pixel Gx = cv.Scharr(src=inpainted, ddepth=cv.CV_32F, dx=1, dy=0, borderType=cv.BORDER_REPLICATE) Gy = cv.Scharr(src=inpainted, ddepth=cv.CV_32F, dx=0, dy=1, borderType=cv.BORDER_REPLICATE) # Valid gradient should be calculated from all filled pixels erode_kernel = np.ones((sobel_size,sobel_size),np.uint8) filled_eroded = cv.erode(filled, erode_kernel, borderType=cv.BORDER_REPLICATE,iterations=1) Gx *= filled_eroded>0 Gy *= filled_eroded>0 # Find the maximum gradient in the target patch as the patch's gradient d = np.sqrt(Gx**2 + Gy**2) dmax = d == d.max() # Change coordinations to kivy's display coordination Dx = -Gy[dmax][0] Dy = Gx[dmax][0] ######################################### return Dy, Dx
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### pcord = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() grey_img = cv.cvtColor(inpaintedImage, cv.COLOR_BGR2GRAY) iinfo, ib = copyutils.getWindow(grey_img, pcord, w) finfo, fb = copyutils.getWindow(filledImage, pcord, w) xsize = finfo.shape[0] ysize = finfo.shape[1] for i in range(xsize): for j in range(ysize): if finfo[i, j] == 0: iinfo[i, j] = 0 sx = cv.Sobel(iinfo, cv.CV_64F, 1, 0) sy = cv.Sobel(iinfo, cv.CV_64F, 0, 1) graph = sx ** 2 + sy ** 2 cord = np.unravel_index(np.argmax(graph), graph.shape) x, y = cord[0], cord[1] Dx = sx[x,y] Dy = sy[x,y] ######################################### return Dy, Dx
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Create a mask of valid `q`s' # - Previously filled # - Valid, i.e. inside boundary # - Filled conv with np.ones((3,3)) is exactly 255*3*3 # indicates gradient values that is not corrupted by unfilled pixels # assuming gradient estimated with a 3x3 kernel pix, valid = copyutils.getWindow(inpaintedImage, psiHatP._coords, psiHatP._w) filled, _ = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w, outofboundsvalue=False) gray = cv.cvtColor(pix, cv.COLOR_BGR2GRAY) filled_padded = cv.copyMakeBorder(filled, 1, 1, 1, 1, cv.BORDER_CONSTANT, value=0) uncorrupted = cv.filter2D(filled_padded, cv.CV_16S, np.ones((3, 3))) valid_q = np.logical_and(np.logical_and(valid, filled), uncorrupted[1:-1, 1:-1] == 255 * 3 * 3) grad_x = cv.Scharr(gray, cv.CV_32F, 1, 0) * valid_q grad_y = cv.Scharr(gray, cv.CV_32F, 0, 1) * valid_q grad_l2 = grad_x * grad_x + grad_y * grad_y q = np.unravel_index(np.argmax(grad_l2), grad_l2.shape) Dx = grad_x[q] Dy = grad_y[q] # print("gray:\n{}".format(gray)) # print("valid:\n{}".format(valid)) # print("filled:\n{}".format(filled)) # print("uncorrupted:\n{}".format(uncorrupted[1:-1,1:-1])) # print("q mask:\n{}".format(valid_q)) # print("gradx masked:\n{}".format(grad_x)) # print("grad_magnitude:\n{}".format(grad_l2)) # print("q; Dx,Dy: {} ; {}".format(q, (Dx,Dy))) ######################################### return Dy, Dx
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### cwindow, _ = copyutils.getWindow(confidenceImage, psiHatP._coords, psiHatP._w) filled, valid = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) psiPArea = valid.sum() C = cwindow[filled>0].sum() / psiPArea ######################################### return C
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### fill, _ = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) # simply use a 3x3 sobel kernel over `p` # can use gradient as substitute for normal # since computing # | gradI \cdot n_p| = | norm(gradI) norm(n_p) cos(theta) | # same regardless or orientation of `n_p` by |cos(theta)| = |-cos(theta + \pi)| grad_x = cv.Sobel(fill, cv.CV_32F, 1, 0, ksize=5) grad_y = cv.Sobel(fill, cv.CV_32F, 0, 1, ksize=5) Nx = grad_x[psiHatP._w, psiHatP._w] Ny = grad_y[psiHatP._w, psiHatP._w] Nx, Ny = normalize2d([Nx, Ny]) # print("Nx,Ny,norm: {}".format((Nx,Ny,N_norm))) ######################################### return Ny, Nx
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code ######################################### w = psiHatP.radius() row = psiHatP.row() col = psiHatP.col() fill = copyutils.getWindow(fillFront, (row, col), w)[0] x = cv.Sobel(fill, cv.CV_64F, 1, 0, ksize=5) y = cv.Sobel(fill, cv.CV_64F, 0, 1, ksize=5) Nx = -y[w][w] Ny = x[w][w] if (Nx != 0 and Ny != 0): length = (Ny**2 + Nx**2)**0.5 Ny = Ny / length Nx = Nx / length return Ny, Nx else: return None, None
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### sizeof_patch = (2 * psiHatP.radius() + 1)**2 confidenceImage_patch, _ = copyutils.getWindow(confidenceImage, psiHatP._coords, psiHatP.radius()) filled_patch = psiHatP.filled() unfilled_confidence_area = np.multiply(confidenceImage_patch.astype(float), filled_patch / 255) # Replace this dummy value with your own code C = np.sum(unfilled_confidence_area) / sizeof_patch / 255 ######################################### return C
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### pcord = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() confi, confb = copyutils.getWindow(confidenceImage, pcord, w) filli, fillb = copyutils.getWindow(filledImage, pcord, w) C = np.sum(confi[filli > 0]) / np.sum(fillb) ######################################### return C
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### kw = 1 size = 2 * kw + 1 # Get target patch's pixels in fill front image front, _ = copyutils.getWindow(fillFront, psiHatP._coords, kw) # Center pixel's gradient Gx = cv.Scharr(src=front, ddepth=cv.CV_32F, dx=1, dy=0, borderType=cv.BORDER_REPLICATE)[kw][kw] Gy = cv.Scharr(src=front, ddepth=cv.CV_32F, dx=0, dy=1, borderType=cv.BORDER_REPLICATE)[kw][kw] # Change to unit vector d = np.sqrt(Gy**2 + Gx**2) if d != 0: Gx /= d Gy /= d # Change coordinations to kivy's display coordination Ny = Gy Nx = Gx ######################################### return Ny, Nx
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code kernel_size = 3 inpainted, _ = copyutils.getWindow(inpaintedImage, psiHatP._coords, psiHatP._w) # Change patch from color to gray scale inpainted = cv.cvtColor(inpainted, cv.COLOR_BGR2GRAY) filled, _ = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) # Try to erode the filled patch used cv.erode() with 3x3 kernel kernel = np.ones((kernel_size, kernel_size), np.uint8) erosion = cv.erode(filled, kernel, iterations=1, borderType=cv.BORDER_REPLICATE) # Compute gradient along x axis gx = cv.Scharr(src=inpainted, ddepth=cv.CV_32F, dx=1, dy=0, borderType=cv.BORDER_REPLICATE) # Compute gradient along y axis gy = cv.Scharr(src=inpainted, ddepth=cv.CV_32F, dx=0, dy=1, borderType=cv.BORDER_REPLICATE) # Filter out pixels that are unfilled gx *= erosion > 0 gy *= erosion > 0 # Compute the magnitude of gradient of every pixel gradient = np.sqrt(gx * gx + gy * gy) # Find the x and y coordinates of the maximum gradient magnitude from gradient matrix x, y = np.unravel_index(gradient.argmax(), gradient.shape) Dx = -gy[x][y] Dy = gx[x][y] ######################################### return Dy, Dx
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None row = psiHatP.row() col = psiHatP.col() radius = psiHatP.radius() conf = copyutils.getWindow(confidenceImage, (row, col), radius) filled = np.asarray( copyutils.getWindow(confidenceImage, (row, col), radius)) / 255 mask = conf * filled c = np.sum(mask) / ((2 * radius + 1)**2) return c
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### cwindow, _ = copyutils.getWindow(confidenceImage, psiHatP._coords, psiHatP._w) filled, valid = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) psiPArea = valid.sum() C = cwindow[filled > 0].sum() / psiPArea ######################################### return C
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code # Ny = 0 # Nx = 1 # get coords and w of the patch in source image coords = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() # get masks in patch size patchFilled = copyutils.getWindow(filledImage, coords, w)[0] patchFront = copyutils.getWindow(fillFront, coords, w)[0] # if the fill front consists of exactly one pixel, the fill front is degenerate # and has no well-defined normal if np.count_nonzero(patchFront) == 1: Nx = None Ny = None return Ny, Nx # compute gradients at patch center, still ksize=5 works better centerGX = cv.Sobel(patchFilled, cv.CV_64F, 1, 0, ksize=5)[w, w] centerGY = cv.Sobel(patchFilled, cv.CV_64F, 0, 1, ksize=5)[w, w] # compute magnitude for tangent at patch center magnitude = np.sqrt(np.add(centerGX**2, centerGY**2)) # set Ny and Nx Nx = -centerGX Ny = centerGY if magnitude != 0: Nx = Nx / float(magnitude) Ny = Ny / float(magnitude) ######################################### return Ny, Nx
def filled(self): if self._fld is not None: # if a window extends beyond image limits, the fill value for the # out-of-bounds pixels is set to zero (ie. those patch pixels are not "filled") fill, _ = copyutils.getWindow(self._fld, self._coords, self._w, outofboundsvalue=False) else: fill = np.fill((2*w+1,2*w+1),True,dtype=np.uint8) return fill
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Sobel filter kernel size kw = 1 sobel_size = 2 * kw + 1 # Get target patch pixels inpainted, _ = copyutils.getWindow(inpaintedImage, psiHatP._coords, psiHatP._w) inpainted = cv.cvtColor(inpainted, cv.COLOR_BGR2GRAY) filled, _ = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) # Using Sobel/Scharr filter to calculate gradients at each pixel Gx = cv.Scharr(src=inpainted, ddepth=cv.CV_32F, dx=1, dy=0, borderType=cv.BORDER_REPLICATE) Gy = cv.Scharr(src=inpainted, ddepth=cv.CV_32F, dx=0, dy=1, borderType=cv.BORDER_REPLICATE) # Valid gradient should be calculated from all filled pixels erode_kernel = np.ones((sobel_size, sobel_size), np.uint8) filled_eroded = cv.erode(filled, erode_kernel, borderType=cv.BORDER_REPLICATE, iterations=1) Gx *= filled_eroded > 0 Gy *= filled_eroded > 0 # Find the maximum gradient in the target patch as the patch's gradient d = np.sqrt(Gx**2 + Gy**2) dmax = d == d.max() # Change coordinations to kivy's display coordination Dx = -Gy[dmax][0] Dy = Gx[dmax][0] ######################################### return Dy, Dx
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace this dummy value with your own code con_val = copyutils.getWindow(confidenceImage, (psiHatP.row(), psiHatP.col()), psiHatP.radius())[0] valid_val = copyutils.getWindow(confidenceImage, (psiHatP.row(), psiHatP.col()), psiHatP.radius())[1] ######################################### return round(1.0 * np.sum(con_val) / np.sum(valid_val))
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None indicator_image = filledImage / 255 indicator_window, indicator_filled = copyutils.getWindow( indicator_image, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) gray_image = cv.cvtColor(inpaintedImage, cv.COLOR_BGR2GRAY) patch, valid = copyutils.getWindow(gray_image, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) sobel_x = cv.Sobel(patch, cv.CV_64F, 1, 0, ksize=5) sobel_y = cv.Sobel(patch, cv.CV_64F, 0, 1, ksize=5) sobel_x_valid = sobel_x * indicator_window sobel_y_valid = sobel_y * indicator_window odd_rows = indicator_window[0:9] even_rows = indicator_window[2:] correct = np.dot(odd_rows, even_rows.T) correct = np.array([0] + [correct[i][i] for i in range(9)] + [0]) sobel_x_valid *= np.uint8(correct == 11)[:, np.newaxis] odd_col = indicator_window[:][0:9] even_col = indicator_window[:][2:] correct = np.dot(odd_col.T, even_col) correct = np.array([0] + [correct[i][i] for i in range(9)] + [0]) sobel_y_valid *= np.uint8(correct == 11)[:, np.newaxis] magnitude = np.sqrt(sobel_x_valid**2 + sobel_y_valid**2) index_1, index_2 = np.unravel_index(magnitude.argmax(), magnitude.shape) Dy = sobel_y_valid[index_1][index_2] Dx = sobel_x_valid[index_1][index_2] return Dy, Dx
def pixels(self, returnValid=None): if self._img is not None: # if the window extends beyond the image limits, we need # to store a bitmap that indicates which pixels in the # patch are actually valid pix, valid = copyutils.getWindow(self._img, self._coords, self._w) else: pix = None if len(pix.shape) == 2: pix = pix[:,:,None] if returnValid is None: return pix else: return pix, valid
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### conf, valid = copyutils.getWindow(confidenceImage, psiHatP._coords, psiHatP._w) C = round(1.0 * np.sum(conf) / np.sum(valid)) ######################################### return C
def pixels(self, returnValid=None): if self._img is not None: # if the window extends beyond the image limits, we need # to store a bitmap that indicates which pixels in the # patch are actually valid pix, valid = copyutils.getWindow(self._img, self._coords, self._w) else: pix = None if len(pix.shape) == 2: pix = pix[:, :, None] if returnValid is None: return pix else: return pix, valid
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### Nx, Ny = None, None x = psiHatP.radius() front, valid = copyutils.getWindow(fillFront, (psiHatP.row(), psiHatP.col()), x) neighbor = [[-1, -1], [-1, 0], [-1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1]] success = False # check if center point has no neighbor for i, j in neighbor: if front[x + i, x + j] != 0: success = True break if success: filled, _ = copyutils.getWindow(filledImage, (psiHatP.row(), psiHatP.col()), x, 255) # normal is also the gradient of unfilled image gX = cv.Scharr(filled, cv.CV_32F, 1, 0) gY = cv.Scharr(filled, cv.CV_32F, 0, 1) Nx = -gX[x, x] Ny = -gY[x, x] norm = np.sqrt(Nx * Nx + Ny * Ny) # undefined when norm = 0 if norm == 0: return None, None Nx /= norm Ny /= norm ######################################### return Ny, Nx
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace this dummy value with your own code # Get the numpy array of size (2w + 1)x(2w + 1) from confidenceImage. confidence, _ = copyutils.getWindow(confidenceImage, psiHatP._coords, psiHatP._w) # Get the numpy array of size (2w + 1)x(2w + 1) from the filledImage to see which # pixel has been filled. filled, valid = copyutils.getWindow(filledImage, psiHatP._coords, psiHatP._w) # Get the total number of pixels which are valid (inbound) total = np.sum(valid) # Sum up for the total confidence value from those pixels which are filled, then # divided by the total number of inbound pixels to get the mean confidence value. C = np.sum(confidence[filled != 0]) / total ######################################### return C
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace this dummy value with your own code # C = 1 # get coords and w coords = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() # get the filled value and its mask that shows filled and unfilled pixels # inside the patch patchFilled, patchInImage = copyutils.getWindow(filledImage, coords, w) patchFilled = patchFilled / float(255) # get the confidence values for each pixel inside the patch patchConf = copyutils.getWindow(confidenceImage, coords, w)[0] # compute numerator -- the sum of the filled pixels' confidence value num = np.sum(patchFilled * patchConf * patchInImage) # compute denominator -- the area of the patch inside the image boundary den = np.count_nonzero(patchInImage) # compute C C = np.divide(num, den) ######################################### return C
def computeC(psiHatP=None, filledImage=None, confidenceImage=None): assert confidenceImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace this dummy value with your own code w = psiHatP.radius() row = psiHatP.row() col = psiHatP.col() C = 0 conf = copyutils.getWindow(confidenceImage, (row, col), w) C = np.sum(conf) ######################################### return C / ((2 * w + 1) * (2 * w + 1))
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### Nx, Ny = None, None pcord = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() imagei, imageb = copyutils.getWindow(filledImage, pcord, w) sx = cv.Sobel(imagei, cv.CV_64F, 1, 0) sy = cv.Sobel(imagei, cv.CV_64F, 0, 1) x, y = sx[w, w], sy[w, w] i = np.sqrt(x ** 2 + y ** 2) if i != 0: Nx = x / i Ny = -y / i ######################################### return Ny, Nx
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code # Get target numpy array of size (2w + 1)x(2w + 1) from fillFront image target, _ = copyutils.getWindow(fillFront, psiHatP._coords, psiHatP._w) # Use 2D gaussian kernel to smooth and filter target patch of fillFront gaussian_filter = sc.filters.gaussian_filter(target, 1) if target.size == 1: # The case that when there is only one pixel in target patch Nx = None Ny = None else: # Compute the gradient of the patch, get the center gradient of the patch nx = cv.Scharr(src=gaussian_filter, ddepth=cv.CV_32F, dx=1, dy=0, borderType=cv.BORDER_REPLICATE)[psiHatP._w][psiHatP._w] ny = cv.Scharr(src=gaussian_filter, ddepth=cv.CV_32F, dx=0, dy=1, borderType=cv.BORDER_REPLICATE)[psiHatP._w][psiHatP._w] # Change to unit vector d = np.sqrt(ny * ny + nx * nx) if d != 0: nx /= d ny /= d Ny = ny Nx = nx ######################################### return Ny, Nx
def computeNormal(psiHatP=None, filledImage=None, fillFront=None): assert filledImage is not None assert fillFront is not None assert psiHatP is not None fronts = np.sum(fillFront) if fronts == 255: Ny = None Nx = None return Ny, Nx front_window, front_fill = copyutils.getWindow( fillFront, (psiHatP.row(), psiHatP.col()), psiHatP.radius()) front_window = front_window / 255 for i in range(front_window.shape[0]): for j in range(front_window.shape[1]): if front_window[i][j] == 1: front_window[i - 1][j] = 1 front_window[i][j] = 0 g_image = cv.cvtColor(psiHatP.pixels(), cv.COLOR_BGR2GRAY) front = front_window * g_image nonzero_x, nonzero_y = np.nonzero(front) if nonzero_y.shape[0] > 1: distance = np.sqrt( np.multiply(nonzero_x - psiHatP.radius() / 2, nonzero_x - psiHatP.radius() / 2) + np.multiply(nonzero_y - psiHatP.radius() / 2, nonzero_y - psiHatP.radius() / 2)) nearest = distance[distance.argmin()] nearest_index = np.unravel_index(distance.argmin(), distance.shape) nearest_x, nearest_y = nonzero_x[nearest_index], nonzero_y[ nearest_index] remainder_x = np.delete(nonzero_x, distance.argmin()) remainder_y = np.delete(nonzero_y, distance.argmin()) remainder = np.sqrt( np.multiply(remainder_x - psiHatP.radius() / 2, remainder_x - psiHatP.radius() / 2) + np.multiply(remainder_y - psiHatP.radius() / 2, remainder_y - psiHatP.radius() / 2)) second_nearest = remainder[remainder.argmin()] second_index = np.unravel_index(remainder.argmin(), remainder.shape) second_x, second_y = remainder_x[second_index], remainder_y[ second_index] if nearest_x != second_x: slope_horizontal = (second_nearest - nearest) / (second_x - nearest_x) if nearest_x < second_x else \ (nearest - second_nearest) / (second_x - nearest_x) else: slope_horizontal = 0 if nearest_y != second_y: slope_vertical = (second_nearest - nearest) / (second_y - nearest_y) if nearest_y < second_y else \ (nearest - second_nearest) / (second_y - nearest_y) else: slope_vertical = 0 magnitude = (slope_vertical**2 + slope_horizontal**2)**0.5 if magnitude == 0: Nx = Ny = 0 else: Nx = -slope_vertical / magnitude Ny = slope_horizontal / magnitude else: Nx = Ny = 0 return Ny, Nx
def computeGradient(psiHatP=None, inpaintedImage=None, filledImage=None): assert inpaintedImage is not None assert filledImage is not None assert psiHatP is not None ######################################### ## PLACE YOUR CODE BETWEEN THESE LINES ## ######################################### # Replace these dummy values with your own code # Dy = 1 # Dx = 0 # get coords and w coords = (psiHatP.row(), psiHatP.col()) w = psiHatP.radius() # # this way is very slow # imgGray = cv.cvtColor(inpaintedImage, cv.COLOR_BGR2GRAY) # validGray = imgGray * ( filledImage / 255 ) # patchGray = copyutils.getWindow(validGray, coords, w)[0] # # compute gradients use sobel (scharr) # gradientsX = cv.Sobel(patchGray, cv.CV_64F, 1, 0, ksize=-1) # gradientsY = cv.Sobel(patchGray, cv.CV_64F, 0, 1, ksize=-1) # extract a larger patch in order to ensure the accuracy for the # border parts of the original size patch imgPatch = copyutils.getWindow(inpaintedImage, coords, w + 2)[0] patchGray = cv.cvtColor(imgPatch, cv.COLOR_BGR2GRAY) # compute gradients, ksize=5 produces better results than ksize=3 and ksize=7 does # therefore, use ksize=5 row = 2 column = patchGray.shape[1] - 2 gradientsX = cv.Sobel(patchGray, cv.CV_64F, 1, 0, ksize=5)[row:column, row:column] gradientsY = cv.Sobel(patchGray, cv.CV_64F, 0, 1, ksize=5)[row:column, row:column] # get mask for filled and inside image boundary pixel patchFilled, patchInImage = copyutils.getWindow(filledImage, coords, w) patchFilled = patchFilled / float(255) validMask = np.multiply(patchFilled, patchInImage) # apply validMask to x and y gradients validGX = np.multiply(gradientsX, validMask) validGY = np.multiply(gradientsY, validMask) # compute squared magnitude of gradient for each pixel (inside image) in patch magnitudes = np.add(validGX**2, validGY**2) # find the coordinates of the maxial elements ind = np.unravel_index(np.argmax(magnitudes, axis=None), magnitudes.shape) # set Dy and Dx Dx = validGX[ind] Dy = validGY[ind] ######################################### return Dy, Dx