打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
在数据坐标系中绘制无缩放图像

Bbox和BboxImage对象

Bbox是一个描述矩形区域的对象,BboxImage则是在Bbox中描绘图像的对象。下面是一个简单的例子:

import pylab as plfrom matplotlib.image import BboxImagefrom matplotlib.transforms import Bboxball_img = pl.imread("blue_ball.png")       ?ax = pl.subplot(111)bbox = Bbox.from_bounds(250, 200, 100, 150) ?bboximg = BboxImage(bbox, data=ball_img)    ?ax.add_artist(bboximg)                      ?pl.show()

调用pylab.imread()载入图像,得到的是一个形状为(图像高, 图像宽, 4)的三维数组,其中4为图像的通道数。?调用Bbox类的静态方法from_bounds()创建一个左下角坐标为(250,200)、宽100,高150的Bbox对象。?通过矩形区域bbox和图像数组ball_img创建一个BboxImage对象。?并通过add_artist()将BboxImage对象添加进子图对象的artist列表。下图是程序的输出结果:

请调整图表的大小,观察图像的位置变化。可以看出图像相对于窗口左下角的位置始终保持不变。因此可知Bbox对象所指定的矩形区域是相对于窗口坐标系的。在窗口坐标系中,窗口的左下角为坐标原点,X轴的正方向为右方,Y轴的正方向为上方,坐标值以像素为单位。

CenterPointBBox类

为了在数据坐标系定位图像的中心,我们需要编写一个BboxBase的派生类,完成坐标系转换工作:

from matplotlib.transforms import BboxBaseclass CenterPointBBox(BboxBase):    def __init__(self, x, y, transform, width, height):        self.center_x = x        self.center_y = y        self.image_width = width        self.image_height = height        self._transform = transform    def get_points(self):        x, y = self._transform.transform((self.center_x, self.center_y)) ?        w = self.image_width // 2        h = self.image_height //2        points = np.array([[x-w, y-h],[x-w+self.image_width, y-h+self.image_height]]) ?        return points

所有的Bbox类都从BboxBase继承,只需要重载其get_points()方法,返回一个格式如下的二维数组即可:

[[左下角X轴坐标, 左下角Y轴坐标], [右上角X轴坐标, 右上角Y轴坐标]]

CenterPointBBox类有5个参数,其中x和y是矩形区域的中心坐标,transform是将中点坐标转换到窗口坐标系的坐标转换对象。例如若(x,y)为数据坐标系中的坐标,那么transform就是将数据坐标系转换为窗口坐标系的对象。width和height是矩形区域的以像素为单位的宽和高。

在get_points()中,?通过坐标转换对象_transform的transform()方法,将坐标转换为窗口坐标。?计算矩形区域的左下角和右上角的坐标。

在数据坐标系中绘制图像

plot_image.py

用CenterPointBBox在数据坐标系中绘制图像

有了CenterPointBBox类,我们很容易写出在数据坐标系中一系列点上绘制图像的函数。

def plot_points_with_image(xs, ys, img):    ax = pl.gca()    for x, y in zip(xs, ys):        bbox = CenterPointBBox(x, y, ax.transData, img.shape[1], img.shape[0]) ?        imgbox = BboxImage(bbox)        imgbox.set_data(img)        ax.add_artist(imgbox)ball_img = pl.imread("blue_ball.png")ax = pl.subplot(111)xs = np.linspace(0, 2*np.pi, 100)ys = np.sin(xs)pl.plot(xs, ys, zorder=-1) ?plot_points_with_image(xs[::10], ys[::10], ball_img)pl.show()

注意图像的第1轴长度为宽度,而第0轴长度为高度。?为了让图像覆盖曲线,将曲线的zorder设置为-1。程序的输出如下图所示。

另外一种方案

还可以使用offsetbox模块中提供的AnnotationBbox和OffsetImage实现相同的功能。AnnotationBbox是一个标注框,其中可以放置任何Artist对象,我们在其中放置一个OffsetImage对象,它能按照指定的比例显示图像,缺省比例为1。关于这两个对象的各种参数,请读者查看相关文档及源代码。

plot_image2.py

用AnnotationBbox和OffsetImage在数据坐标系中绘制图像

import numpy as npfrom matplotlib.offsetbox import AnnotationBbox, OffsetImageimport pylab as pldef plot_points_with_image(xs, ys, img):    ax = pl.gca()    for x, y in zip(xs, ys):        imagebox = OffsetImage(img)        ab = AnnotationBbox(imagebox, (x, y),                            xycoords='data',                            frameon = False)        ax.add_artist(ab)xs = np.linspace(0, 2*np.pi, 100)ys = np.sin(xs)ax = pl.subplot(111)pl.plot(xs, ys, zorder=-1)ball_img = pl.imread("blue_ball.png")plot_points_with_image(xs[::10], ys[::10], ball_img)pl.show()
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
实战 | 巧用位姿解算实现单目相机测距
基于全景图像与激光点云配准的彩色点云生成算法(2014年文章)
4 共线方程
AI视觉,人脸识别实时跟踪监测,附python完整代码
基于三维人脸网格模型的二维人脸纹理贴图matlab仿真
从深度图到点云的构建方式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服