OpenCV Python 笔记

OpenCV Tutorial in Python

显示图片

1
2
3
4
5
6
7
8
9
import cv2

img = cv2.imread('cat_dog.jpg', cv2.IMREAD_COLOR)

print(img.shape)

cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

显示图片(matplotlib)

默认情况下,OpenCV以BGR格式存储彩色图像。

1
2
3
4
5
6
7
8
9
import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('cat_dog.jpg')
rgb_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(rgb_img)
plt.waitforbuttonpress()
plt.close('all')

显示灰度图

1
2
3
4
5
6
7
import cv2

img = cv2.imread('cat_dog.jpg', cv2.IMREAD_GRAYSCALE)

cv2.imshow('image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
阅读全文 »

源代码

https://gitee.com/yjwx0017/ftpserver

参考

FTP 协议简介

命令连接负责传送命令,数据连接负责传送数据。

服务端启动后在21端口监听,接受客户端连接。

命令格式,例如:

1
2
client --> server: USER username\r\n
client <-- server: 331 User name okay, need password.\r\n

命令交互方式为:客户端发送一个命令,服务端返回响应(返回代码 + 描述)。

部分命令:

  • USER命令 指定用户名

  • PASS命令 指定密码

  • PORT命令 主动模式,服务端将连接到客户端提供的IP地址和端口(数据连接)

  • PASV命令 被动模式,服务端启动监听,接受客户端的连接(数据连接)

  • TYPE命令 指定二进制模式还是ASCII模式

  • CWD 命令 更改当前目录

  • CDUP命令 切换到上级目录

  • QUIT命令 断开连接

  • DELE命令 删除文件

  • RMD 命令 删除目录

  • MKD 命令 创建目录

  • PWD 命令 输出当前目录

  • RNFR命令 指定重命名的源(Rename From)

  • RNTO命令 指定重命名的目标(Rename To)

  • LIST命令 列出当前目录下的所有内容

  • NLST命令 列出当前目录下的所有内容(只包含名称)

  • RETR命令 下载文件(Retrieve)

  • STOR命令 上传文件(Store)

  • STOU命令 上传文件(不覆盖重名文件, Store Unique)

  • APPE命令 上传文件(以附加的方式, Append)

  • REST命令 指定断点续传的位置(Restart)

  • FEAT命令 查询支持的扩展特性(比如 UTF8 )

  • OPTS命令 启用禁用某特性(比如 OPTS UTF8 ON)

https://github.com/lapce/floem

  • 布局系统使用 Taffy 实现 Flexbox
  • 响应式设计启发自 leptos_reactive

响应性“信号”允许您以最小的努力保持UI最新,同时保持非常高的性能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
use floem::reactive::create_signal;
use floem::view::View;
use floem::views::{h_stack, label, v_stack, Decorators};
use floem::widgets::button;

fn app_view() -> impl View {
// 创建一个响应式信号,默认值为0
let (counter, set_counter) = create_signal(0);

// 创建一个垂直布局
v_stack((
// 标签控件上的计数文本将自动更新,得益于响应式信号
label(move || format!("Value: {}", counter.get())),
// 创建一个水平布局
h_stack((
button(|| "Increment").on_click_stop(move |_| {
// 按钮单击时更新计数
set_counter.update(|value| *value += 1);
}),
button(|| "Decrement").on_click_stop(move |_| {
// 按钮单击时更新计数
set_counter.update(|value| *value -= 1);
}),
)),
))
}

fn main() {
floem::launch(app_view);
}
阅读全文 »

Rust 程序设计语言 中文版

智能指针

  • Box,用于在堆上分配值
  • Rc,一个引用计数类型,其数据可以有多个所有者
  • Ref 和 RefMut,通过 RefCell 访问

RefCell 是一个在运行时而不是在编译时执行借用规则的类型。

使用 Box 指向堆上的数据

box 允许你将一个值放在堆上而不是栈上。留在栈上的则是指向堆数据的指针。

1
2
3
4
fn main() {
let b = Box::new(5);
println!("b = {}", b);
}

举例,使用box实现一个递归类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
enum List {
Cons(i32, Box<List>),
Nil,
}

use crate::List::{Cons, Nil};

fn main() {
let list = Cons(1,
Box::new(Cons(2,
Box::new(Cons(3,
Box::new(Nil))))));
}

Box 类型是一个智能指针,因为它实现了 Deref trait,它允许 Box 值被当作引用对待。

1
2
3
4
5
6
7
fn main() {
let x = 5;
let y = Box::new(x);

assert_eq!(5, x);
assert_eq!(5, *y);
}

当 Box 值离开作用域时,由于 Box 类型 Drop trait 的实现,box 所指向的堆数据也会被清除。

阅读全文 »

Rust 程序设计语言 中文版

vector

vector 允许我们在一个单独的数据结构中储存多个值,所有值在内存中彼此相邻排列。vector 只能储存相同类型的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let v: Vec<i32> = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);

// 获取指定元素的引用
let third: &i32 = &v[2];

// 通过 get 获取元素,返回值为 Option<T>
match v.get(2) {
Some(third) => println!("The third element is {}", third),
None => println!("There is no third element."),
}

使用初始值来创建一个Vec:

1
2
// Rust 可以推断出 v 的类型是 Vec<i32>,因此类型标注就不是必须的。
let v = vec![1, 2, 3];

遍历 vector 中的元素:

1
2
3
4
5
6
7
8
9
let v = vec![100, 32, 57];

for i in &v {
println!("{}", i);
}

for i in &mut v {
*i += 50;
}
阅读全文 »

Rust 程序设计语言 中文版

Hello World

Rust 文件通常以 .rs 扩展名结尾。

1
2
3
fn main() {
println!("Hello, world!");
}

编译并运行:

1
2
3
> rustc main.rs
> .\main.exe
Hello, world!

其他命令:

1
2
3
4
rustup update           # 更新
rustup self uninstall # 卸载
rustc --version # 查看版本号
rustup doc # 查看文档

Cargo

Cargo 是 Rust 的构建系统和包管理工具。

常用命令:

1
2
3
4
5
cargo new hello_cargo  # 创建项目
cargo build # 构建项目
cargo run # 构建并运行项目
cargo check # 构建项目而无需生成二进制文件来检查错误
cargo build --release # 发布构建
阅读全文 »

如何使用 Certbot 命令列工具建立免費的 TLS/SSL 頂層網域憑證

安装 certbot

1
apt install certbot

生成证书

1
certbot certonly --manual --preferred-challenges http -m youremail@example.com -d www.zhouyuanchao.com

根据提示在网站服务器指定目录创建指定文件并包含指定内容,通过验证后会在本地生成证书相关文件:

  • cert.pem
  • chain.pem
  • fullchain.pem
  • privkey.pem

将证书部署到网站

以新网为例,要求上传三个文件:

  • 证书链:chain.pem
  • 公钥:cert.pem
  • 私钥:privkey.pem
阅读全文 »

解包/重新打包 initrd 文件

动机:修改启动Logo

首先使用 binwalk 查看 initrd 文件的打包方式。

一种情况是整个文件是一个压缩文件,解压缩后是一个 cpio 归档文件。

另一种情况是文件分为两部分,开头是 cpio 归档文件,后面的部分是压缩文件(解压后也是 cpio 归档文件)。

压缩和解压缩根据压缩算法的类型使用相应的命令,此处以 lz4 为例。

情况一

1
2
3
4
5
6
7
8
9
10
11
12
mkdir initrd_output
mkdir initrd_new

cd initrd_output

# 解压缩,并且解包 cpio
lz4 -dc ../initrd.img | cpio -id

# ... 修改解包出来的 initrd 文件系统

# 重新打包
find . | cpio -o -H newc | lz4 -l9 > ../initrd_new/initrd.img

情况二

使用 binwalk initrd.img 查看两部分内容的边界:

截图

本例中压缩文件的偏移值为 6906880 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mkdir initrd_output
mkdir initrd_new

cd initrd_output

# 解包第一部分 cpio
cat ../initrd.img | cpio -id

# 解包第二部分
mkdir rootfs
cd rootfs
dd if=../../initrd.img bs=6906880 skip=1 | lz4 -dc | cpio -id --no-absolute-filenames

# ... 修改解包出来的 initrd 文件系统

# 打包第一部分
cd ..
find kernel/ | cpio -o -H newc > ../initrd_new/initrd.img

# 打包第二部分并附加
cd rootfs
find . | cpio -o -H newc | lz4 -l9 >> ../../initrd_new/initrd.img
阅读全文 »

edge-tts 简介

edge-tts 是一个 Python 模块,允许使用微软 Edge 的在线文本转语音服务,可使用 Python 代码或 edge-tts 命令行工具执行语音合成。

安装

1
pip install edge-tts

使用

查看 edge-tts 支持的语音列表:

1
edge-tts --list-voices

语音合成:

1
edge-tts --voice zh-CN-YunxiNeural --text "你好,我是微软语音合成小助手。" --write-media hello.mp3

为命令行工具编写一个 UI 界面

使用 Qt 实现。

源码:https://gitee.com/yjwx0017/edge-tts-ui

截图

0%