分类目录归档:工具

Python 批量修改图片亮度和饱和度

在Photoshop里也可以做到批量修改图片的亮度和饱和度,但是很多人都没有条件使用Photoshop,此外,Photoshop里的批量修改其实很耗性能,而且使用起来并不是很方便。

那我们能不能用Python做一个小工具,先找到合适的亮度和饱和度,然后再根据这个指定的值对所有需要做相似调整的图片做批量修改呢?答案是肯定的。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal). 输入以下命令安装我们所需要的模块:

pip install numpy
pip install opencv-python

看到 Successfully installed xxx 则说明安装成功。

2.开发调整工具

这一部分,我们将开发出一个能够调整图像亮度和饱和度的工具,而且这个工具支持滑动调整。其实放到别的语言里,这可是个小工程,但是放到Python里,我们用50行代码就能解决了。

首先是加载图片,然后需要将图片转化为HLS模式才能够调整亮度和饱和度。这是因为默认的图片颜色空间是RGB,它非常适合显示器显示,但由于只有三个颜色分类,并不适合图像处理。而HLS模式相对于RGB颜色空间则复杂得多,HLS分别代表H: Hue(色调),L: Lightness(亮度), S: Saturation(饱和度)。

其颜色空间是一个三维空间,如下图所示:

这样的颜色空间才使得我们可以调整图片的细节部分。Python代码中,将RGB转化为HLS空间是很简单的,两行代码就能做到:

import numpy as np
import cv2

# 加载图片 读取彩色图像归一化且转换为浮点型
image = cv2.imread('2.jpg', cv2.IMREAD_COLOR).astype(np.float32) / 255.0

# 颜色空间转换 BGR转为HLS
hlsImg = cv2.cvtColor(image, cv2.COLOR_BGR2HLS)

然后我们需要做两个滑动块,一个调节亮度,一个调节饱和度:

# 滑动条最大值
MAX_VALUE = 100
# 滑动条最小值
MIN_VALUE = 0

# 调节饱和度和亮度的窗口
cv2.namedWindow("lightness and saturation", cv2.WINDOW_GUI_NORMAL)

# 创建滑动块
cv2.createTrackbar("lightness", "lightness and saturation", MIN_VALUE, MAX_VALUE, lambda x:x)
cv2.createTrackbar("saturation", "lightness and saturation", MIN_VALUE, MAX_VALUE, lambda x:x)

调节前还需要保存一下原图,所以我们会在内存里复制一个新的变量用于调节图片,然后获得两个滑动块的值,再根据值进行亮度和饱和度的调整:

# 调整饱和度和亮度
while True:
    # 复制原图
    hlsCopy = np.copy(hlsImg)
    # 得到 lightness 和 saturation 的值
    lightness = cv2.getTrackbarPos('lightness', 'lightness and saturation')
    saturation = cv2.getTrackbarPos('saturation', 'lightness and saturation')
    # 1.调整亮度(线性变换)
    hlsCopy[:, :, 1] = (1.0 + lightness / float(MAX_VALUE)) * hlsCopy[:, :, 1]
    hlsCopy[:, :, 1][hlsCopy[:, :, 1] > 1] = 1
    # 饱和度
    hlsCopy[:, :, 2] = (1.0 + saturation / float(MAX_VALUE)) * hlsCopy[:, :, 2]
    hlsCopy[:, :, 2][hlsCopy[:, :, 2] > 1] = 1
    # HLS2BGR
    lsImg = cv2.cvtColor(hlsCopy, cv2.COLOR_HLS2BGR)
    # 显示调整后的效果
    cv2.imshow("lightness and saturation", lsImg)

效果如下图所示:

到这里还不够,由于是while循环支持的调节,我们还需要让其可以退出和保存:

    ch = cv2.waitKey(5)
    # 按 ESC 键退出
    if ch == 27:
        break
    elif ch == ord('s'):
        # 按 s 键保存并退出
        lsImg = lsImg * 255
        lsImg = lsImg.astype(np.uint8)
        cv2.imwrite("lsImg.jpg", lsImg)
        break

这样,按s键可以保存图片并退出,按ESC键可以直接退出编辑器。 完整文字版50行代码请在Python实用宝典公众号后台回复:批量修改图片 获得。

3.批量修改

前面根据我们的小工具获得了需要的饱和度和亮度,把这对值记下来就可以批量修改图片了。当然,我们没有自动批量修改到正确值这么逆天的功能,这个工具只适合相同场景下,能够用同一对亮度和饱和度进行调整的图片:

def update(input_img_path, output_img_path, lightness, saturation):
    """
    用于修改图片的亮度和饱和度
    :param input_img_path: 图片路径
    :param output_img_path: 输出图片路径
    :param lightness: 亮度
    :param saturation: 饱和度
    """

    # 加载图片 读取彩色图像归一化且转换为浮点型
    image = cv2.imread(input_img_path, cv2.IMREAD_COLOR).astype(np.float32) / 255.0

    # 颜色空间转换 BGR转为HLS
    hlsImg = cv2.cvtColor(image, cv2.COLOR_BGR2HLS)

    # 1.调整亮度(线性变换)
    hlsImg[:, :, 1] = (1.0 + lightness / float(MAX_VALUE)) * hlsImg[:, :, 1]
    hlsImg[:, :, 1][hlsImg[:, :, 1] > 1] = 1
    # 饱和度
    hlsImg[:, :, 2] = (1.0 + saturation / float(MAX_VALUE)) * hlsImg[:, :, 2]
    hlsImg[:, :, 2][hlsImg[:, :, 2] > 1] = 1
    # HLS2BGR
    lsImg = cv2.cvtColor(hlsImg, cv2.COLOR_HLS2BGR) * 255
    lsImg = lsImg.astype(np.uint8)
    cv2.imwrite(output_img_path, lsImg)

这部分其实比制作刚刚的工具简单,可以说是工具的简化版。分为以下六个步骤:

1.加载图片。
2.转化为HLS空间。
3.调整亮度。
4.调整饱和度。
5.转化为RGB空间。
6.保存。

然后我们只需要批量地将图片传入该函数,就能实现批量转化:

dataset_dir = 'imgs'
output_dir = 'output'
lightness = 10
saturation = 20

# 获得需要转化的图片路径, 并生成目标路径
image_filenames = [(os.path.join(dataset_dir, x), os.path.join(output_dir, x))
                    for x in os.listdir(dataset_dir)]
# 转化所有图片
for path in image_filenames:
    update(path[0], path[1], lightness, saturation)

通过这份Python代码,你能在1分钟内修改几千张图片,这样的效率并非Photoshop能比的。当然,它也有它的缺点,那就是只能根据你输入的值进行修改,而Photoshop能够进行自动优化(虽然精度评价因人而异)。

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 强大的模式匹配工具—Pampy

在自然语言处理界,模式匹配可以说是最常用的技术。甚至可以说,将NLP技术作为真实生产力的项目都少不了模式匹配

什么是模式匹配呢?在计算机科学中,往往是检查给定的序列或字符串中是否有符合某种模式的片段。比如说:“啊,你的AK-47打得真准”,如果我们将 “啊,你的_____打得真准 ” 作为一种模式,则会将AK-47匹配出来。

实现模式匹配往往都是用正则表达式,但是如果你想识别特别复杂的模式,编写正则表达式就会变得非常非常麻烦。而Pampy这个项目能解决你不少的烦恼。

pampy使用例子

1.安装

赶紧让我们来试一下,安装Pampy前,你要确保Python和pip已经成功安装在电脑上噢,如果没有,请访问这篇文章:超详细Python安装指南

打开Cmd(开始—运行—CMD)或Terminal(command+空格输入Terminal). 输入以下命令安装Pampy:

pip install pampy

看到 Successfully installed pampy-0.3.0 则说明安装成功。

2.使用

特性1: HEAD 和 TAIL

HEAD和TAIL能代表某个模式的前面部分或后面部分。

比如将特定模式后的元素都变成元组:

from pampy import match, HEAD, TAIL, _

x = [-1, -2, -3, 0, 1, 2, 3]

print(match(x, [-1, TAIL], lambda t: [-1, tuple(t)]))
# => [-1, (-2, -3, 0, 1, 2, 3)] 

将特定模式前的元素设为集合,后面的元素设为元组:

from pampy import match, HEAD, TAIL, _

x = [-1, -2, -3, 0, 1, 2, 3]

print(match(x, [HEAD, _, _, 0, TAIL], lambda h, a, b, t: (set([h, a, b]), tuple(t))))
# => ({-3, -1, -2}, (1, 2, 3)) 

特性2:甚至能匹配字典中的键

在你不知道哪个键下有某个值的时候,这招非常好用:

from pampy import match, HEAD, TAIL, _
my_dict = {
    'global_setting': [1, 3, 3],
    'user_setting': {
        'face': ['beautiful', 'ugly'],
        'mind': ['smart', 'stupid']
    }
}
result = match(my_dict, { _: {'face': _}}, lambda key, son_value: (key, son_value))
print(result)
# => ('user_setting', ['beautiful', 'ugly']) 

特性3: 搭配正则

不仅如此,它还能搭配正则一起使用哦:

import re
from pampy import match, HEAD, TAIL, _
def what_is(pet):
    return match(pet,
        re.compile('(\w+),(\w)\w+鳕鱼$'),     lambda mygod, you: you + "像鳕鱼",
    )

print(what_is('我的天,你长得真像鳕鱼'))     # => '你像鳕鱼' 

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

开工第一天,先用Python戴个口罩

Python实用宝典终于复工啦(我咸鱼够了)!这些天,令人揪心的肺炎疫情一直闹得沸沸扬扬,口罩也被抢得断货,许多网友朋友们都只能开始给自己的头像戴口罩了(也挺好,为疫区省点医疗物资)

有个朋友(Prodesire)一早就预料到有这种情况,因此ta开发了一个工具,能让大家用一行语句就成功戴上口罩!

1.准备

老规矩,在开工前一定要安装好Python,如果还没安装请看这篇文章:超详细Python安装教程。安装完Python后我们就可以安装Prodesire开发的一个叫做face-mask的模块。

如果你是windows机器,请在 开始—运行 中输入cmd,执行
pip install face-mask

如果你是macOS机器,请command+空格,输入Terminal打开终端,执行
pip install face-mask

如果出现:CMake must be installed to build the following extensions: dlib 这样的错误,请先安装cmake:
pip install cmake

2.使用

同样地,打开cmd或终端,输入以下命令,就能在该图片的当前文件夹下生成一张戴着口罩的图片:

face-mask 该图片路径

比如说宽叔的这张图片:

输入命令 face-mask Downloads/2.jpg 即可生成戴口罩的图片:

类似的还有很多哦:

就不给大家一一尝试啦,总而言之,有基本脸部表情的,都可以戴的上这个口罩!

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python pandas高效数据处理之绘图

Pandas是Python中非常常用的数据处理工具,使用起来非常方便。它建立在NumPy数组结构之上,所以它的很多操作通过NumPy或者Pandas自带的扩展模块编写,这些模块用Cython编写并编译到C,并且在C上执行,因此也保证了处理速度。

今天我们就来体验一下它的强大之处。

1.创建数据

使用pandas可以很方便地进行数据创建,现在让我们创建一个5列1000行的pandas DataFrame:

mu1, sigma1 = 0, 0.1
mu2, sigma2 = 0.2, 0.2
n = 1000df = pd.DataFrame(
    {
        "a1": pd.np.random.normal(mu1, sigma1, n),
        "a2": pd.np.random.normal(mu2, sigma2, n),
        "a3": pd.np.random.randint(0, 5, n),
        "y1": pd.np.logspace(0, 1, num=n),
        "y2": pd.np.random.randint(0, 2, n),
    }
)
  • a1和a2:从正态(高斯)分布中抽取的随机样本。
  • a3:0到4中的随机整数。
  • y1:从0到1的对数刻度均匀分布。
  • y2:0到1中的随机整数。

生成如下所示的数据:

2.绘制图像

Pandas 绘图函数返回一个matplotlib的坐标轴(Axes),所以我们可以在上面自定义绘制我们所需要的内容。比如说画一条垂线和平行线。这将非常有利于我们:

1.绘制平均线

2.标记重点的点

import matplotlib.pyplot as plt
ax = df.y1.plot()
ax.axhline(6, color="red", linestyle="--")
ax.axvline(775, color="red", linestyle="--")
plt.show()

我们还可以自定义一张图上显示多少个表:

fig, ax = plt.subplots(2, 2, figsize=(14,7))
df.plot(x="index", y="y1", ax=ax[0, 0])
df.plot.scatter(x="index", y="y2", ax=ax[0, 1])
df.plot.scatter(x="index", y="a3", ax=ax[1, 0])
df.plot(x="index", y="a1", ax=ax[1, 1])
plt.show()

3.绘制直方图

Pandas能够让我们用非常简单的方式获得两个图形的形状对比:

df[["a1", "a2"]].plot(bins=30, kind="hist")
plt.show()

还能允许多图绘制:

df[["a1", "a2"]].plot(bins=30, kind="hist", subplots=True)
plt.show()

当然,生成折线图也不在画下:

df[['a1', 'a2']].plot(by=df.y2, subplots=True)
plt.show()

4.线性拟合

Pandas还能用于拟合,让我们用pandas找出一条与下图最接近的直线:

最小二乘法计算和该直线最短距离:

df['ones'] = pd.np.ones(len(df))
m, c = pd.np.linalg.lstsq(df[['index', 'ones']], df['y1'], rcond=None)[0]

根据最小二乘的结果绘制y和拟合出来的直线:

df['y'] = df['index'].apply(lambda x: x * m + c)
df[['y', 'y1']].plot()
plt.show()

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 球队进球得分自动提醒

英超的比赛很多都会在当地时间周末的晚上举行,而很不巧这个时间在中国是凌晨4点左右,对中国观众非常不友好。或者有的时候是中国时间晚上8点或晚上10点开始,但是我们并不一定有时间看。

这些情况下如果你想查看比分,还得打开某个软件,点击国际足球——赛事——积分榜,非常麻烦。今天用Python告诉你怎样在你支持的足球队得分时给你发送短信,如果你原意,可以不编写任何代码哦!

1.准备

今天只在本地做部署和测试,实际上当项目运行起来的时候,应该是放在服务器上的,毕竟本地机器不太适合全天24小时开着嘛。

1.首先,你需要下载Python3环境,如果你还没下载,可以参考这篇文章:超详细Python下载安装指南

2.其次,你需要克隆一个名为footballNotifier的仓
https://github.com/carlos-menezes/footballNotifier

3.打开CMD或Terminal, 输入以下命令安装依赖:
pip install -r requirements.txt

2.配置你的主队

这一步,需要打开仓里的config.ini:

1.在Number处填入你的手机号,在TEAM处填入你的主队
如:Arsenal 阿森纳等。请注意要填写英文。

2.前往TextLocal注册一个短信发送账号:
https://www.textlocal.com/
邮箱验证后才能设置账号密码。

3.在下面的链接创建一个API_KEY
https://control.txtlocal.co.uk/settings/apikeys/

不需要填IP,直接保存。然后会刷新到上个页面,你能看到一个秘钥,复制这串秘钥,并相应填写到config.init中的API_KEY里:

配置完成后,在cmd或Terminal中输入以下命令就可以开始监控比分啦:
python app.py

3.源码分析

其实这个仓一共就两个文件,一个是scrapegoals.py,用于抓取实时的赛事结果,其实是一个非常简单的爬虫

还有一个是app.py,是程序的入口点,也就做两个事:

1.获取赛事结果。
2.如果是目标队伍进球,那就调用短信API发送短信。
#用While循环保持监控进程

其实是非常简单的一个开源项目,大家有兴趣可以自己做一个国内版的,并不复杂。

自动通知系列文章:

教你如何使用Python向手机发送通知(IFTTT)

Python 自动发送邮件详细教程

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 9行代码批量翻转壁纸的惊喜

今天在欣赏一些新的手机壁纸的时候,不小心把手机拿反了,但是却因此偶然看到了非常有特色的图片。因此突然有了推送的灵感——用Python批量翻转图片

其实原理很简单,用九行代码就能完成我们所需要的功能。

1.准备

为了能够翻转图片,我们需要先安装好PIL,也就是pillow,在CMD/Terminal输入:

pip install pillow

请记得先安装Python,才能够pip,如果你还没有安装Python,请看这篇文章: 超详细Python安装指南

2.编程

仅需要3个步骤:

1.获得图片文件夹下所有文件名

2.迭代所有图片

3.翻转保存到指定文件夹

#-*- coding: UTF-8 -*- 

from PIL import Image
import os

# 获得文件夹下所有文件
filePath = './imgs/'
filenames = os.listdir(filePath)

# 指定保存的文件夹
outputPath = './imgs_rotate/'

# 迭代所有图片
for filename in filenames:
    # 读取图像
    im = Image.open(filePath + filename)

    # 指定逆时针旋转的角度
    im_rotate = im.rotate(180)
    
    # 保存图像
    im_rotate.save(outputPath + filename) 

3.效果

嘻嘻,其实也是相当于壁纸分享了,当然,微信公众号会有压缩的现象,大家如果想下载原图请点击下方阅读原文,或者关注文章最下方Python实用宝典公众号,回复 翻转壁纸

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Python 监控文件增加、修改、删除等变化

现在有一个应用场景,需要对文件系统进行监控,发生变化时产生日志,对新增的文件做一些相应的操作。比如说应用到我们之前的高潮提取器:若当前文件夹下增加了一个音乐文件,监控器就调用高潮提取器提取该音乐文件的高潮部分。

这样的监控器写起来也不难,但是很花时间,有许多情况要考虑。不过幸好我们是写Python的,有许多轮子可以使用。

1.安装”看门狗”

“看门狗”模块就是用于监控文件事件变化的一个Python”轮子”,代码架构优秀,可以注册许多事件处理器,方便用户做自定义操作。如果你还没有安装Python,请看这篇文章《Python详细安装指南》,在终端输入以下命令即可安装看门狗:

pip install watchdog

2.基本使用

看门狗的使用其实不复杂,请认真看以下代码和注释:

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'

    # 生成事件处理器对象
    event_handler = LoggingEventHandler()

    # 生成监控器对象
    observer = Observer()
    # 注册事件处理器,配置监控目录
    observer.schedule(event_handler, path, recursive=True)
    # 监控器启动——创建线程
    observer.start()

    # 以下代码是为了保持主线程运行
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()

    # 主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止
    observer.join()

可以看到代码中有几个关键步骤,1.配置各项信息;2.生成事件处理器、监控器;3.注册事件处理器、配置目录、递归执行(即同时监控子文件夹);4.启动。

其实,看门狗的observer是基于 threading.Thread 对象的,所以observer很多属性都继承了 threading.Thread 的属性。

如果你不带参数地运行该脚本,就是要监控脚本文件所在的文件夹,如果要监控其他文件夹,记得运行时带文件夹的路径参数,如:

python obserber.py /data/home/ckend/

我们来试着运行看看:

可以看到,我在当前文件夹下做的所有操作都被记录下来了。接下来我们就试试怎么自定义一些操作。

3.监控提取音乐高潮

如果你不知道怎么提取音乐文件的高潮部分,请看这篇文章:《Python自动提取音乐文件高潮》

要实现这样的功能,我们有几种方法,一个是在原来log的处理器上做一些新增修改,比如多增一个函数调用音乐高潮提取器。第二个是重新继承 FileSystemEventHandler 类,并做相应的修改。这里我们还是要保留log的样式,只是在log的时候顺便提取音乐高潮,因此采用第一个方法。

看看LoggingEventHandler源代码中的on_created,这就是当文件创建时监控器的操作:

class LoggingEventHandler(FileSystemEventHandler):
    """Logs all the events captured."""

    # ...省略其他源代码...

    def on_created(self, event):
        super(LoggingEventHandler, self).on_created(event)

        what = 'directory' if event.is_directory else 'file'
        logging.info("Created %s: %s", what, event.src_path)

我们仅需要继承这个类并对on_created进行修改,就能完成我们想要的功能:

# Python实用宝典
# 2019/12/29

import sys
import time
import logging
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler
from pychorus import find_and_output_chorus


class extractor(LoggingEventHandler):

    def on_created(self, event):
        super(LoggingEventHandler, self).on_created(event)
        what = 'directory' if event.is_directory else 'file'
        logging.info("Created %s: %s", what, event.src_path)
        NameExt = event.src_path.split('.')
        if NameExt[-1] == 'mp3':
            logging.info("mp3文件, 提取音乐高潮中...")
            output_path = "."+"".join(NameExt[:-1])+'_high.wav'
            find_and_output_chorus(event.src_path, output_path, 30)


if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    path = sys.argv[1] if len(sys.argv) > 1 else '.'

    # 生成事件处理器对象
    event_handler = extractor()

    # 生成监控器对象
    observer = Observer()
    # 注册事件处理器
    observer.schedule(event_handler, path, recursive=True)
    # 监控器启动——创建线程
    observer.start()

    # 以下代码是为了保持主线程运行
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()

    # 主线程任务结束之后,进入阻塞状态,一直等待其他的子线程执行结束之后,主线程再终止
    observer.join() 

首先声明一个类,继承LoggingEventHandler,然后重载on_created函数,在这个函数中不仅记录文件事件变化,还要对mp3文件做一次音乐高潮提取。最后别忘了,生成事件处理器时要用我们新的类名。

看看效果,将小永远.mp3复制过来:

成功监控文件变化并提取到音乐高潮,生成高潮文件。

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

庆祝胖五发射成功, 来用Python发射火箭!

今天看到了一则可喜可贺的消息:长征五号遥三运载火箭在中国文昌航天发射场点火升空,与实践二十号卫星成功分离,任务取得圆满成功。 真是令人自豪,为这些辛苦工作的航天人喝彩。

不过,火箭发射似乎离我们普通人太远了,如果我们想体验一把亲自将火箭送上天的感觉怎么办呢?好像很难啊?没关系,Python有方法,现实世界里做不到,但是你可以在虚拟世界里实现。

《坎巴拉太空计划》就是一个能让你实现这个愿望的一款游戏。在这个游戏中,玩家拥有一支庞大的航天团队,能够造出你想要的任意航天器,你也可以驾驶航天器在坎巴拉星系中遨游,建立太空站。

更重要的是,它!支持!Python!

你可以使用Python来画你想要的航天器、设置警报、航天器之间的通讯、控制运行轨道、监控燃料量等等一系列功能,甚至能够改变游戏界面。

在Space Center API中,你可以读取作用在飞船上的重力、获得海拔高度、绕行轨道的纬度、参考系速度、控制游戏内部相机等等,几乎一切想读取的它都可以读取到。

1.安装

你可以通过pip安装这个项目:

pip install krpc

如果你还没有安装python,请看这篇文章:安装Python

注意,使用这个项目的前提是先下载好游戏。而且在运行脚本的时候,游戏必须在运行着,并与客户端保持连接。怎样才能和客户端连接呢?你还需要下载kRPC服务器插件:

https://github.com/krpc/krpc/releases/download/v0.4.8/krpc-0.4.8.zip

然后执行以下操作:

  1. 提取gamedata文件夹到您的KSP目录。
  2. 启动游戏。
  3. 这时候应该就会弹出服务器窗口

2.使用

运行游戏,并且服务器正常启动后,我们就可以开始尝试一些例子了。不过在这之前,Python脚本作为客户端还需要和服务器进行连接:

import krpc
conn = krpc.connect(name='Hello World')
vessel = conn.space_center.active_vessel
print(vessel.name) 

第二行连接服务器,第三行获得激活的飞行器、第四行打印飞行器名字:

你还可以尝试一些别的API,比如下面这个例子,能够获得飞行棋相对于参照物(行星)的速度:

import krpc, time
conn = krpc.connect(name='Surface speed')
vessel = conn.space_center.active_vessel

while True:

    velocity = vessel.flight(vessel.orbit.body.reference_frame).velocity
    print('Surface velocity = (%.1f, %.1f, %.1f)' % velocity)

    speed = vessel.flight(vessel.orbit.body.reference_frame).speed
    print('Surface speed = %.1f m/s' % speed)

    time.sleep(1) 

如果你们感兴趣,推荐先下载游戏并试玩,大致摸清楚游戏的玩法后,开始使用Python来进行编程游戏。说实话,这个游戏太适合用来教小孩子了。

Python和游戏之间详细的API都在这里可以找得到:

http://krpc.github.io/krpc/python.html

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

超方便的 Python 唤醒窗口自动截图脚本

利用Python自带的win32api和win32con、win32gui等模块,我们能执行许多windows下的自动化操作。比如两个窗口的自动点击操作,从软件中的窗口复制文本到txt中,甚至是截图操作。

截图的操作用途最为广泛,你可以用它配合定时工具,定时检测某个程序的运行情况;甚至可以根据截图做一些辅助性的决策,比如玩类似于《连连看》的游戏时,对相同类型的方块进行标记,辅助你玩游戏。

下面就讲讲如何使用 win32api 实现自动唤醒并截图的操作。

1.准备

开始之前,你要确保Python和pip已经成功安装在电脑上,如果没有,请访问这篇文章:超详细Python安装指南 进行安装。

(可选1) 如果你用Python的目的是数据分析,可以直接安装Anaconda:Python数据分析与挖掘好帮手—Anaconda,它内置了Python和pip.

(可选2) 此外,推荐大家用VSCode编辑器来编写小型Python项目:Python 编程的最好搭档—VSCode 详细指南

Windows环境下打开Cmd(开始—运行—CMD),苹果系统环境下请打开Terminal(command+空格输入Terminal),输入命令安装依赖:

pip install pypiwin32
pip install pillow

1.获取窗口左上角及右下角坐标

​通过 win32gui 的 FindWindow 函数,我们能轻易地找到任何进程的窗口:

import win32api, win32con, win32gui
def get_window_pos(name):
    name = name
    handle = win32gui.FindWindow(0, name)
    # 获取窗口句柄
    if handle == 0:
        return None
    else:
        return win32gui.GetWindowRect(handle)
x1, y1, x2, y2 = get_window_pos('暴雪战网')
print(x1,y1,x2,y2)

结果:

F:\push\20190929>python 1.py
(349, 83, 1549, 1013)

其中窗口信息(x1, y1, x2, y2),(x1, y1)是窗口左上角的坐标,(x2, y2)是窗口右下角的坐标。我们可以利用这个信息配合PIL进行截图。但是在这之前,我们还要解决两个问题:

  1. 该窗口并不在当前的界面上,被其他的软件覆盖到底层中,这时候需要高亮窗口
  2. 该窗口被最小化怎么办

2.win32gui 高亮窗口

为了使得被叠在底层的窗口能放到最上层显示,我们需要拿到窗口的handle,对其执行高亮操作,其实很简单,我们刚刚获得坐标信息的时候已经得到handle了,只需要做一下简单的更改即可。

import win32api, win32con, win32gui
def get_window_pos(name):
    name = name
    handle = win32gui.FindWindow(0, name)
    # 获取窗口句柄
    if handle == 0:
        return None
    else:
        # 返回坐标值和handle
        return win32gui.GetWindowRect(handle), handle
(x1, y1, x2, y2), handle = get_window_pos('暴雪战网')
text = win32gui.SetForegroundWindow(handle)

这样就能将被覆盖到底层的窗口放到最上层,如下图所示。

python 高亮窗口

3. 还原最小化窗口

还有一种特殊情况就是窗口被缩小了,这时候我们就需要还原最小化窗口,其实也非常简单,只要利用win32gui和win32con向该窗口发送一个信息即可。

import win32api, win32con, win32gui
def get_window_pos(name):
    name = name
    handle = win32gui.FindWindow(0, name)
    # 获取窗口句柄
    if handle == 0:
        return None
    else:
        # 返回坐标值和handle
        return win32gui.GetWindowRect(handle), handle
(x1, y1, x2, y2), handle = get_window_pos('暴雪战网')
win32gui.SendMessage(handle, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
# 发送还原最小化窗口的信息
win32gui.SetForegroundWindow(handle)
# 设为高亮 

效果如图所示:

python还原最小化窗口

4.截图

有了PIL模块和窗口的坐标后,我们想截图可非常简单。PIL 模块安装

pip install pillow

安装完就可以试一下我们的完整代码了,如下:

import win32api, win32con, win32gui

def get_window_pos(name):
    name = name
    handle = win32gui.FindWindow(0, name)
    # 获取窗口句柄
    if handle == 0:
        return None
    else:
        # 返回坐标值和handle
        return win32gui.GetWindowRect(handle), handle
(x1, y1, x2, y2), handle = get_window_pos('暴雪战网')
win32gui.SendMessage(handle, win32con.WM_SYSCOMMAND, win32con.SC_RESTORE, 0)
# 发送还原最小化窗口的信息
win32gui.SetForegroundWindow(handle)
# 设为高亮
from PIL import Image, ImageGrab
img_ready = ImageGrab.grab((x1, y1, x2, y2))
# 截图
img_ready.show()
# 展示 

效果如下:

python 截图

这个功能可好用了,比如说你需要监控一个窗口的运行状况,不可能时时刻刻都去观察它,你可以使用while循环不断调用这个窗口截图脚本,先截图进行保存。

你甚至可以配合定时任务做截图,见我们上篇文章:Schedule—简单实用的 Python 周期任务调度工具

截图后的图表信息还能够用于分析、辅助决策。举个游戏的例子:当你玩《连连看》的时候,可以截图检测每个方块是否相同,把相同的方块标记出来,提高你的连连看游戏效率。

我们的文章到此就结束啦,如果你喜欢今天的Python 实战教程,请持续关注Python实用宝典。原创不易,希望你能在下面点个赞和在看支持我继续创作,谢谢!

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

Blender, 用Python绘制宇宙飞船的3D建模软件

见过用Python进行3D建模操作的么?下面给你演示一下:

强不强?这就是Blender,一款能用Python进行建模的软件。

Blender是一个免费的开源3D计算机图形软件工具集,用于创建动画电影视觉效果,艺术品,3D打印模型,动态图形,交互式3D应用程序和计算机游戏

不仅如此,它还提供了一个Python与Blender交互的API: https://docs.blender.org/api/2.81/ ,使Python进行3D建模成为一种可能。

下面介绍一下这个宇宙飞船项目。这是一个比赛作品,作者用它参与了reddit的一个2016年6月的挑战赛。实现的原理并不复杂,就是从一个立方体开始建造船体,利用随机数增加船体的不确定性。然后慢慢地往船体增加细节,比如引擎、天线、炮塔、照明灯等等。

项目地址: https://github.com/a1studmuffin/SpaceshipGenerator

快来生成你的宇宙飞船

要想运行这个项目,你需要做如下准备:

1. 安装Blender 2.76以上:
https://www.blender.org/download/

2. 下载作者的生成代码(也就是已经和Blender做好API联调的代码)。
如果你访问不了Github, 可在公众号后台回复 宇宙飞船 下载这些代码。

3. 将下载好的代码( add_mesh_SpaceshipGenerator.zip, 以压缩包的形式)载入到blender中:

3.1 点击菜单栏里的 Edit — 选择Preferences.

3.2 选择左侧的Add-ons,然后点击install,选择刚刚下载下来的压缩包。

3.3 载入后记得勾选插件。

4. 使用快捷键shift+F5进入3D视图

5. 使用快捷键shift+A,这时候鼠标右键会弹出选项,在mesh中选择 Spaceship即可生成你的宇宙飞船!

怎么样,够不够帅?记得自己实践一下生成一个哦!

自己用Python进行DIY

如果你想自己再进行一下DIY,让飞船变得更帅气,那也是可以的!把下载下来的压缩包解压,里面会有一个文件叫spaceship_generator.py的,这个就是主要的模型生成代码。你能在里面看到作者的许多参数设置,稍微修改一下会有惊喜哦!

你也可以阅读完作者的这份源代码(也不多,就800行),自己学着做一个有别于宇宙飞船的3D模型!

我们的文章到此就结束啦,如果你希望我们今天的Python 教程,请持续关注我们,如果对你有帮助,麻烦在下面点一个赞/在看哦有任何问题都可以在下方留言区留言,我们都会耐心解答的!


​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典