未验证 提交 f1c4a3ae 编写于 作者: 走神的阿圆's avatar 走神的阿圆 提交者: GitHub

add image_matrix

上级 8f9993e4
...@@ -287,6 +287,76 @@ visualdl --logdir ./log --port 8080 ...@@ -287,6 +287,76 @@ visualdl --logdir ./log --port 8080
<img src="https://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/>
</p> </p>
### 添加图片矩阵
除使用add_image记录一张图片之外,还可以使用add_image_matrix一次添加多张图片并生成一张图片矩阵,接口及参数说明如下:
add_image_matrix的记录接口如下:
```python
add_image_matrix(tag, imgs, step, rows=-1, scale=1, walltime=None, dataformats="HWC")
```
接口参数说明如下:
| 参数 | 格式 | 含义 |
| -------- | ------------- | ------------------------------------------- |
| tag | string | 记录指标的标志,如`train/loss`,不能含有`%` |
| imgs | numpy.ndarray | 以ndarray格式表示的多张图片,第一维为图片的数量 |
| step | int | 记录的步数 |
| rows | int | 生成图片矩阵的行数,默认值为-1,表示尽量把传入的图片组合成行列数相近的形式 |
| scale | int | 图片放大比例,默认为1 |
| walltime | int | 记录数据的时间戳,默认为当前时间戳 |
| dataformats| string | 传入的图片格式,包括`NCHW``HWC``HW`,默认为`HWC`|
#### Demo
下面展示了使用 Image 组件合成并记录多张图片数据的示例,代码文件请见[Image组件](https://github.com/PaddlePaddle/VisualDL/blob/develop/demo/components/image_matrix_test.py)
```python
import numpy as np
from PIL import Image
from visualdl import LogWriter
def random_crop(img):
"""Get random block of img, which size is 100x100.
"""
img = Image.open(img)
w, h = img.size
random_w = np.random.randint(0, w - 100)
random_h = np.random.randint(0, h - 100)
r = img.crop((random_w, random_h, random_w + 100, random_h + 100))
return np.asarray(r)
if __name__ == '__main__':
imgs = []
# 获取8张图像
for step in range(8):
img = random_crop("../../docs/images/dog.jpg")
imgs.append(img)
imgs = np.array(imgs)
with LogWriter(logdir='./log/image_matrix_test/train') as writer:
# 合成长宽尽量接近的图形矩阵,本例生成3X3的矩阵
writer.add_image_matrix(tag='test_images', step=1, imgs=imgs, rows=-1)
# 合成长为1的图形矩阵,本例生成1x8的矩阵
writer.add_image_matrix(tag='test_images', step=2, imgs=imgs, rows=1)
# 合成长为2的图形矩阵,本例生成2X4的矩阵
writer.add_image_matrix(tag='test_images', step=3, imgs=imgs, rows=2)
# 合成长为3的图形矩阵,本例生成3X3的矩阵
writer.add_image_matrix(tag='test_images', step=4, imgs=imgs, rows=3)
# 合成长为4的图形矩阵,本例生成4X2的矩阵
writer.add_image_matrix(tag='test_images', step=5, imgs=imgs, rows=4)
```
运行上述程序后,在命令行执行
```shell
visualdl --logdir ./log --port 8080
```
在浏览器输入`http://127.0.0.1:8080`,即可查看图片数据。
<p align="center">
<img src="https://user-images.githubusercontent.com/28444161/104555348-ad63df80-5678-11eb-9d68-04f7f7451eac.png" width="40%"/>
<img src="https://user-images.githubusercontent.com/28444161/104556243-2dd71000-567a-11eb-9222-225b0acdf56b.png" width="40%"/>
</p>
## Audio--音频播放组件 ## Audio--音频播放组件
### 介绍 ### 介绍
......
# Copyright (c) 2020 VisualDL Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =======================================================================
import math
from functools import reduce
import numpy as np
from visualdl.component.base_component import convert_to_HWC
def padding_image(img, height, width):
height_old, width_old, _ = img.shape
height_before = math.floor((height - height_old) / 2)
height_after = height - height_old - height_before
width_before = math.floor((width - width_old) / 2)
width_after = width - width_old - width_before
return np.pad(img, ((height_before, height_after), (width_before, width_after), (0, 0)))
def merge_images(imgs, dataformats, scale=1.0, rows=-1):
assert rows <= len(imgs), "rows should not greater than numbers of pictures"
channel = imgs[0].shape[2]
# convert format of each image to `hwc`
for i, img in enumerate(imgs):
imgs[i] = convert_to_HWC(img, dataformats)
height = -1
width = -1
for img in imgs:
height = height if height > img.shape[0] else img.shape[0]
width = width if width > img.shape[1] else img.shape[1]
# padding every sub-image with height and width
for i, img in enumerate(imgs):
imgs[i] = padding_image(img, height, width)
# get row and col
len_imgs = len(imgs)
if -1 == rows:
rows = cols = math.floor(math.sqrt(len_imgs))
while rows*cols < len_imgs:
if rows <= cols:
rows += 1
else:
cols += 1
else:
cols = math.ceil(len_imgs/rows)
# add white sub-image
for i in range(rows*cols-len_imgs):
imgs = np.concatenate((imgs, np.zeros((height, width, channel), dtype=np.uint8)[None, :]))
imgs = reduce(lambda x, y: np.concatenate((x, y)), [
reduce(lambda x, y: np.concatenate((x, y), 1),
imgs[i * cols: (i + 1) * cols]) for i in range(rows)])
# choose bigger number of rows and cols
scale = 1.0/scale * rows if rows > cols else 1.0/scale * cols
dsize = tuple(map(lambda x: math.floor(x/scale), imgs.shape))[-2::-1]
try:
import cv2
imgs = cv2.resize(src=imgs, dsize=dsize)
except ImportError:
from PIL import Image
imgs = Image.fromarray(imgs)
imgs.resize(dsize)
imgs = np.array(imgs)
return imgs
...@@ -17,6 +17,7 @@ import os ...@@ -17,6 +17,7 @@ import os
import time import time
import numpy as np import numpy as np
from visualdl.writer.record_writer import RecordFileWriter from visualdl.writer.record_writer import RecordFileWriter
from visualdl.utils.img_util import merge_images
from visualdl.component.base_component import scalar, image, embedding, audio, histogram, pr_curve, roc_curve, meta_data from visualdl.component.base_component import scalar, image, embedding, audio, histogram, pr_curve, roc_curve, meta_data
...@@ -189,6 +190,36 @@ class LogWriter(object): ...@@ -189,6 +190,36 @@ class LogWriter(object):
image(tag=tag, image_array=img, step=step, walltime=walltime, image(tag=tag, image_array=img, step=step, walltime=walltime,
dataformats=dataformats)) dataformats=dataformats))
def add_image_matrix(self, tag, imgs, step, rows=-1, scale=1.0, walltime=None, dataformats="HWC"):
"""Add an image to vdl record file.
Args:
tag (string): Data identifier
imgs (np.ndarray): Image represented by a numpy.array
step (int): Step of image
rows (int): Number of rows, -1 means as close as possible to the square
scale (float): Image zoom scale
walltime (int): Wall time of image
dataformats (string): Format of image
Example:
from PIL import Image
import numpy as np
I = Image.open("./test.png")
I_array = np.array([I, I, I])
writer.add_image_matrix(tag="lll", imgs=I_array, step=0)
"""
if '%' in tag:
raise RuntimeError("% can't appear in tag!")
walltime = round(time.time() * 1000) if walltime is None else walltime
img = merge_images(imgs=imgs, dataformats=dataformats, scale=scale, rows=rows)
self.add_image(tag=tag,
img=img,
step=step,
walltime=walltime,
dataformats=dataformats)
def add_embeddings(self, tag, labels, hot_vectors, labels_meta=None, walltime=None): def add_embeddings(self, tag, labels, hot_vectors, labels_meta=None, walltime=None):
"""Add embeddings to vdl record file. """Add embeddings to vdl record file.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册