项目迁移至AidLux说明文档

将电脑上的已有项目迁移到AidLux平台,并加入到examples-gpu案例中,实现可视化一键运行,避免了重复的命令行操作。

下面用一个图像去噪(Image Denoising)的示例作为演示:

1. 第一步:将项目文件拷贝到手机上

打开AidLux上的Cloud_ip,可以看到其ip地址,在电脑上的浏览器里输入此网址远程访问Aid桌面。选择文件图标, 在/sdcard目录下新建文件夹,将项目放到该路径下。项目也可放到任意指定路径下,笔者这里推荐/sdcard,避免重装AidLux示例被重置。

2. 第二步:调试代码

打开终端,试运行代码,看是否缺失必要的依赖库和包,可在应用中心直接下载,也可通过aid install命令进行安装。

下面对denoise_img.py代码做简略说明:

import cv2
import torchvision
import numpy as np
import torch

from UNet import UNet # UNet.py文件定义模型架构

使用opencv读取图像

img_cv = cv2.imread(‘./noise_img/test4.jpg’) # np.array, (H x W x C), [0, 255], BGR
print(img_cv.shape)

加载模型路径

checkpoint = torch.load(‘./checkpoints/chk_2_1_0.5.pt’, map_location=torch.device(‘cpu’))

model_test = UNet(in_channels=3, out_channels=3).double()
model_test.load_state_dict(checkpoint[‘model_state_dict’])
model_test = model_test.cpu()

将图像数据处成模型输入需要的格式

torch.set_default_tensor_type(torch.DoubleTensor)
tensor_cv = torch.from_numpy(np.transpose(img_cv, (2, 0, 1))) # (C x H x W)
tensor_cv = tensor_cv.unsqueeze(0)
tensor_cv = tensor_cv / 127.5 - 1 # range: [-1, 1]

print(tensor_cv.shape, tensor_cv)

denoise_img = torchvision.utils.make_grid(model_test(tensor_cv)) # 运行模型
print(denoise_img.shape)

保存图片降噪结果

cv2.imwrite(‘cv_img.jpg’, np.transpose(denoise_img.detach().numpy().astype(np.uint8), (1, 2, 0)))
print(‘Save denoising image successfully!’)

3. 第三步:编写可视化界面

上边是常见模型推断演示的一般过程,不过将待处理的图片直接写死了,每次替换图片都需要修改代码,过于繁琐。下边写一个简单的界面,通过可视化窗口手动选择图片,执行代码。

import PIL.Image as Image
import base64
import remi.gui as gui
from urllib.request import urlopen
from remi import start, App
from threading import Timer

import cv2
import torchvision
import numpy as np
import torch

import android
droid = android.Android()

from UNet import UNet

try:
import socketio

sio = socketio.Client()
sio.connect('ws://0.0.0.0:9909')
socket_connection = True

except:
socket_connection = False

def base64_to_style_image(base64_image):
return ‘data:image/png;base64,’+base64_image

class MyApp(App):
def init(self, *args):
super(MyApp, self).init(*args)

def main(self):
    # 定义窗体
    verticalContainer = gui.Container(width=404, height=700, style={'display': 'block', 'overflow': 'hidden','text-align': 'center'})
    # 窗口1
    self.img_lr = gui.Image('', width=256,height=256,margin='1px')
    verticalContainer.append(self.img_lr)
    # 控件1
    self.btFileDiag = gui.Button('Select Image', width='100%', height=30, margin='0px')
    self.btFileDiag.onclick.do(self.open_fileselection_dialog)
    verticalContainer.append(self.btFileDiag)
    # 窗口2
    self.img_hr = gui.Image('',width=256, height=256, margin='1px')
    verticalContainer.append(self.img_hr)
    # 控件2,注意退出程序需要点此处
    self.btClose = gui.Button('Exit', width=404, height=30, margin='0px')
    self.btClose.onclick.do(self.server_close)
    verticalContainer.append(self.btClose)

    return verticalContainer

def open_fileselection_dialog(self, widget):
    print('open_fileselection_dialog')
    self.fileselectionDialog = gui.FileSelectionDialog('File Selection Dialog', 
                                                      'Select files and folders', False,'.')
    self.fileselectionDialog.confirm_value.do(
        self.on_fileselection_dialog_confirm)

    # here is returned the Input Dialog widget, and it will be shown
    self.fileselectionDialog.show(self)

def on_fileselection_dialog_confirm(self, widget, filelist):
    print('filelist', filelist)
    if (len(filelist) > 0):
        file_name = filelist[0]
        with open(filelist[0], "rb") as f:
            lr, hr = self.imageDemo(file_name)
            print(lr.shape, hr.shape)
            lr = cv2.imencode('.jpg',lr)[1]
            hr = cv2.imencode('.jpg',hr)[1]
            bs64_str_lr = str(base64.b64encode(lr))[2:-1]

            bs64_str_hr = str(base64.b64encode(hr))[2:-1]
            if not isinstance(bs64_str_lr, str):
                bs64_str_lr = bs64_str_lr.decode()

            if not isinstance(bs64_str_hr, str):
                bs64_str_hr = bs64_str_hr.decode()
            self.img_lr.set_image(base64_to_style_image(bs64_str_lr))
            self.img_hr.set_image(base64_to_style_image(bs64_str_hr))


def imageDemo(self, image_path):
    # 使用opencv读取图像

    img = cv2.imread(image_path)     # np.array, (H x W x C), [0, 255], BGR
    # img = cv2.resize(img, (256, 256))

    checkpoint = torch.load('./checkpoints/chk_2_1_0.5.pt', map_location=torch.device('cpu'))

    model_test = UNet(in_channels=3, out_channels=3).double()
    model_test.load_state_dict(checkpoint['model_state_dict'])
    model_test = model_test.cpu()


    torch.set_default_tensor_type(torch.DoubleTensor)
    tensor_cv = torch.from_numpy(np.transpose(img, (2, 0, 1)))   # (C x H x W)
    tensor_cv = tensor_cv.unsqueeze(0)
    tensor_cv = tensor_cv / 127.5 - 1   # range: [-1, 1]

    # print(tensor_cv.shape, tensor_cv)
    denoise_img = torchvision.utils.make_grid(model_test(tensor_cv))
    print('----denoise shape:', denoise_img.shape, type(denoise_img))

    pred = (denoise_img + 1) * 127.5     # unnormalize [0, 255]
    pred = pred.detach().numpy()
    pred = np.transpose(pred, (1, 2, 0))
    pred = pred.astype(np.uint8)
    print('----pred shape:', pred.shape)
    # cv2.imwrite('res_test.jpg', pred)
    return img, pred

def server_close(self, widget):
    pname = 'image_denoising.py'
    urlopen('http://127.0.0.1:9000/?name=kill~' + pname)

if name == "main":
droid.showCustomDialog(5556)
# sio.emit(‘request_open_window’, {‘data’: {‘url’: ‘http://0.0.0.0:’ + str(5556),
# ‘title’: ‘Deniose’, ‘icon’: ‘’, ‘camid’: 0}})
start(MyApp, update_interval=0.1, address=‘0.0.0.0’, port=5556, start_browser=False, enable_file_cache=False)

通过在命令行运行该文件,手机上会跳出界面,选择指定图片文件,确定后,便会执行图片降噪处理,并将处理前后图片显示在界面上。

4. 第四步:将该实例放入examples-gpu中

修改前端文件,路径/root/User/demo/aid.dev/

i.在index.html中添加新增示例的代码块,在./assets/img/photos/路径下添加事先准备的封面图像x.png(本文为方便起见,直接复用了其他示例封面)

ii.添加代码块

<div class="col-12 col-md-6  d-flex">
  <!-- Card -->
  <div class="card mb-6 shadow-light-lg lift lift-lg">
    <!-- Image -->
    <script>document.write("<a class='card-img-top' href=http://"+window.location.hostname+":8900/sdcard/kuhn/image_denoising/image_denoising.py~editor>");</script>
&lt;!--&lt;a class=&quot;card-img-top&quot; href=&quot;https://www.aidlearning.net/box_tracking&quot;&gt;--&gt;
  &lt;!-- Image --&gt;
  &lt;img src=&quot;assets/img/photos/x.png&quot; alt=&quot;...&quot; class=&quot;card-img-top&quot;&gt;
&lt;/a&gt;
&lt;!-- Body --&gt;
&lt;!--&lt;a class=&quot;card-body&quot; href=&quot;https://www.aidlearning.net/box_tracking&quot;&gt;--&gt;
&lt;script&gt;document.write(&quot;&lt;a class='card-body' href=http://&quot;+window.location.hostname+&quot;:8900/sdcard/kuhn/image_denoising/image_denoising.py~editor&gt;&quot;);&lt;/script&gt;
  &lt;h3&gt;Image Denoising&lt;/h3&gt;
  &lt;p class=&quot;mb-0 text-muted&quot;&gt;图片去噪 &lt;/p&gt;
&lt;/a&gt;

</div>
</div>

以上代码主要改动有5处

a) Image块里指定运行的python文件路径

b) 指定界面显示图像路径assets/img/photos/x.jpg

c) Body块里再次指定待运行的python文件路径

d) 修改标题Image Denoising

e) 添加示例简要中文描述

至此,在示例中心就能看见新鲜上线的示例啦!


Ps: 非正常退出窗口,下次启动可能会造成端口号被占用。通过ps aux|grep python命令能查到哪些进程在运行,用kill -9 [端口号] 命令 杀掉指定进程

1 个赞

优秀~

挺清楚哦

试一下呢?

真棒!!

请问ssh登录的密码是多少,端口变化了service不提示新端口,找了半天ssh的端口却发现密码不是123456

ssh root@192.168.xx.xx -p9022 密码123456

用户名是root哦,新版本

0.87f3要修改参数,你可以看开发文档历史版本的快速开始里面有写,0.88直接连接9022就可以