def forward(self, X): # X.shape=(N,C,H,W) col_weights = self.weights.tensor.transpose(1, 2, 3, 0).reshape( (-1, self.out_channels)) self.col_image = im2col(X, self.kernel_size, self.stride) conv_ret = self.col_image @ col_weights + self.bias.tensor conv_ret = conv_ret.reshape( (X.shape[0], self.out_channels, (X.shape[2] - self.kernel_size) // self.stride + 1, (X.shape[3] - self.kernel_size) // self.stride + 1)) def backward(D): self.weights.gradient += (self.col_image.T @ D.transpose( 3, 1, 2, 0).reshape(-1, self.out_channels)).reshape( self.weights.tensor.shape) self.bias.gradient += D.transpose(3, 1, 2, 0).reshape( -1, self.out_channels).sum(axis=0) pad_D = np.pad(D, ((0, 0), (0, 0), (self.kernel_size - 1, self.kernel_size - 1), (self.kernel_size - 1, self.kernel_size - 1)), 'constant', constant_values=0) flip_W = self.weights.tensor[::-1] flip_W = flip_W.swapaxes(1, 2) col_flip_W = flip_W.reshape((-1, self.in_channels)) col_pad_D = im2col(pad_D, self.kernel_size, self.stride) dX = col_pad_D @ col_flip_W dX = dX.reshape(X.shape) return dX return conv_ret, backward
def NLM_affinity(y, sample_indices): start = time.time() M, N = y.shape[:2] h = 3. ksz = 7 kRad = int((ksz - 1) / 2) img = np.pad(y, (kRad, kRad), 'symmetric') G = matlab_style_gauss2D((ksz, ksz), 1.2) G = G.reshape(ksz**2, 1) G = G / np.sum(G) Z = im2col(img.T, [ksz, ksz]) Z = Z * np.repeat(G, M * N).reshape(ksz**2, M * N) AB = np.empty((len(sample_indices), M * N), dtype=np.float64) for i, idx in enumerate(sample_indices): ind_x, ind_y = num2xy(idx, M, N) loc_p = [ind_x + kRad, ind_y + kRad] yp = img[loc_p[0] - kRad:loc_p[0] + kRad + 1, loc_p[1] - kRad:loc_p[1] + kRad + 1] Zc = yp.T.reshape(ksz**2) * G.reshape(ksz**2) Zc = np.repeat(Zc, M * N).reshape(ksz**2, M * N) Ker = np.exp(-np.sum((Zc - Z)**2, axis=0) / h**2) AB[i, :] = Ker logger.info('Affinity function NLM done in {0}s'.format(time.time() - start)) return AB
def forward(self, V): self.in_act = V ## We shall use the technique of im2Col as detailed in the notes for the course ## CS231n. However, there are still speed-ups to be had if we could link ## numpy with the BLAS Library A = Vol(self.out_sx, self.out_sy, self.out_depth, 0.0) input_vol = V.w input_vol = input_vol.reshape(V.depth, V.sx, V.sy) inputim2col = im2col(input_vol, [self.filter_sx, self.filter_sy], self.stride) ##Create the filter matrix filtercol = np.zeros((self.out_depth,self.filter_sx*self.filter_sy*self.in_depth)) for i in xrange(self.out_depth): filtercol[i] = self.filters[i].w.flatten() ##Perform the convolution step convolve = np.dot(filtercol, inputim2col) ##Adding biases ##Could be done in a neater fashion for i in xrange(self.out_depth): convolve[i] += self.biases.w[i] A.w = convolve.flatten() self.out_act = A return self.out_act
def forward(self, X): # pad X so that X.shape = (batch_size, input_depth, input_height, input_width) X = np.pad(X, ((0,0), (0,0), (self.pad1,self.pad2), (self.pad1,self.pad2)), \ mode='constant') assert X.shape == self.input_shape # W_blocks.shape = (output_depth, filter_size**2 * input_depth) # X_blocks.shape = (filter_size**2 * input_depth, # output_height * output_width * batch_size) # outputs.shape = (output_depth, output_height * out_width * batch_size) W_blocks = np.reshape(self.W, (self.output_depth, -1)) X_blocks = im2col(X, self.filter_size, self.filter_size, \ 0, self.stride) outputs = np.dot(W_blocks, X_blocks) + self.b outputs = np.reshape(outputs, (self.output_depth, self.output_height, \ self.output_width, self.batch_size)) outputs = outputs.transpose(3, 0, 1, 2) self.X_blocks = X_blocks print('X.shape=', X.shape, 'FILTER SIZE=', self.filter_size) print('H2=', self.output_height, 'W2=', self.output_width) print('STRIDE=', self.stride, 'total+pad=', self.total_pad) print('W_Blocks.shape=', W_blocks.shape) print('X_blocks.shape=', X_blocks.shape) print('outputs shape=', outputs.shape) return outputs
def forward(self, feature_map): # feature_map : R(batch_size,in_channels,in_width,in_height) batch_size, in_channels, height, width = feature_map.shape self.in_c = in_channels self.in_h = height self.in_w = width if self.padding > 0: padding_h = height + 2 * self.padding padding_w = width + 2 * self.padding padding_feat = torch.zeros( (batch_size, in_channels, padding_h, padding_w), dtype=feature_map.dtype) padding_feat[:, :, self.padding:self.padding + height, self.padding:self.padding + width] = feature_map feature_map = padding_feat h_steps = (height - self.kernel_size + 2 * self.padding) // self.stride + 1 v_steps = (width - self.kernel_size + 2 * self.padding) // self.stride + 1 self.feat_mat = im2col(feature_map, self.kernel_size, h_steps, v_steps, self.in_channels, self.stride) self.kernel_mat = kernel2row(self.kernel) outmap = torch.matmul(self.kernel_mat, self.feat_mat) outmap = outmap.view( (self.out_channels, batch_size, h_steps, v_steps)).permute( (1, 0, 2, 3)) return outmap
def max_pool_forward_im2col(x, pool_param): """ An implementation of the forward pass for max pooling based on im2col. This isn't much faster than the naive version, so it should be avoided if possible. """ N, C, H, W = x.shape pool_height, pool_width = pool_param['pool_height'], pool_param[ 'pool_width'] stride = pool_param['pool_stride'] assert (H - pool_height) % stride == 0, 'Invalid height' assert (W - pool_width) % stride == 0, 'Invalid width' out_height = (H - pool_height) / stride + 1 out_width = (W - pool_width) / stride + 1 x_split = x.reshape(N * C, 1, H, W) x_cols = im2col(x_split, pool_height, pool_width, padding=0, stride=stride) x_cols_argmax = np.argmax(x_cols, axis=0) x_cols_max = x_cols[x_cols_argmax, np.arange(x_cols.shape[1])] out = x_cols_max.reshape(out_height, out_width, N, C).transpose(2, 3, 0, 1) cache = (x, x_cols, x_cols_argmax, pool_param) return out, cache
def calc_gradient(self, error): self.error = error error_col = self.error.reshape(self.batch_size, self.out_channels, -1) # print('self.col_images.shape:', self.col_images.shape) # print('error_col.shape:', error_col.shape) # print('error.shape:', error.shape) for batch_i in range(self.batch_size): self.weight_gradient += np.dot(error_col[batch_i], self.col_images[batch_i]).reshape( self.weight.shape) # 将对应的维度相加,需要将N和最后求和 self.bias_gradient += np.sum(error_col, axis=(0, 2)).reshape(self.bias.shape) # 反向传播计算上一层error error_pad = np.pad(self.error, ((0, 0), (0, 0), (self.kernel_size - 1, self.kernel_size - 1), (self.kernel_size - 1, self.kernel_size - 1)), 'constant', constant_values=0) # print('error_pad.shape:', error_pad.shape) # print('error:', error) # print('error_pad:', error_pad) weight_flip = self.weight[:, :, ::-1, ::-1] weight_flip = np.swapaxes(weight_flip, 0, 1) weight_flip_col = weight_flip.reshape(self.in_channels, -1) # print('weight_flip_col.shape:', weight_flip_col.shape) next_error = np.zeros( (self.batch_size, self.in_channels, self.input_h, self.input_w)) for batch_i in range(self.batch_size): # 输入的第i个图像C_in*H_in*W_in error_pad_image_batch_i = error_pad[batch_i, :] error_pad_image_batch_i_col = im2col(error_pad_image_batch_i, self.kernel_size, self.stride) # print('error_pad_image_batch_i_col.shape:', error_pad_image_batch_i_col.shape) next_error[batch_i] = np.reshape( np.dot(weight_flip_col, np.transpose(error_pad_image_batch_i_col)), (self.in_channels, self.input_h, self.input_w)) # print('error_pad_image_col.shape:', error_pad_image_col.shape) # print('error_pad_image_col.shape:', error_pad_image_col.shape) # next_error = np.dot(error_pad_image_col, np.transpose(weight_flip_col)).reshape(self.batch_size, self.in_channels, self.input_h, self.input_w) # print('next_error.shape:', next_error.shape) # # conv_out[batch_i] = np.reshape(np.dot(weight_col, np.transpose(image_batch_i_col)) + self.bias, # (self.out_channels, self.out_h, self.out_w)) return next_error
def forward(self, x): self._ims = [] self._cols = [] new_rows = [] for row in x: im = row.reshape((1,self.im_rect[0],self.im_rect[1])) col = utils.im2col(im, self.pool_rect, self.pool_stride) new_row = utils.max_pool(col) new_rows.append(new_row) self._ims.append(im) self._cols.append(col) return np.array(new_rows)
def forward(self, inputs): assert (inputs.shape == (self.inputs_depth, self.inputs_height, self.inputs_width)) self.X_col = im2col(inputs, self.X_col_indices) W_row = self.weights.reshape( (self.outputs_depth, self.k * self.k * self.inputs_depth)) res = np.dot(W_row, self.X_col.T) + self.biases self.outputs = res.reshape( (self.outputs_depth, self.outputs_height, self.outputs_width)) return self.outputs
def forward(self, x): self._ims = [] self._cols = [] new_rows = [] for row in x: im = row.reshape((1, self.im_rect[0], self.im_rect[1])) col = utils.im2col(im, self.pool_rect, self.pool_stride) new_row = utils.max_pool(col) new_rows.append(new_row) self._ims.append(im) self._cols.append(col) return np.array(new_rows)
def denoise(self, noise_im) -> torch.Tensor: """ input: noise_im: [b, c, h, w] clean_im: [b, c, h, w] return: restored_im: [b, c, h, w] """ # half quadratic split restored_im = noise_im.clone() for beta in self.betas: for t in range(self.num_iters): restored_imcol = im2col( restored_im, 8, 8, self.stride ) # matlab style im2col, output shape = [batch, c, patch_size**2, num_patches], # GMM prior p_y_z, mean_noise_imcol, GMM_noisy_covs = self.prior( noise_imcol=restored_imcol, noise_sd=beta**(-0.5)) # weiner filtering: update z in Equa. 5 max_index = torch.argmax(p_y_z, dim=1) Xhat = torch.zeros_like(restored_imcol) for b in range(Xhat.shape[0]): for i in range(self.GMM["nmodels"]): index = torch.nonzero((max_index[b] - i) == 0, as_tuple=False)[:, 0] B = torch.matmul(self.GMM["covs"][i], restored_imcol[b, :, :, index]) solution = torch.matmul(GMM_noisy_covs[i].inverse(), B) Xhat[b, :, :, index] = solution Xhat += mean_noise_imcol restored_imcol = Xhat I1 = torch.zeros_like(restored_im) for b in range(I1.shape[0]): I1[b] = avg_col2im(restored_imcol[b], noise_im.shape[2], noise_im.shape[3], self.stride) # update Xhat in Equa. 4 restored_im = noise_im * self.lamb / ( self.lamb + beta * 8**2) + (beta * 8**2 / (self.lamb + beta * 8**2)) * I1 psnr1 = 10 * torch.log10(1 / torch.mean( (restored_im - self.clean_im)**2)) print(f"[beta={beta:.3f}, iter={t}] PSNR={psnr1.item():.3f}") torch.clamp_(restored_im, min=0, max=1) return restored_im
def forward(self, x): N, C, H, W = x.shape self.img_shape = x.shape im_col = im2col(x, self.pool_h, self.pool_w, self.stride, self.padding) im_col = im_col.reshape(-1, self.pool_h*self.pool_w) self.argmax = im_col.argmax(axis=1) out = im_col.max(axis=1) out_h, out_w = get_conv_result_shape( H, W, self.pool_h, self.pool_w, self.stride, self.padding) out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) self.out_shape = out.shape return out
def __convolution(self, inputs, stride=1, padding=0): """ Description: Convolution layer """ new_size = (np.shape(inputs)[1] - self.kernel_size + 2 * padding) / stride + 1 tile_col = im2col(inputs, self.kernel_size, stride, padding) kernel_col = np.reshape(self.kernel_count, -1) result = np.dot(tile_col, kernel_col) return np.reshape(self.kernel_count, new_size, new_size)
def forward(self, x): """ :param x: (N, C_in, H_in, W_in) 通道*高度*宽度 :return: """ self.input_map = x if not self.init_params: self.init_params = True weights_scale = math.sqrt( reduce(lambda x, y: x * y, self.input_map.shape) / self.out_channels) self.weight = np.random.standard_normal( size=(self.in_channels, self.out_channels, self.kernel_size, self.kernel_size)) / weights_scale self.bias = np.random.standard_normal(size=(self.out_channels, 1)) / weights_scale self.batch_size, _, self.input_h, self.input_w = x.shape self.out_h = (self.input_h - self.kernel_size) / self.stride + 1 self.out_w = (self.input_w - self.kernel_size) / self.stride + 1 # print('out_h:', self.out_h) # print('out_w:', self.out_w) # 图像转换为矩阵,N*(H*W)*(C*K*K) self.col_images = [] weight_col = self.weight.reshape(self.out_channels, -1) # N * C_out * H_out * W_out conv_out = np.zeros( (self.batch_size, self.out_channels, self.out_h, self.out_w)) for batch_i in range(self.batch_size): # 输入的第i个图像C_in*H_in*W_in image_batch_i = x[batch_i, :] image_batch_i_col = im2col(image_batch_i, self.kernel_size, self.stride) self.col_images.append(image_batch_i_col) # print(image_batch_i_col.shape) # print(weight_col.shape) conv_out[batch_i] = np.reshape( np.dot(weight_col, np.transpose(image_batch_i_col)) + self.bias, (self.out_channels, self.out_h, self.out_w)) self.col_images = np.array(self.col_images) return conv_out
def forward(self, x): N, C, H, W = x.shape out_h = int(1 + (H - self.pool_h) / self.stride) out_w = int(1 + (W - self.pool_w) / self.stride) col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) col = col.reshape(-1, self.pool_h*self.pool_w) arg_max = np.argmax(col, axis=1) out = np.max(col, axis=1) out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2) self.x = x self.arg_max = arg_max return out
def forward(self, x): FN, C, FH, FW = self.W.shape N, C, H, W = x.shape out_h = int(1 + (H + 2 * self.pad - FH) / self.stride) out_w = int(1 + (W + 2 * self.pad - FW) / self.stride) col = im2col(x, FH, FW, self.stride, self.pad) col_W = self.W.reshape(FN, -1).T # 滤波器的展开 out = np.dot(col, col_W) + self.b out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) self.x = x self.col = col self.col_W = col_W return out
def forward(self, x): FN, C, FH, FW = self.par['w'].shape N, C, H, W = x.shape out_h = 1 + int((H + 2*self.pading - FH) / self.strid) out_w = 1 + int((W + 2*self.pading - FW) / self.strid) col = im2col(x, FH, FW, self.strid, self.pading) col_W = self.par['w'].reshape(FN, -1).T out = np.dot(col, col_W) + self.par['b'] out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) self.x = x self.col = col self.col_W = col_W return out
def backward(D): self.weights.gradient += (self.col_image.T @ D.transpose( 3, 1, 2, 0).reshape(-1, self.out_channels)).reshape( self.weights.tensor.shape) self.bias.gradient += D.transpose(3, 1, 2, 0).reshape( -1, self.out_channels).sum(axis=0) pad_D = np.pad(D, ((0, 0), (0, 0), (self.kernel_size - 1, self.kernel_size - 1), (self.kernel_size - 1, self.kernel_size - 1)), 'constant', constant_values=0) flip_W = self.weights.tensor[::-1] flip_W = flip_W.swapaxes(1, 2) col_flip_W = flip_W.reshape((-1, self.in_channels)) col_pad_D = im2col(pad_D, self.kernel_size, self.stride) dX = col_pad_D @ col_flip_W dX = dX.reshape(X.shape) return dX
def __avg_pool(self, inputs, size, stride, padding): """ (Copy & paste of the max pool code with np.mean instead of np.argmax) Description: Average pool layer Parameters: inputs -> The input of size [batch_size] x [filter] x [shape_x] x [shape_y] size -> The size of the tiling stride -> The applied translation at each step padding -> The padding (padding with 0 so the last column isn't left out) """ inp_sp = np.shape(inputs) tile_col = im2col(reshaped, size, stride=stride, padding=padding) max_ids = np.mean(tile_col, axis=0) result = tile_col[max_ids, range(max_ids.size)] new_size = (inp_sp[2] - size + 2 * padding) / stride + 1 result = np.reshape(result, (new_size, new_size, inp_sp[0])) return np.transpose(result, (2, 0, 1))
def forward(self, x): FN, C, FH, FW = self.W.shape if x.ndim == 3: x = x.reshape((1,) + x.shape) N, C, H, W = x.shape out_h = 1 + int((H + 2*self.pad - FH) / self.stride) out_w = 1 + int((W + 2*self.pad - FW) / self.stride) col = im2col(x, FH, FW, self.stride, self.pad) col_W = self.W.reshape(FN, -1).T out = np.dot(col, col_W) + self.b out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) self.x = x self.col = col self.col_W = col_W return out
def forward(self, feature_map): batch_size = feature_map.shape[0] in_channels = feature_map.shape[1] in_height = feature_map.shape[2] in_width = feature_map.shape[3] self.in_height = in_height self.in_width = in_width self.in_channels = in_channels out_width = in_width // self.kernel_size out_height = in_height // self.kernel_size self.out_width = out_width self.out_height = out_height self.cut_in_h = self.out_height * self.kernel_size self.cut_in_w = self.out_width * self.kernel_size out_channels = in_channels feat_mat = im2col(feature_map[:, :, :self.cut_in_h, :self.cut_in_w], self.kernel_size, out_height, out_width, in_channels, stride=self.kernel_size) # R(ic*k*k,bt*oh*ow) feat_mat = feat_mat.view(out_channels, self.kernel_size**2, -1) out_map, self.max_ind = feat_mat.max(dim=1) # # print(feat_mat) # print("feat_mat\n") # # print(self.max_ind) # print("max_ind\n") out_map = out_map.view(out_channels, batch_size, out_height, out_width).transpose(1, 0).contiguous() return out_map
def forward(self, x): N, C, H, W = x.shape OH = (H + 2*self.pad - self.FH)//self.stride + 1 OW = (W + 2*self.pad - self.FW)//self.stride + 1 col = im2col(x, self.FH, self.FW, self.stride, self.pad) # save for backward self.x_shape = x.shape self.col = col # NOTES # W.shape: (C*FH*FW, FN) wherein, each filter is a column # b.shape: (FN,) # col.shape: (N*OH*OW, C*FH*FW) # y.shape: (N*OH*OW, FN) # after reshape: (N, OH, OW, FN) # after transpose(N, FN, OH, OW) # FN (filter nums) == OC (output channels) y = np.dot(col, self.W) + self.b y = y.reshape(N, OH, OW, -1).transpose(0, 3, 1, 2) return y
def forward(self, x): FN, FC, FH, FW = self.W.shape if(x.ndim == 3): C, H, W = x.shape x = x.reshape(1, C, H, W) N, C, H, W = x.shape self.xshape = x.shape self.x = x out_h, out_w = get_conv_result_shape( H, W, FH, FW, self.stride, self.padding) im_col = im2col(x, FH, FW, self.stride, self.padding) self.im_col = im_col W_col = self.W.reshape((FN, -1)) out = im_col.dot(W_col.T)+self.b out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2) return out
def backward(self, dl_out, lr): batch_size, out_c, out_h, out_w = dl_out.shape padding_h = ( self.in_h - 1) * self.stride + self.kernel_size - 2 * self.padding - out_h padding_w = ( self.in_w - 1) * self.stride + self.kernel_size - 2 * self.padding - out_w padding_h //= 2 padding_w //= 2 padding_dout = torch.zeros( (batch_size, out_c, out_h + 2 * padding_h, out_w + 2 * padding_w), dtype=dl_out.dtype) padding_dout[:, :, padding_h:padding_h + out_h, padding_w:padding_w + out_w] = dl_out rotated_kernels = self.kernel.transpose(1, 0).flip(2).flip( 3) # (oc, ic, k, k) -> (ic, oc, k, k) padding_dout2col = im2col(padding_dout, self.kernel_size, self.in_w, self.in_h, self.out_channels, self.stride) rotated_kernels2row = kernel2row(rotated_kernels) dl_in = torch.matmul(rotated_kernels2row, padding_dout2col) # (ic, batch_size*in_h*in_w) dl_in = dl_in.reshape((self.in_channels, batch_size, self.in_h, self.in_w)).transpose(1, 0) dl_out = dl_out.permute(1, 0, 2, 3).contiguous().view(self.out_channels, -1) feat_mat = self.feat_mat.transpose(1, 0) dl_k = torch.matmul(dl_out, feat_mat) / batch_size dl_k = dl_k.view((self.out_channels, self.in_channels, self.kernel_size, self.kernel_size)) self.kernel -= lr * dl_k return dl_in
def forward(self, x): N, C, H, W = x.shape out_h = (H + 2*self.pad - self.pool_h)//self.stride + 1 out_w = (W + 2*self.pad- self.pool_w)//self.stride + 1 # x.shape: (N, C, H, W) # col.shape: (N*out_h*out_w, C*pool_h*pool_w) # after reshape: (N*out_h*out_w*C, pool_h*pool_w) col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad) col = col.reshape(-1, self.pool_h*self.pool_w) # save for backward self.x_shape = x.shape self.argmax = np.argmax(col, axis=1) # col.shape: (N*out_h*out_w*C, pool_h*pool_w) # after np.max: (N*out_h*out_w*C,) # after reshape: (N, out_h, out_w, C) # after transpose: (N, C, out_h, out_W) # so y.shape: (N, C, out_h, out_w) col = np.max(col, axis=1) y = col.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2) return y
def __max_pool(self, inputs, size, stride, padding): """ Description: Max pool layer Parameters: inputs -> The input of size [batch_size] x [filter] x [shape_x] x [shape_y] size -> The size of the tiling stride -> The applied translation at each step padding -> The padding (padding with 0 so the last column isn't left out) """ inp_sp = np.shape(inputs) # We reshape it so every filter is considered an image. tile_col = im2col(reshaped, size, stride=stride, padding=padding) # We take the max of each column max_ids = np.argmax(tile_col, axis=0) # We get the resulting 1 x 10240 vector result = tile_col[max_ids, range(max_ids.size)] new_size = (inp_sp[2] - size + 2 * padding) / stride + 1 result = np.reshape(result, (new_size, new_size, inp_sp[0])) # Make it from 16 x 16 x 10 to 10 x 16 x 16 return np.transpose(result, (2, 0, 1))
def EPLL_half_quadratic_split(noise_image, lamb, patch_size, T, betas=None, prior=None, I=None, log_fuction=None, log=None): """EPLL framework Args: noise_image(numpy.array): the image with noise lamb(float/numpy.array): the parameter lambda from Equation (2) in the paper, if it is matrix, it should have same size as image patch_size(int): the size of patches to extract. patch should be square betas(list): T(int): prior(function): I(numpy.array): the original image I, used only for PSNR calculations and comparisons Log_fuction(function): """ #print result to log or not print_log = log is not None #The real image noise standard deviation counts = patch_size**2 real_noise_sd = np.sqrt(1 / (lamb / counts)) PSNR = [] PSNR_I1 = [] #If log loss function is given, compute the loss in each iteration cost_list = [] cal_cost = log_fuction is not None #simple guess of beta, in case the auto-estimation doesn't work for some reason beta = abs(betas[0] / 4) #initialize with the noise image clean_image = noise_image k = 1 sd = np.Inf #iteration along all the beta for betaa in betas: #if betaa<0, estimate beta automatically. if betaa < 0: old_sd = sd sd, _ = estimate_noiseSD_using_Kurts(clean_image) if print_log: log.info("sd is %0.4f, beta is %0.4f *(1/real_noise_sd**2) " % (sd, (1 / sd**2) / (1 / real_noise_sd**2))) else: print("sd is %0.4f, beta is %0.4f *(1/real_noise_sd**2) " % (sd, (1 / sd**2) / (1 / real_noise_sd**2))) if np.isnan(sd) or sd > old_sd: beta = beta * 4 sd = beta**-0.5 else: beta = 1 / sd**2 else: beta = betaa # iteration for T times. for i in range(T): #get overlapping image patch z from current estimation z, _, _ = utils.im2col(clean_image, patch_size) #compute current cost if cal_cost: cost_list.append( 0.5 * np.sum(lamb * np.square(clean_image - noise_image)) - log_fuction(z)) if print_log: log.info("Cost is %0.4f" % cost_list[-1]) else: print("Cost is %0.4f" % cost_list[-1]) #compute MAP estimation on z clean_z = prior(z, patch_size, beta**-0.5, noise_image.shape) #average the pixels in the cleaned patches in z I1 = utils.scol2im(clean_z, patch_size, I.shape, "average") #close form solution of new estimate image for denoising and inpainting(A is Identity matrix clean_image = (noise_image * lamb) / (lamb + beta * counts) + ( beta * counts * I1) / (lamb + beta * counts) PSNR.append(20 * np.log10(1 / np.std(clean_image - I))) PSNR_I1.append(20 * np.log10(1 / np.std(I1 - I))) if print_log: log.info("PSNR is %0.4f I1 PSNR: %0.4f" % (PSNR[-1], PSNR_I1[-1])) else: print("PSNR is %0.4f I1 PSNR: %0.4f" % (PSNR[-1], PSNR_I1[-1])) k += 1 clean_image = clean_image.reshape(noise_image.shape) # clip values to be between 1 and 0, hardly changes performance clean_image[clean_image > 1] = 1 clean_image[clean_image < 0] = 0 return clean_image, PSNR, PSNR_I1, cost_list
# create save dir if not os.path.exists(save_path): os.makedirs(save_path) patch_size = 8 I = (imread('new.jpg')) / 255 mask = (imread('new_mask.png')) / 255. if len(I.shape) == 3: I = rgb2ycbcr(I) / 255. #find which patches are occluded for faster performance noiseI = np.copy(I) mask_index = mask > 0 tt = noiseI[:, :, 0] tt[mask_index] = -999.0 ttt, _, _ = im2col(tt, patch_size) exclude_list = [ np.sum(ttt[i] == -999.0) != ttt.shape[1] for i in range(ttt.shape[0]) ] GMM_path = "GSModel_8x8_200_2M_noDC_zeromean" GS = GMM_from_learned_model(GMM_path) # change prior if needed def denoise_GMM_prior(z, patch_size, noiseSD, imsize): return aprxMAPGMM(z, patch_size, noiseSD, imsize, GS, exclude_list) prior = denoise_GMM_prior # change log function if needed log_fuction = lambda Z: GMM_log_p(Z, GS)
def forward(self, x): self._im = x.reshape((x.shape[0],self.im_rect[0],self.im_rect[1])) self._t0 = utils.im2col(self._im, self.fit_rect, self.fit_stride) self._t1 = np.dot(self.weights, self._t0) self._t2 = self._t1 + self.biases return self.fact(self._t2)
def forward(self, x): self._im = x.reshape((x.shape[0], self.im_rect[0], self.im_rect[1])) self._t0 = utils.im2col(self._im, self.fit_rect, self.fit_stride) self._t1 = np.dot(self.weights, self._t0) self._t2 = self._t1 + self.biases return self.fact(self._t2)