作者:韩信子@ShowMeAI

Python3◉技能提升系列https://www.showmeai.tech/tutorials/56

计算机视觉实战系列https://www.showmeai.tech/tutorials/46

本文地址https://www.showmeai.tech/article-detail/404

声明:版权所有,转载请联系平台与作者并注明出处

收藏ShowMeAI查看更多精彩内容

引言

我们本次用到的数据集是 Kaggle 100 种鸟数据集,大家可以通过 ShowMeAI 的百度网盘地址下载。

实战数据集下载(百度网盘):公众号『ShowMeAI研究中心』回复『实战』,或者点击 这里 获取本文 [39]使用Python构建图片颜色提取器Bird 450 Species数据集

ShowMeAI官方GitHubhttps://github.com/ShowMeAI-Hub

大家在做图像处理或者制作PPT时,一个非常常用的功能是颜色提取,我们可以通过提取器从已有图像的某个位置提取颜色,而不用自己肉眼比对和选择。今天ShowMeAI就带大家用python来实现这个功能。

我们会构建如下2个颜色提取器:

  • 简单提取器——从单个图像中选择颜色
  • 复杂提取器——从多个图像中选择颜色列表并显示颜色

本文的实现涉及python编程知识与部分数据可视化知识,大家可以通过ShowMeAI的以下教程和文章进行系统学习:

图解Python编程:从入门到精通系列教程

数据科学工具库速查表 | Matplotlib 速查表

颜色提取器实现

导入工具库

首先我们需要导入本次所需的工具库,matplotlib.image用于显示图像,pyperclip用于将字符串保存到剪贴板,glob用于处理文件路径。

#Imports
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg import pyperclip import random
import glob

我们将从不同的鸟类图像中提取颜色(即大家在第1节看到的图像)。我们读取路径下所有的jpg格式图像,代码如下:

#Dataset
read_path = "../../data/birds/"
img_path = glob.glob(read_path + "*.jpg")

简单颜色提取器实现

我们先实现一个简单颜色提取器。它的功能是,每次我们单击图像中的某个位置,该像素的 RGB 通道会保存到我们的剪贴板中,然后我们可以将该值粘贴到笔记本中。

我们先构建一个onclick函数,每次单击图像时都会运行此程序。我们获取点击的 x 和 y 坐标,然后得到该坐标处像素的 RGB 通道值,并将其作为字符串保存到剪贴板。完整的代码如下:

def onclick(event):
global img # get x,y of click
x = round(event.xdata)
y = round(event.ydata) # get RGB values
rgb = img[y][x] # save to clip board
pyperclip.copy(str(rgb))

我们要使用上面这个函数,我们首先使用 matplotlib 创建一个图形,然后设置该图的交互功能,将onclick函数作为参数传入,这样我们每次点击就会调用上述函数进行颜色提取。

%matplotlib notebook
global img fig = plt.figure(figsize=(5,5)) #Add an interactive widget to figure
cid = fig.canvas.mpl_connect('button_press_event', onclick) #Load image and add count
path = img_path[0]
img = mpimg.imread(path) plt.imshow(img)
plt.show()

注意:上述代码的第2行使用了全局变量,这样就可以在onclick函数中更新这些变量。

复杂颜色提取器实现

下面我们来构建一个复杂颜色提取器,它实现的功能如下图所示:我们多次点击不同图像的多个位置,我们会按照顺序编号和记录颜色(注意颜色框左上角的红色数字),并把颜色保存到列表中。

我们还是需要构建onclick函数,和之前的简单颜色提取器有点类似,这里的主要区别在于我们不直接保存 RGB 通道值,而是调用change_choice来调整右侧显示的提取颜色。

def onclick(event):
global img
global rgb # get x,y of click
x = round(event.xdata)
y = round(event.ydata) # get RGB values
rgb = img[y][x] #Update second plot with colour
change_choice()

我们再定义一个函数onpress,它会在按下键盘时运行。这个函数在按下了不同键的情况下做不同的处理:(change_imagechange_choice会分别用于更新图片和更新显示颜色框,在后续会定义)

  • n:运行change_image函数。
  • c:我们将 RGB 通道值保存到剪贴板和颜色列表中,接着运行change_choice函数。

具体代码实现如下:

def onpress(event):
global rgb
global colours #Get key
key = event.key if key == 'n':
change_image() elif key == 'c':
# save to clip board
pyperclip.copy(str(rgb)) # add to list of colours
colours.append(rgb) change_choice()

change_choice函数用于更新右侧颜色框。右侧的颜色框有与图像框相同的尺寸,并且根据当前全局 rgb 值进行颜色显示。

def change_choice():
global img
global ax
global colours
global rgb # remove previous count
for txt in ax[1].texts:
txt.set_visible(False) # create array of colour choice
dims = np.shape(img)
col = np.array([[rgb]*dims[0]]*dims[1])
ax[1].imshow(col) # update colour count
ax[1].text(0, 15, len(colours),color='r',size=20) plt.show()

change_choice函数在2处调用和执行:

  • 点击图片时调用的onclick函数中,它完成 全局 rgb 更新并调整框中的颜色。
  • 调用onpress函数并按下“c”时,这里颜色列表的长度+1,颜色计数也会改变。

接下来我们定义change_image函数。我们在按下“n”时会调用它更新图像框。代码如下:

def change_image():
global img_path
global img
global ax
global rgb # close all open plots
plt.close('all') fig,ax = plt.subplots(1,2,figsize=(10,5)) # add an interactive widget to figure
cid = fig.canvas.mpl_connect('button_press_event', onclick)
cid2 = fig.canvas.mpl_connect('key_press_event', onpress) # load random image
path = random.choice(img_path)
img = mpimg.imread(path) ax[0].imshow(img) # reset the colour window
rgb = [255,255,255]
change_choice()

我们可以通过运行change_image函数来启动颜色选择器,如下:

%matplotlib tk
global img_path
global colours
colours = [] # load image paths
read_path = "../../data/birds/"
img_path = glob.glob(read_path + "*.jpg") # start widget
change_image()

接下来当你就可以使用这个复杂颜色提取器啦,在您遍历图像并保存颜色时,颜色列表随之更更新,我们在下图的 colours 里可以看到提取的颜色构建的rgb值序列。

参考资料

推荐阅读

一定要用Photoshop?no!动手用Python做一个颜色提取器! ⛵的更多相关文章

  1. 用Python做一个知乎沙雕问题总结

    用Python做一个知乎沙雕问题总结 松鼠爱吃饼干2020-04-01 13:40 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以 ...

  2. 使用python做一个IRC在线下载器

    使用python做一个IRC在线下载器 1.开发流程 2.软件流程 3.开始 3.0 准备工作 3.1寻找API接口 3.2 文件模块 3.2.1 选择文件弹窗 3.2.2 提取文件名 3.2.2.1 ...

  3. 用python做youtube自动化下载器 代码

    目录 项目地址 思路 流程 1. post i. 先把post中的headers格式化 ii.然后把参数也格式化 iii. 最后再执行requests库的post请求 iv. 封装成一个函数 2. 调 ...

  4. 在树莓派上用 python 做一个炫酷的天气预报

    教大家如何在树莓派上自己动手做一个天气预报.此次教程需要大家有一定的python 基础,没有也没关系,文末我会放出我已写好的代码供大家下载. 首先在开始之前 需要申请高德地图API,去高德地图官网注册 ...

  5. 听歌识曲--用python实现一个音乐检索器

    听歌识曲,顾名思义,用设备"听"歌曲,然后它要告诉你这是首什么歌.而且十之八九它还得把这首歌给你播放出来.这样的功能在QQ音乐等应用上早就出现了.我们今天来自己动手做一个自己的听歌 ...

  6. 用python做一个搜索引擎(Pylucene)

    什么是搜索引擎? 搜索引擎是“对网络信息资源进行搜集整理并提供信息查询服务的系统,包括信息搜集.信息整理和用户查询三部分”.如图1是搜索引擎的一般结构,信息搜集模块从网络采集信息到网络信息库之中(一般 ...

  7. 媳妇儿喜欢玩某音中的动漫特效,那我就用python做一个图片转化软件。

    ​    最近某音上的动漫特效特别火,很多人都玩着动漫肖像,我媳妇儿也不例外.看着她这么喜欢这个特效,我决定做一个图片处理工具,这样媳妇儿的动漫头像就有着落了.编码    为了快速实现我们的目标,我们 ...

  8. 用Python做一个简单的翻译工具

    编程本身是跟年龄无关的一件事,不论你现在是十四五岁,还是四五十岁,如果你热爱它,并且愿意持续投入其中,必定会有所收获. 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过 ...

  9. [python]做一个简单爬虫

    为什么选择python,它强大的库可以让你专注在爬虫这一件事上而不是更底层的更繁杂的事 爬虫说简单很简单,说麻烦也很麻烦,完全取决于你的需求是什么以及你爬的网站所决定的,遇到的第一个简单的例子是pas ...

  10. python做一个数独小游戏

    最近看了下python的一些知识,在这里记载一下. 1.首先是安装,在官网下载最新的版本3.6,安装的时候要注意在下面勾选上ADD TO PATH,安装的时候会自动写入到环境变量里面,如果没有勾选,可 ...

随机推荐

  1. K8s 上的分布式存储集群搭建(Rook/ceph)

    转载自:https://mp.weixin.qq.com/s/CdLioTzU4oWI688lqYKXUQ 1 环境准备 1.1 基础环境 3台配置一致的虚拟机 虚拟机配置:4c 8g 虚拟机操作系统 ...

  2. DirectPV-----文章内容有待进一步实践完善

    GitHub文档地址:https://github.com/minio/directpv DirectPV是用于直连存储的CSI驱动程序.从更简单的意义上讲,它是一个分布式持久卷管理器,而不是像SAN ...

  3. Leetcode链表

    Leetcode链表 一.闲聊 边学边刷的--慢慢写慢慢更 二.题目 1.移除链表元素 题干: 思路: 删除链表节点,就多了一个判断等值. 由于是单向链表,所以要删除节点时要找到目标节点的上一个节点, ...

  4. 编写一个应用程序,在主类Test1类中,创建两个链表List<E>对象,分别存储通过键盘输入的字符串内容

    题目1:编写一个应用程序,在主类Test1类中,创建两个链表List<E>对象,分别存储通过键盘输入的字符串内容--"chen","wang",&q ...

  5. .Net CLR GC plan_phase二叉树和Brick_table

    楔子 别那么懒,勤快点.以下取自CLR PreView 7.0. 主题 GC计划阶段(plan_phase)主要就两个部分,一个是堆里面的对象构建一颗二叉树(这颗二叉树的每个节点包含了诸如对象移动信息 ...

  6. IPv4 与 IPv6的区别

    在介绍 IPv4 到 IPv6 区别之前,我们先来简单了解一下 IPv4 和 IPv6. IPv4 网际协议版本4(英语:Internet Protocol version 4,IPv4),又称互联网 ...

  7. bat批处理命令语法总结

    ::1. 关闭回显表示不显示命令本身只显示输出部分 @echo off ::2. 设置变量注意等号间不能有空格 set num=10 ::3. 使用变量 echo %num% ::4. call 调用 ...

  8. 拉格朗日插值优化DP

    拉格朗日插值优化DP 模拟赛出现神秘插值,太难啦!! 回忆拉格朗日插值是用来做什么的 对于一个多项式\(F(x)\),如果已知它的次数为\(m - 1\),且已知\(m\)个点值,那么可以得到 \[F ...

  9. Docker_基础知识

    容器概述 容器本义:盛装物体.隔离物体. 容器意义:解决虚拟化资源浪费的问题. 容器沿革:1979---2013---                     版本:企业版(EE)/社区版(CE)1. ...

  10. JVM中的堆

    堆 内存结构 堆的核心概念 <java虚拟机规范>中对java堆的描述是:所有的对象实例以及数组都应当在运行时分配在堆上. 一个JVM实例只存在一个堆内存(就是new 出来一个对象),ja ...