Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种使用Python生成渐变位图的简单方法?_Python_Image_Matplotlib_Graphviz - Fatal编程技术网

有没有一种使用Python生成渐变位图的简单方法?

有没有一种使用Python生成渐变位图的简单方法?,python,image,matplotlib,graphviz,Python,Image,Matplotlib,Graphviz,我正在生成一个简单的、基于Python的程序,该程序生成graphviz图形作为输出。我想使用自定义节点来描述程序中的数据。一旦有了图像,使用自定义节点就足够简单了,但是我很难找到一种方便的方法来生成我想要的图像 具体来说,我希望节点是圆,其面积表示测量值,但梯度表示该值的不确定性。使用一些数学程序(例如)生成的等高线图似乎是合理的,但这些程序往往会生成未缩放的方形图像。或者,图像处理程序上的梯度函数似乎很难与严格的高斯函数相关联 理想情况下,我想按照伪代码的思路编写一个函数 def make_

我正在生成一个简单的、基于Python的程序,该程序生成graphviz图形作为输出。我想使用自定义节点来描述程序中的数据。一旦有了图像,使用自定义节点就足够简单了,但是我很难找到一种方便的方法来生成我想要的图像

具体来说,我希望节点是圆,其面积表示测量值,但梯度表示该值的不确定性。使用一些数学程序(例如)生成的等高线图似乎是合理的,但这些程序往往会生成未缩放的方形图像。或者,图像处理程序上的梯度函数似乎很难与严格的高斯函数相关联

理想情况下,我想按照伪代码的思路编写一个函数

def make_node_image(measured_value, std_dev):

    mean_circle_radius = sqrt(measured_value/pi)
    image_circle_radius = sqrt((measured_value + 2*std_dev)/pi)

    gradient_amplitude = 1/(std_dev*sqrt(2*pi))
    gradient_fade = e^(-(r-mean_circle_radius)^2/(2*std_dev^2))

    image_gradient = gradient_amplitude*gradient_fade

    ***generate_image_from_gradient***

    ***scale_and_clip_image_to_image_circle_radius***

    return image

这两个星号是我需要帮助的地方;如果有任何建议,我将不胜感激,谢谢

实现这一点的一种方法是使用
matplotlib
,正如您在标记中所建议的那样。要做到这一点,我会

  • 使用numpy创建一个NxN数组来表示
    图像\u梯度
  • 创建一个正方形的
    图形
    ,其大小以英寸为单位与圆的半径相关(
    image\u circle\u radius
    ),您需要记住图形的每英寸点数(
    fig.dpi
  • 创建一个无边距、无边框和无记号的轴(
    fig.add_轴([0,0,1,1],frameon=False,xticks=[],yticks=[])
  • 使用
    imshow
    将阵列绘制为图像
  • 创建一个圆,圆心和半径以DPI为单位
  • 使用
    set\u clip\u path()
    方法剪裁由
    imshow
    调用创建的
    AxesImage
  • 这种方法的灵感来自于一种新的方法

    下面是一个尝试,尝试执行以下操作:

    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.path as path
    import matplotlib.patches as patches
    
    pi = np.pi
    sqrt = np.sqrt
    exp = np.exp
    
    def make_node_image(measured_value, std_dev, coverage="0.96",imageID=1):
    
        DPI = 100
        TODPI=1
        MINSIZE = 50 # in DPI
        MAXSIZE = 400 # in DPI
        MAXAMPLITUDE = .005
    
        # make radius,std_dev  values in grid units
        mean_circle_radius = int(sqrt(measured_value/pi)/TODPI)
        image_circle_radius = int(sqrt((measured_value + 2*std_dev)/pi)/TODPI)
        if image_circle_radius < MINSIZE:
            raise Exception("image_circle_radius too small!")
        if image_circle_radius > MAXSIZE:
            raise Exception("image_circle_radius too large!")
    
        grid_std_dev = std_dev/TODPI
    
        gradient_amplitude = 1/(std_dev*sqrt(2*pi))/MAXAMPLITUDE
        gradient_fade = np.zeros([2*image_circle_radius,
                                  2*image_circle_radius])
        for ix in range(2*image_circle_radius):
            for iy in range(2*image_circle_radius):
                r = sqrt((ix-image_circle_radius)**2
                         +(iy-image_circle_radius)**2)
                gradient_fade[ix,iy] = exp(
                    -(r-mean_circle_radius)**2
                     /(2*grid_std_dev**2))
    
        image_gradient = gradient_amplitude*gradient_fade
    
        fig = plt.figure(figsize=(2*image_circle_radius/DPI,
                                  2*image_circle_radius/DPI),dpi=DPI)
    
    
        ax = fig.add_axes([0,0,1,1],frameon=True, xticks=[], yticks=[])
    
        #***generate_image_from_gradient***
        im = ax.imshow(image_gradient,vmin=0,vmax=1)
    
        patch = patches.Circle((image_circle_radius,image_circle_radius), 
                               radius=image_circle_radius,fc='white')
    
        #***scale_and_clip_image_to_image_circle_radius***
        im.set_clip_path(patch)
    
        name = 'circImage%d.png'%imageID
        fig.savefig(name)
    
        return name
    
    make_node_image(90000*pi,100)
    
    将numpy导入为np
    将matplotlib.pyplot作为plt导入
    将matplotlib.path导入为路径
    将matplotlib.patches导入为修补程序
    pi=np.pi
    sqrt=np.sqrt
    exp=np.exp
    def生成节点图像(测量值,标准偏差,覆盖率=“0.96”,图像ID=1):
    DPI=100
    TODPI=1
    MINSIZE=50(以DPI为单位)
    最大尺寸=400英寸DPI
    最大振幅=.005
    #以网格单位生成半径、标准偏差值
    平均圆半径=int(sqrt(测量值/pi)/TODPI)
    图像圆半径=整数(sqrt((测量值+2*std\U dev)/pi)/TODPI)
    如果图像\圆\半径<最小尺寸:
    引发异常(“图像\圆\半径太小!”)
    如果图像\圆\半径>最大尺寸:
    引发异常(“图像\圆\半径太大!”)
    网格标准偏差=标准偏差/TODPI
    梯度振幅=1/(标准偏差*sqrt(2*pi))/MaxAmpliance
    渐变淡入=np.零([2*图像\圆\半径,
    2*图像(圆(半径)])
    对于范围内的ix(2*图像\圆\半径):
    对于范围内的iy(2*图像\圆\半径):
    r=sqrt((ix-图像\圆\半径)**2
    +(iy-image_圆_半径)**2)
    梯度衰减[ix,iy]=exp(
    -(r-平均圆半径)**2
    /(2*电网标准开发**2)
    图像梯度=梯度振幅*梯度衰减
    图=plt.图(图尺寸=(2*图像、圆、半径/DPI),
    2*图像\圆\半径/DPI),DPI=DPI)
    ax=fig.add_轴([0,0,1,1],frameon=True,xticks=[],yticks=[]))
    #***从梯度生成图像***
    im=ax.imshow(图像梯度,vmin=0,vmax=1)
    面片=面片圆((图像圆半径,图像圆半径),
    半径=图像\圆\半径,fc='白色')
    #***缩放和剪裁图像到圆半径***
    im.设置剪辑路径(补丁)
    名称='circImage%d.png'%imageID
    图savefig(名称)
    返回名称
    制作节点图像(90000*pi,100)
    
    这导致:

  • 圆圈的边缘似乎被剪掉了
  • 几乎可以肯定,这是一种矢量化的方法来构建
    渐变_fade
    ,尽管我不知道它是什么
  • 这让人觉得很尴尬,我真的希望有人能提供一个更优雅的答案
  • 显然,上面的代码只是一个起点,有人肯定可以改进它

  • 我在下面提供了一个答案,但我没有得到参数
    覆盖率
    的要点,以及
    r
    小于
    平均圆半径
    的值会发生什么情况。如果我不了解这些要点,我可能错过了最终结果,但我想我得到了您希望的要点。您非常善于观察t、 覆盖率参数最初旨在限制图像半径,但更容易仅在两个标准偏差处切断边界。测量值是物体的质量,因此不能为负。质量测量的概率分布函数不是严格的高斯分布,但不足以确定在这个程序中需要寻址。密度函数在零以下的“尾部”可以用几种方式寻址,但这对我的问题并不重要。这是一个很好的开始,谢谢!我使用了matploblib,但主要是作为python(x,y)的后端,我不太擅长直接使用它。