-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
bada9bf
commit cf53f1f
Showing
36 changed files
with
4,150 additions
and
0 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
# aotgan Sample Code | ||
|
||
## Introduction | ||
This is sample code for using AppBuilder to load aotgan QNN model to HTP and execute inference to erase and in-paint part of given input image. | ||
|
||
## Setup AppBuilder environment and prepare QNN SDK libraries by referring to the links below: | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/README.md | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/Docs/User_Guide.md | ||
|
||
Copy the QNN libraries from QNN SDK to below path: | ||
``` | ||
C:\ai-hub\aotgan\qnn\libQnnHtpV73Skel.so | ||
C:\ai-hub\aotgan\qnn\QnnHtp.dll | ||
C:\ai-hub\aotgan\qnn\QnnHtpV73Stub.dll | ||
C:\ai-hub\aotgan\qnn\QnnSystem.dll | ||
C:\ai-hub\aotgan\qnn\libqnnhtpv73.cat | ||
``` | ||
|
||
## aotgan QNN models | ||
Download the quantized aotgan QNN models from Qualcomm® AI Hub: | ||
https://aihub.qualcomm.com/compute/models/aotgan | ||
|
||
After downloaded the model, copy it to the following path: | ||
``` | ||
"C:\ai-hub\aotgan\models\aotgan.bin" | ||
``` | ||
|
||
## Run the sample code | ||
Download the sample code from the following link: | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/Samples/aotgan/aotgan.py | ||
|
||
After downloaded the sample code, please copy it to the following path: | ||
``` | ||
C:\ai-hub\aotgan\ | ||
``` | ||
|
||
Copy one sample 512x512 image and mask to following path: | ||
``` | ||
C:\ai-hub\aotgan\test_input_image.png | ||
C:\ai-hub\aotgan\test_input_mask.png | ||
``` | ||
|
||
Run the sample code: | ||
``` | ||
python aotgan.py | ||
``` | ||
|
||
## Output | ||
The output image will be saved to the following path: | ||
``` | ||
C:\ai-hub\aotgan\out.png | ||
``` | ||
|
||
## Reference | ||
You need to setup the AppBuilder environment before you run the sample code. Below is the guide on how to setup the AppBuilder environment: | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/README.md | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/Docs/User_Guide.md | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
# --------------------------------------------------------------------- | ||
# Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
# --------------------------------------------------------------------- | ||
|
||
import os | ||
import numpy as np | ||
import torch | ||
import torchvision.transforms as transforms | ||
|
||
from PIL import Image | ||
from PIL.Image import fromarray as ImageFromArray | ||
from torch.nn.functional import interpolate, pad | ||
from torchvision import transforms | ||
from typing import Callable, Dict, List, Tuple | ||
|
||
from qai_appbuilder import (QNNContext, Runtime, LogLevel, ProfilingLevel, PerfProfile, QNNConfig) | ||
|
||
image_size = 512 | ||
aotgan = None | ||
image_buffer = None | ||
|
||
|
||
def preprocess_PIL_image(image: Image) -> torch.Tensor: | ||
"""Convert a PIL image into a pyTorch tensor with range [0, 1] and shape NCHW.""" | ||
transform = transforms.Compose([transforms.Resize(image_size), # bgr image | ||
transforms.CenterCrop(image_size), | ||
transforms.PILToTensor()]) | ||
img: torch.Tensor = transform(image) # type: ignore | ||
img = img.float().unsqueeze(0) / 255.0 # int 0 - 255 to float 0.0 - 1.0 | ||
return img | ||
|
||
def torch_tensor_to_PIL_image(data: torch.Tensor) -> Image: | ||
""" | ||
Convert a Torch tensor (dtype float32) with range [0, 1] and shape CHW into PIL image CHW | ||
""" | ||
out = torch.clip(data, min=0.0, max=1.0) | ||
np_out = (out.detach().numpy() * 255).astype(np.uint8) | ||
return ImageFromArray(np_out) | ||
|
||
def preprocess_inputs( | ||
pixel_values_or_image: Image, | ||
mask_pixel_values_or_image: Image, | ||
) -> Dict[str, torch.Tensor]: | ||
|
||
NCHW_fp32_torch_frames = preprocess_PIL_image(pixel_values_or_image) | ||
NCHW_fp32_torch_masks = preprocess_PIL_image(mask_pixel_values_or_image) | ||
|
||
# The number of input images should equal the number of input masks. | ||
if NCHW_fp32_torch_masks.shape[0] != 1: | ||
NCHW_fp32_torch_masks = NCHW_fp32_torch_masks.tile( | ||
(NCHW_fp32_torch_frames.shape[0], 1, 1, 1) | ||
) | ||
|
||
# Mask input image | ||
image_masked = ( | ||
NCHW_fp32_torch_frames * (1 - NCHW_fp32_torch_masks) + NCHW_fp32_torch_masks | ||
) | ||
|
||
return {"image": image_masked, "mask": NCHW_fp32_torch_masks} | ||
|
||
# AotGan class which inherited from the class QNNContext. | ||
class AotGan(QNNContext): | ||
def Inference(self, input_data, input_mask): | ||
input_datas=[input_data, input_mask] | ||
output_data = super().Inference(input_datas)[0] | ||
return output_data | ||
|
||
def Init(): | ||
global aotgan | ||
|
||
# Config AppBuilder environment. | ||
QNNConfig.Config(os.getcwd() + "\\qnn", Runtime.HTP, LogLevel.WARN, ProfilingLevel.BASIC) | ||
|
||
# Instance for AotGan objects. | ||
aotgan_model = "models\\aotgan.bin" | ||
aotgan = AotGan("aotgan", aotgan_model) | ||
|
||
def Inference(input_image_path, input_mask_path, output_image_path): | ||
global image_buffer | ||
|
||
# Read and preprocess the image&mask. | ||
image = Image.open(input_image_path) | ||
mask = Image.open(input_mask_path) | ||
inputs = preprocess_inputs(image, mask) | ||
image_masked, mask_torch = inputs["image"], inputs["mask"] | ||
image_masked = image_masked.numpy() | ||
mask_torch = mask_torch.numpy() | ||
|
||
image_masked = np.transpose(image_masked, (0, 2, 3, 1)) | ||
mask_torch = np.transpose(mask_torch, (0, 2, 3, 1)) | ||
|
||
# Burst the HTP. | ||
PerfProfile.SetPerfProfileGlobal(PerfProfile.BURST) | ||
|
||
# Run the inference. | ||
output_image = aotgan.Inference([image_masked], [mask_torch]) | ||
|
||
# Reset the HTP. | ||
PerfProfile.RelPerfProfileGlobal() | ||
|
||
# show%save the result | ||
output_image = torch.from_numpy(output_image) | ||
output_image = output_image.reshape(image_size, image_size, 3) | ||
output_image = torch.unsqueeze(output_image, 0) | ||
output_image = [torch_tensor_to_PIL_image(img) for img in output_image] | ||
image_buffer = output_image[0] | ||
image_buffer.save(output_image_path) | ||
image_buffer.show() | ||
|
||
|
||
def Release(): | ||
global aotgan | ||
|
||
# Release the resources. | ||
del(aotgan) | ||
|
||
|
||
Init() | ||
|
||
Inference("input.png", "mask.png", "output.png") | ||
|
||
Release() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
# unet_segmentation Sample Code | ||
|
||
## Introduction | ||
This is sample code for using AppBuilder to load unet_segmentation QNN model to HTP and execute inference to produce a segmentation mask for an image. | ||
|
||
## Setup AppBuilder environment and prepare QNN SDK libraries by referring to the links below: | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/README.md | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/Docs/User_Guide.md | ||
|
||
Copy the QNN libraries from QNN SDK to below path: | ||
``` | ||
C:\ai-hub\unet_segmentation\qnn\libQnnHtpV73Skel.so | ||
C:\ai-hub\unet_segmentation\qnn\QnnHtp.dll | ||
C:\ai-hub\unet_segmentation\qnn\QnnHtpV73Stub.dll | ||
C:\ai-hub\unet_segmentation\qnn\QnnSystem.dll | ||
C:\ai-hub\unet_segmentation\qnn\libqnnhtpv73.cat | ||
``` | ||
|
||
## unet_segmentation QNN models | ||
Download the quantized unet_segmentation QNN models from Qualcomm® AI Hub: | ||
https://aihub.qualcomm.com/compute/models/unet_segmentation | ||
|
||
After downloaded the model, copy it to the following path: | ||
``` | ||
"C:\ai-hub\unet_segmentation\models\unet_segmentation.bin" | ||
``` | ||
|
||
## Run the sample code | ||
Download the sample code from the following link: | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/Samples/unet_segmentation/unet_segmentation.py | ||
|
||
After downloaded the sample code, please copy it to the following path: | ||
``` | ||
C:\ai-hub\unet_segmentation\ | ||
``` | ||
|
||
Copy one sample image to following path: | ||
``` | ||
C:\ai-hub\unet_segmentation\in.jpg | ||
``` | ||
|
||
Run the sample code: | ||
``` | ||
python unet_segmentation.py | ||
``` | ||
|
||
## Output | ||
The output image will be saved to the following path: | ||
``` | ||
C:\ai-hub\unet_segmentation\out.jpg | ||
``` | ||
|
||
## Reference | ||
You need to setup the AppBuilder environment before you run the sample code. Below is the guide on how to setup the AppBuilder environment: | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/README.md | ||
https://github.com/quic/ai-engine-direct-helper/blob/main/Docs/User_Guide.md | ||
|
||
|
Oops, something went wrong.