代码之家  ›  专栏  ›  技术社区  ›  Tom Kurushingal

如何使用python更改轮廓(从非python获得)中的颜色?

  •  0
  • Tom Kurushingal  · 技术社区  · 7 年前

    我正在尝试转换从非python应用程序生成的轮廓的颜色映射。我尝试使用Matthias Bussonnier's code available here ,但无法给我一个完整的转换。我试图截断颜色映射以进行完全转换,但又不能进行完全转换。

    mwe

    导入matplotlib.pyplot as plt 将numpy导入为np 将matplotlib.colors导入为颜色 将matplotlib.image导入为mpimg 从scipy.space导入目录树 导入Matplotlib 将matplotlib.cm导入为mplcm def truncate_colormap(cmap,minval=0.0,maxval=1.0,n=100): 新的_cmap=colors.linearSegmentedColormap.from_list( 'trunc(n,a:.2f,b:.2f),'格式(n=cmap.name,a=minval,b=maxval), CMAP(np.linspace(minval,maxval,n))) 返回新的_cmap cmap=plt.get_cmap('jet') cmap=截断颜色映射(cmap,0.1,0.9) img=mpimg.imread('./test.png')[:,:,:3] #@交互(sub=(0,500),d=(0,1,0.05) def convert(sub=256,d=0.1,cin=cmap,cout='viridis'): Viridis=plt.get_cmap(cout) jet=plt.get_cmap(cin) jet256=颜色。MakeMappingArray(Sub,Jet)[::,:3] K=CKD树(Jet256) oshape=img.形状 img_data=img.重塑((-1,3)) res=k.查询(img_data,距离_upper_bound=d) 指数=Res[1] L=长度(jet256) 索引=索引。重塑(oshape[:2]) 重新映射=索引 indexs.max()。 掩码=(索引==L) 重映射=重映射/(L-1) mask=np.stack([mask]*3,axis=-1) 混合=np.其中(mask,img,viridis(remapped)[:,:,:3]) 图,ax=plt.子批次()。 图设定高度(10) 图设置图宽度(10) ax.imshow(混合) Fig.saveFig('viridize.pdf') 转换()
    
    

    输入图像

    输出图像

    如何使用python将颜色映射(本例中为jet)完全转换为viridis?但是不能给我一个完整的转换。我试图截短颜色映射来给我一个完整的转换,但再次不能给我一个完整的转换。

    MWE

    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.colors as colors
    import matplotlib.image as mpimg
    from scipy.spatial import cKDTree
    import matplotlib
    
    
    import matplotlib.cm as mplcm
    
    def truncate_colormap(cmap, minval=0.0, maxval=1.0, n=100):
        new_cmap = colors.LinearSegmentedColormap.from_list(
            'trunc({n},{a:.2f},{b:.2f})'.format(n=cmap.name, a=minval, b=maxval),
            cmap(np.linspace(minval, maxval, n)))
        return new_cmap
    cmap = plt.get_cmap('jet')
    cmap = truncate_colormap(cmap, 0.1, 0.9)
    img = mpimg.imread('./test.png')[:,:,:3]
    
    #@interact(sub=(0, 500), d=(0,1,0.05))
    def convert(sub=256,d=0.1, cin=cmap, cout='viridis'):
        viridis = plt.get_cmap(cout)
        jet = plt.get_cmap(cin)
        jet256 = colors.makeMappingArray(sub, jet)[:, :3]
        K = cKDTree(jet256)
        oshape = img.shape
        img_data = img.reshape((-1,3))
        res = K.query(img_data, distance_upper_bound=d)
        indices = res[1]
        l = len(jet256)
        indices = indices.reshape(oshape[:2])
        remapped = indices
    
        indices.max()
    
        mask = (indices == l)
    
        remapped = remapped / (l-1)
        mask = np.stack( [mask]*3, axis=-1)
    
        blend = np.where(mask, img, viridis(remapped)[:,:,:3])
        fig, ax = plt.subplots()
        fig.set_figheight(10)
        fig.set_figwidth(10)
        ax.imshow(blend)
        fig.savefig('viridize.pdf')
    convert()    
    

    输入图像

    enter image description here

    输出图像

    enter image description here

    如何使用python将颜色映射(在本例中是jet)完全转换为viridis?

    1 回复  |  直到 7 年前
        1
  •  1
  •   ImportanceOfBeingErnest    7 年前

    如前所述,解决方案来自 how I can-specify-how-rainbow-color-scheme-should-be-converted-to-grayscale“>如何指定 会起作用,但需要做一些小的修改。

    也就是说,您需要将目标颜色映射应用于从该解决方案中选择的值,然后将生成的数组大小修改为3d。

    这项工作的条件是:

    • 您知道使用( origin_cmap )生成原始图像的颜色映射
    • 该图像中的所有颜色要么是灰度(轴、文本等),要么是该图像的一部分。也就是说,在图中不应该有任何其他的线图或类似的图。
    • 原始颜色映射是明确的,即不包含相同颜色两次。
    • 原始颜色映射的整个范围已用于创建输入图像,目标颜色映射的整个范围将针对。(如果需要,可以通过指定不同的 norm 和/或 r ange)来减弱这种情况。)

    因此,以下内容将“绿色化”给定图像。

    导入numpy as np 导入matplotlib.colors 将matplotlib.pyplot导入为plt image=plt.imread(“https://i.stack.imgur.com/nylq2.png”)。 def changecolormap(图像,原点,目标点): r=np.linspace(0,1,256) norm=matplotlib.colors.normalize(0,1) mapvals=原点cmap(norm(r))[:,:3] def从\cm(颜色)中获取\u值: color=matplotlib.colors.to_gb(颜色) #如果颜色已经是灰度,不要更改它 如果NP.标准(颜色)<0.1: 返回颜色 #否则从颜色映射返回值 距离=np.sum((贴图-颜色)**2,轴=1) 返回目标_cmap(r[np.argmin(距离)])[:3] newim=np.zeros_-like(图像) 对于范围内的i(image.shape[0]): 对于范围内的J(image.shape[1]): C=图像[I,J,:3] newim[i,j,:3]=从_cm(c)获取_值 返回newim 图(ax,ax2)=plt.子批次(ncols=2) ax.imshow(图像) ax2.imshow(更改颜色映射(图像,plt.cm.jet,plt.cm.viridis)) 轴线(“关”)。 ax2.轴(“关闭”) 请显示())

    会起作用,但需要做一些小的修改。

    也就是说,您需要将目标颜色映射应用于从该解决方案中选择的值,从而将生成的数组大小修改为3D。

    这项工作的条件是:

    • 你知道原始图像的彩色地图(origin_cmap)
    • 图像中的所有颜色要么是灰度(轴、文本等),要么是其中的一部分。原产地. 也就是说,在图中不应该有任何其他的线图或类似的图。
    • 原始颜色映射是明确的,即不包含相同的颜色两次。
    • 原始颜色映射的整个范围已用于创建输入图像,目标颜色映射的整个范围将针对。(如果需要,可以通过指定不同的norm和/或rANGE)

    因此,以下内容将“绿色化”给定图像。

    import numpy as np
    import matplotlib.colors
    import matplotlib.pyplot as plt
    
    image = plt.imread("https://i.stack.imgur.com/NyLq2.png")
    
    def changecolormap(image, origin_cmap, target_cmap):
        r = np.linspace(0,1, 256)
        norm = matplotlib.colors.Normalize(0,1)
        mapvals = origin_cmap(norm(r))[:,:3]
    
        def get_value_from_cm(color):
            color=matplotlib.colors.to_rgb(color)
            #if color is already gray scale, dont change it
            if np.std(color) < 0.1:
                return color
            #otherwise return value from colormap
            distance = np.sum((mapvals - color)**2, axis=1)
            return target_cmap(r[np.argmin(distance)])[:3]
    
        newim = np.zeros_like(image)
        for i in range(image.shape[0]):
            for j in range(image.shape[1]):
                c = image[i,j,:3]
                newim[i,j, :3] =  get_value_from_cm(c)
        return newim
    
    
    fig, (ax,ax2) = plt.subplots(ncols=2)
    ax.imshow(image)
    ax2.imshow(changecolormap(image, plt.cm.jet, plt.cm.viridis))
    
    ax.axis("off")
    ax2.axis("off")
    plt.show()
    

    enter image description here