当前位置: 首页 > article >正文

图像修复的可视化demo代码

  • 做项目的时候需要用到一个windows窗口可视化来展示我们的工作,我们的工作是一个文本指导的人脸图像修复,所以窗口需要包括输入图像,文本指导输入和修复结果,并且提供在输入图像上画mask的功能,使用tkinter来实现,相关代码如下:
# Authro: Wu
# define of gui
# borrow from https://github.com/zsyzzsoft/co-mod-ganimport tkinter as tk
from PIL import Image, ImageTk, ImageDraw
import numpy as np
import cv2
import torch
import os
def adjust_dynamic_range(data, drange_in, drange_out):if drange_in != drange_out:scale = (np.float32(drange_out[1]) - np.float32(drange_out[0])) / (np.float32(drange_in[1]) - np.float32(drange_in[0]))bias = (np.float32(drange_out[0]) - np.float32(drange_in[0]) * scale)data = data * scale + biasreturn dataclass App(tk.Tk):def __init__(self, model, window_size=256):super().__init__()self.state = -1self.window_size = window_sizeself.canvas = tk.Canvas(self, bg='gray', height=self.window_size, width=self.window_size*2+10)self.canvas.bind("<Button-1>", self.L_press)self.canvas.bind("<ButtonRelease-1>", self.L_release)self.canvas.bind("<B1-Motion>", self.L_move)self.canvas.bind("<Button-3>", self.R_press)self.canvas.bind("<ButtonRelease-3>", self.R_release)self.canvas.bind("<B3-Motion>", self.R_move)self.canvas.bind("<Key>", self.key_down)self.canvas.bind("<KeyRelease>", self.key_up)self.canvas.pack()self.canvas.focus_set()self.canvas_image_left = self.canvas.create_image(0, 0, anchor='nw')self.canvas_image_right = self.canvas.create_image(self.window_size + 10, 0, anchor='nw')# 'generate' buttonself.btn_pen = tk.Button(self, text="生成", command=self.generate)self.btn_pen.pack(side="left", padx="10")# 'continue' buttonself.btn_pen = tk.Button(self, text="继续", command=self.switch)self.btn_pen.pack(side="left", padx="10")# textself.text = Noneself.entry01 = tk.Entry(self, textvariable=self.text, width=50)self.entry01.pack()self.model = modelself.new_image()self.display()def generate(self):real = adjust_dynamic_range(self.input_image, [0, 255], [0, 1])# real: np array (1,3,256,256); # mask: np array (1,1,256,256),masked 0, unmasked 1; # text: stringself.text = self.entry01.get()if len(self.text) < 1:self.text = 'a man'# with torch.no_grad():#     self.output_image = self.model.inpaint_(real, self.mask, self.text)  # save to localsave_path = 'D:\我的文件\dd\demo\mask'if not os.path.exists(save_path):os.makedirs(save_path)mask_to_save = np.repeat(np.expand_dims(np.squeeze((1-self.mask)*255),2),3,2)Image.fromarray(mask_to_save).save(os.path.join(save_path, '7532_mask.png'))input_to_save = np.transpose(np.squeeze(self.input_image*np.repeat(self.mask,3,1)+np.repeat((1-self.mask)*255,3,1)), (1, 2, 0))Image.fromarray(input_to_save).save(os.path.join(save_path, '7532_masked.png'))# predict_to_save = np.transpose(np.squeeze(self.output_image), (1, 2, 0))# Image.fromarray(predict_to_save).save(os.path.join(save_path, 'predict.png'))self.display(2)self.mask = np.ones((1, 1, self.resolution, self.resolution), np.uint8)self.mask_history = [self.mask]def switch(self):self.input_image = self.output_imageself.display(1)def new_image(self):################################# load image from sourceimage_path = tk.filedialog.askopenfilename()# self.input_image = Image.open(image_path).convert('RGB').resize((256,256))self.input_image = Image.open(image_path).convert('RGB')# self.input_image = Image.open('./application/eyeglasses/mmceleba/5995.jpg').convert('RGB').resize((256,256))self.input_image = np.expand_dims(np.transpose(np.asarray(self.input_image, dtype=np.uint8), (2,0,1)),axis=0)#######################self.resolution = self.input_image.shape[-1]self.mask = np.ones((1, 1, self.resolution, self.resolution), np.uint8)self.mask_history = [self.mask]def display(self, state=0):if state != self.state:self.last_state = self.stateself.state = stateif self.state == 0: #  paintingimage = self.input_image * self.mask + (1-self.mask)*255image_for_display = np.transpose(image[0, :3], (1, 2, 0))image_for_display_resized = cv2.resize(image_for_display, (self.window_size, self.window_size))self.tkimage = ImageTk.PhotoImage(image=Image.fromarray(image_for_display_resized))self.canvas.itemconfig(self.canvas_image_left, image=self.tkimage)elif self.state == 1: # switchimage = self.input_imageimage_for_display = np.transpose(image[0, :3], (1, 2, 0))image_for_display_resized = cv2.resize(image_for_display, (self.window_size, self.window_size))self.tkimage = ImageTk.PhotoImage(image=Image.fromarray(image_for_display_resized))self.canvas.itemconfig(self.canvas_image_left, image=self.tkimage)elif self.state == 2: # generateimage =  self.output_image image_for_display = np.transpose(image[0, :3], (1, 2, 0))image_for_display_resized = cv2.resize(image_for_display, (self.window_size, self.window_size))self.tkimage_right = ImageTk.PhotoImage(image=Image.fromarray(image_for_display_resized))self.canvas.itemconfig(self.canvas_image_right, image=self.tkimage_right)image =  self.input_image image_for_display = np.transpose(image[0, :3], (1, 2, 0))image_for_display_resized = cv2.resize(image_for_display, (self.window_size, self.window_size))self.tkimage_left = ImageTk.PhotoImage(image=Image.fromarray(image_for_display_resized))self.canvas.itemconfig(self.canvas_image_left, image=self.tkimage_left)def get_pos(self, event):return (int(event.x * self.resolution / self.window_size), int(event.y * self.resolution / self.window_size))def L_press(self, event):self.last_pos = self.get_pos(event)def L_move(self, event):a = self.last_posb = self.get_pos(event)width = 6img = Image.fromarray(self.mask[0, 0])draw = ImageDraw.Draw(img)draw.line([a, b], fill=0, width=width)draw.ellipse((b[0] - width // 2, b[1] - width // 2, b[0] + width // 2, b[1] + width // 2), fill=0)self.mask = np.array(img)[np.newaxis, np.newaxis, ...]self.display()self.last_pos = bdef L_release(self, event):self.L_move(event)self.mask_history.append(self.mask)def R_press(self, event):self.last_pos = self.get_pos(event)def R_move(self, event):a = self.last_posb = self.get_pos(event)self.mask = self.mask_history[-1].copy()self.mask[0, 0, max(min(a[1], b[1]), 0): max(a[1], b[1]), max(min(a[0], b[0]), 0): max(a[0], b[0])] = 0self.display()def R_release(self, event):self.R_move(event)self.mask_history.append(self.mask)def key_down(self, event):if event.keysym == 'z':if len(self.mask_history) > 1:self.mask_history.pop()self.mask = self.mask_history[-1]self.display()def key_up(self, event):if event.keysym in ['1', '2']:self.display(self.last_state)if __name__ == "__main__":# 这里model不能用None,应当定义一个nn.Module对象并load参数用于修复,这里就不给出来model的定义了。app = App(model=None, window_size=256)app.mainloop()

相关文章:

图像修复的可视化demo代码

做项目的时候需要用到一个windows窗口可视化来展示我们的工作&#xff0c;我们的工作是一个文本指导的人脸图像修复&#xff0c;所以窗口需要包括输入图像&#xff0c;文本指导输入和修复结果&#xff0c;并且提供在输入图像上画mask的功能&#xff0c;使用tkinter来实现&#…...

autodl 安装了多个conda虚拟环境 选择合适虚拟环境的语句

1.conda env list 列出所有虚拟环境 可以看到&#xff0c;我有两个虚拟环境&#xff0c;一个是joygen&#xff0c;一个是base conda activate base 或者 conda activate joygen 激活对应的环境。我选择激活 joygen 环境 然后就可以在joygen环境下进行操作了 base环境也是同理…...

【AI工具应用】使用 trae 实现 word 转成 html

假如我们要实现某个网站的《隐私协议》等静态页面&#xff0c;产品给了一个 word 文档&#xff0c;以前我都是手动从 word 文档复制一行的文字&#xff0c;然后粘贴到一个html文件中&#xff0c;还得自己加各种标签&#xff0c;很麻烦。 我们可以使用 trae 等 ai 工具实现 wor…...

ansible-playbook 进阶 接上一章内容

1.异常中断 做法1&#xff1a;强制正常 编写 nginx 的 playbook 文件 01-zuofa .yml - hosts : web remote_user : root tasks : - name : create new user user : name nginx-test system yes uid 82 shell / sbin / nologin - name : test new user shell : gete…...

趋势直线指标

趋势直线副图和主图指标&#xff0c;旨在通过技术分析工具帮助交易者识别市场趋势和潜在的买卖点。 副图指标&#xff1a;基于KDJ指标的交易策略 1. RSV值计算&#xff1a; - RSV&#xff08;未成熟随机值&#xff09;反映了当前收盘价在过去一段时间内的相对位置。通过计算当前…...

基线配置管理:为什么它对网络稳定性至关重要

什么是基线配置&#xff08;Baseline Configuration&#xff09; 基线配置&#xff08;Baseline Configuration&#xff09;是经过批准的标准化主设置&#xff0c;代表所有设备应遵循的安全、合规且运行稳定的配置基准&#xff0c;可作为评估变更、偏差或未授权修改的参考基准…...

AWS WebRTC:获取ICE服务地址(part 1)

建立WebRTC连接的第二步是获取ICE服务地址。 ICE全称&#xff1a;Interactive Connectivity Establishment&#xff0c;建立互动连接。 ICE 服务地址&#xff0c;主要是 TURN 和 STUN 服务器的地址&#xff0c;用于 WebRTC 在 NAT 网络环境中协商建立连接。 上代码&#xff…...

Nest全栈到失业(一):Nest基础知识扫盲

Nest 是什么? 问你一个问题,node是不是把js拉出来浏览器环境运行了?当然,他使用了v8引擎加上自己的底层模块从而实现了,在外部编辑处理文件等;然后它使用很多方式来发送请求是吧,你知道的什么http.request 或 https.request; 我们浏览器中,使用AJAX以及封装AJAX和http的Axios…...

摩尔线程S4000国产信创计算卡性能实战——Pytorch转译,多卡P2P通信与MUSA编程

简介 MTT S4000 是基于摩尔线程曲院 GPU 架构打造的全功能元计算卡&#xff0c;为千亿规模大语言模型的训练、微调和推理进行了定制优化&#xff0c;结合先进的图形渲染能力、视频编解码能力和超高清 8K HDR 显示能力&#xff0c;助力人工智能、图形渲染、多媒体、科学计算与物…...

Tesseract OCR 安装与中文+英文识别实现

一、下载 https://digi.bib.uni-mannheim.de/tesseract/ 下载&#xff0c;尽量选择时间靠前的&#xff08;识别更好些&#xff09;。符合你的运行机&#xff08;我的是windows64&#xff09; 持续点击下一步安装&#xff0c;安装你认可的路径即可&#xff0c;没必要配置环境变…...

Cypress + React + TypeScript

🧪 Cypress + React + TypeScript 组件测试全流程实战:从入门到自动化集成 在现代前端开发中,组件测试 是保障 UI 行为可靠性的重要手段。本文将通过一个 React 项目示例,实战演示如何结合 Cypress + React + TypeScript 实现从零配置到自动化集成的完整测试链路。 一、项…...

每个路由器接口,都必须分配所属网络内的 IP 地址,用于转发数据包

在IP网络中&#xff0c;主机&#xff08;Host&#xff09;和路由器接口&#xff08;Router Interface&#xff09;都需要分配网络地址&#xff08;IP地址&#xff09;。 1. 主机&#xff08;Host&#xff09;的IP地址分配 (1) 作用 主机的IP地址用于唯一标识该设备&#xff0…...

c++第四课(基础c)——布尔变量

1.前言 好&#xff0c;今天我们来学布尔变量&#xff08;bool&#xff09;&#xff0c;开搞&#xff01; 2.正文 2.1布尔数据的定义值 布尔数据的定义值&#xff0c;是只有真和假 顺便提一句0是假&#xff0c;非0的数字都是真 不过为了简便 我们一般都用0和1 2.2布尔数…...

第2期:APM32微控制器键盘PCB设计实战教程

第2期&#xff1a;APM32微控制器键盘PCB设计实战教程 一、APM32小系统介绍 使用apm32键盘小系统开源工程操作 APM32是一款与STM32兼容的微控制器&#xff0c;可以直接替代STM32进行使用。本教程基于之前开源的APM32小系统&#xff0c;链接将放在录播评论区中供大家参考。 1…...

Docker-搭建MySQL主从复制与双主双从

Docker -- 搭建MySQL主从复制与双主双从 一、MySQL主从复制1.1 准备工作从 Harbor 私有仓库拉取镜像直接拉取镜像运行容器 1.2 配置主、从服务器1.3 创建主、从服务器1.4 启动主库&#xff0c;创建同步用户1.5 配置启动从库1.6 主从复制测试 二、MySQL双主双从2.1 创建网络2.2 …...

LeetCode - 203. 移除链表元素

目录 题目 解题思路 读者可能出现的错误写法 正确的写法 题目 203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 解题思路 使用哨兵节点&#xff1a; 创建一个哨兵节点(dummy)&#xff0c;将其next指向原链表头节点 哨兵节点的作用是统一处理所有情况&#x…...

canvas 实现全屏倾斜重复水印

​ 参考&#xff1a; html、js、canvas实现水印_html页面使用canvas绘制重复水印-CSDN博客 效果 ​​​​ 不求水印显示完全。 实现代码 <template><div class"watermark" ref"waterMark"></div></template><script lang&q…...

vue3项目 前端文件下载的两种工具函数

1、Blob 流下载 Blob 表示不可变的原始数据的类文件对象&#xff0c;通常用于处理文件或大块二进制数据。 注意&#xff1a;js中还有一个二进制数据类型ArrayBuffer&#xff0c;它们的区别如下 Blob 可以位于磁盘、高速缓存内存和其他不可用的位置&#xff1b;ArrayBuffer 是存…...

SpringAI系列 - 升级1.0.0

目录 一、调整pom二、MessageChatMemoryAdvisor调整三、ChatMemory get方法删除lastN参数四、QuestionAnswerAdvisor调整Spring AI发布1.0.0正式版了😅 ,搞起… 一、调整pom <properties><java.version>17</java.version><spring-ai.version>...

5.31 day33

知识点回顾&#xff1a; PyTorch和cuda的安装 查看显卡信息的命令行命令&#xff08;cmd中使用&#xff09; cuda的检查 简单神经网络的流程 数据预处理&#xff08;归一化、转换成张量&#xff09; 模型的定义 继承nn.Module类 定义每一个层 定义前向传播流程 定义损失函数和优…...

Vue3 + VTable 高性能表格组件完全指南,一个基于 Canvas 的高性能表格组件

Vue3 + VTable 高性能表格组件完全指南 前言 VTable 是一个高性能的多维表格组件,专为处理大数据量场景而设计。它支持数十万条数据的快速渲染,提供了丰富的表格功能和良好的用户体验。本文将详细介绍如何在 Vue3 项目中使用 VTable,并解决常见的配置问题。 什么是 VTabl…...

【七. Java字符串操作与StringBuilder高效拼接技巧】

7. java字符串 7.1 API 介绍&#xff1a;应用程序编程接口。在 Java 中&#xff0c;API 指的是 JDK 提供的各种功能类&#xff0c;这些类把底层实现封装好了&#xff0c;我们不用关心内部怎么写的&#xff0c;直接用就行 用 API 帮助文档步骤&#xff1a;以查Random类为例 打…...

题解:洛谷 P12672 「LAOI-8」近期我们注意到有网站混淆视听

设 LGR 存在数量为 x x x&#xff0c;CSP 存在数量为 y y y。 很明显&#xff0c;我们只需要将其中数量较小的一方改没就行了&#xff08;一个巴掌拍不响&#xff09;。 每两个字符串可同意进行一次更改&#xff0c;答案为&#xff1a; ⌈ min ⁡ ( x , y ) 2 ⌉ \left\lce…...

HTML 计算网页的PPI

HTML 计算网页的PPI vscode上安装live server插件&#xff0c;可以实时看网页预览 有个疑问&#xff1a; 鸿蒙density是按照类别写死的吗&#xff0c;手机520dpi 折叠屏426dpi 平板360dpi <html lang"en" data - overlayscrollbars - initialize><header&…...

WIN11+eclipse搭建java开发环境

环境搭建&#xff08;WIN11ECLIPSE&#xff09; 安装JAVA JDK https://www.oracle.com/cn/java/technologies/downloads/#jdk24安装eclipse https://www.eclipse.org/downloads/ 注意&#xff1a;eclipse下载时指定aliyun的软件源&#xff0c;后面安装会快一些。默认是jp汉化e…...

Linux 环境下C、C++、Go语言编译环境搭建秘籍

引言 在当今多元化的编程世界里&#xff0c;C、C 和 Go 语言凭借各自独特的优势&#xff0c;在不同的领域发光发热。C 语言作为一门古老而强大的编程语言&#xff0c;以其高效、贴近硬件的特性&#xff0c;在操作系统、嵌入式系统等底层开发中占据着重要地位&#xff1b;C 作为…...

MMR-Mamba:基于 Mamba 和空间频率信息融合的多模态 MRI 重建|文献速递-深度学习医疗AI最新文献

Title 题目 MMR-Mamba: Multi-modal MRI reconstruction with Mamba and spatial-frequency information fusion MMR-Mamba&#xff1a;基于 Mamba 和空间频率信息融合的多模态 MRI 重建 01 文献速递介绍 磁共振成像&#xff08;MRI&#xff09;因其无创、无辐射特性以及…...

2.5/Q2,Charls最新文章解读

文章题目&#xff1a;Trajectories of depressive symptoms and risk of chronic liver disease: evidence from CHARLS DOI&#xff1a;10.1186/s12876-025-03943-7 中文标题&#xff1a;抑郁症状的轨迹和慢性肝病风险&#xff1a;来自 CHARLS 的证据 发表杂志&#xff1a;BM…...

Unity QFramework 简介

目录 什么是MVC模式&#xff1f; QFramework 架构提供了 Model 的概念 QFramework 架构引入 Command 的方式 QFramework 架构引入 Event事件机制 四个层&#xff1a;表现层、系统层、数据层、工具层 委托和回调函数的关系 命令和事件的区别 工具篇 QFramework整体基于M…...

C++ 日志系统实战第五步:日志器的设计

全是通俗易懂的讲解&#xff0c;如果你本节之前的知识都掌握清楚&#xff0c;那就速速来看我的项目笔记吧~ 本文项目代码编写收尾&#xff01; 日志器类 (Logger) 设计&#xff08;建造者模式&#xff09; 日志器主要用于和前端交互。当我们需要使用日志系统打印 log 时&…...