def ConvertPhoneImageToSLMImage(image_phone, SLM_to_phone_zoom_ratio): """ Resize the phone display image to be displayed on SLM, such that the phone display imaged onto SLM matches exactly the size and position of the one on the SLM. Returns a PIL image to be saved. image_phone: 2D numpy array with dtype uint8 SLM_to_phone_zoom_ratio: the number of pixels on the SLM divided the number of pixels on the phone such that the pattern of their image are of the same size """ r = SLM_to_phone_zoom_ratio # equals the number of pixels of a line on SLM divided the that of the same line on the phone. (h, w) = (1152, 1920) # SLM size #im = image_phone.transpose() # transpose the image from 1920x1080 to 1080x1920 #im = im[::-1, :] # flip left and right # Pad the phone image to 1920x1600 to give enough margin for cropping later if isinstance(image_phone, (np.ndarray, )): #im = np.zeros((1920, 1600), dtype="uint8") #im[:, 260:(260+1080)] = image_phone im = np.zeros((h, w), dtype="uint8") im[36:(36 + 1080), :] = image_phone.transpose() imPIL = PIL.Image.fromarray(im) # Convert from numpy to PIL image elif isinstance(image_phone, (torch.Tensor, )): #im = torch.zeros(1920, 1600, dtype=torch.uint8) #im[:, 260:(260+1080)] = image_phone im = torch.zeros(h, w, dtype=torch.uint8) im[36:(36 + 1080), :] = image_phone.t() imPIL = ToPILImage()(im) # Convert from numpy to PIL image # Adjust pixel values according to SLM LUT # im[im == 0] = 155 # pixel value for the max transmission intensity on SLM # im[im == 255] = 77 # pixel value for the min transmission intensity on SLM # Resize the SLM image new_width = round( float(im.shape[1]) * r / 2 ) * 2 # Calculate the resized image size, round to even number of pixels. new_height = round(float(im.shape[0]) * r / 2) * 2 imPIL = imPIL.resize((new_width, new_height)) # Resize the image # Transform the image on the SLM to have the same spatial orientation as that on the phone. imPIL = PIL.ImageOps.flip(imPIL) imPIL = PIL.ImageOps.mirror(imPIL) # Create a PIL image of the exactly same size as required by the SLM. rowOffset = int( (imPIL.size[1] - h) / 2) # Calculate the boundary coordinate for cropping the image colOffset = int((imPIL.size[0] - w) / 2) # PIL.size sequence is reversed from numpy.shape!!!!!!! image_SLM = imPIL.crop( (colOffset, rowOffset, colOffset + w, rowOffset + h)) # Crop the image to fit SLM size (1152x1920) return image_SLM
def create_image(net, loader, name, upscaling=2, multiscale=False): patch_size = 30 patches = np.array( [[85, 90, 85 + patch_size, 90 + patch_size], [160, 140, 160 + patch_size, 140 + patch_size], [350, 80, 350 + patch_size, 80 + patch_size]]) fig = plt.figure(figsize=(15, 18), dpi=100) gs = fig.add_gridspec(4, 3, wspace=0.01, hspace=0.3, left=0.05, top=0.95, bottom=0.02, right=0.95) highres, lowres = loader[0] lowres = lowres.to(torch.device("cuda:0")) lowres = lowres.view([1] + list(lowres.size())) net.eval() with torch.no_grad(): if (multiscale): superres = net(lowres, upscaling) else: superres = net(lowres) lowres = ToImage()(lowres.cpu().view(lowres.size()[1:])) superres = ToImage()(superres.cpu().view(superres.size()[1:])) highres = ToImage()(highres.cpu().view(highres.size()[1:])) lowres_draw = lowres.copy() draw = ImageDraw.Draw(lowres_draw) draw.rectangle(list(patches[0]), outline='white') draw.rectangle(list(patches[1]), outline='white') draw.rectangle(list(patches[2]), outline='white') lowres = lowres.resize((lowres.size[0] * upscaling, lowres.size[1] * upscaling), Image.BICUBIC) psnr_low, psnr_super, ssim_low, ssim_super = compute_metrics( net, DataLoader(loader), upscaling, multiscale) lowres_title = "Low-resolution image" +\ "\nAverage PSNR over the dataset: {:.2f}\n".format(psnr_low) +\ "Average SSIM over the dataset: {:.4f}".format(ssim_low) superres_title = "Reconstructed image\n" +\ "Average PSNR over the dataset: {:.2f}\n".format(psnr_super) +\ "Average SSIM over the dataset: {:.4f}".format(ssim_super) fig.add_subplot(gs[0, 0], xticks=[], yticks=[], ylabel=f"Image", title=lowres_title) plt.imshow(np.array(lowres_draw)) fig.add_subplot(gs[0, 1], xticks=[], yticks=[], title=superres_title) plt.imshow(np.array(superres)) fig.add_subplot(gs[0, 2], xticks=[], yticks=[], title="High-resolution image") plt.imshow(np.array(highres)) ylabels = ["Patch 1", "Patch 2", "Patch 3"] for i in range(3): print(lowres.size, highres.size, superres.size) lowres_patch = lowres.crop(patches[i] * upscaling) highres_patch = highres.crop(patches[i] * upscaling) superres_patch = superres.crop(patches[i] * upscaling) fig.add_subplot(gs[1 + i, 0], xticks=[], yticks=[], ylabel=ylabels[i]) plt.imshow(np.array(lowres_patch)) fig.add_subplot(gs[1 + i, 1], xticks=[], yticks=[]) plt.imshow(np.array(superres_patch)) fig.add_subplot(gs[1 + i, 2], xticks=[], yticks=[]) plt.imshow(np.array(highres_patch)) plt.savefig(name)