由于我的 pi 里的 python 版本还是 3.5,一些功能无法使用,但是 arm 架构又没有现成的源,只好本地编译安装。
先安装基础的编译工具
sudo apt-get install -y make build-essential libssl-dev zlib1g-dev
sudo apt-get install -y libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm
sudo apt-get install -y libncurses5-dev libncursesw5-dev xz-utils tk-dev
到 python 的官方库里取下载源码,例如:
https://www.python.org/ftp/python/3.9.13/Python-3.9.13.tgz
cd /tmp
tar zxvf Python-3.9.13.tgz
cd Python-3.9.13
sudo ./configure && sudo make -j4 && sudo make install
需要注意的是,在解压缩时,可能会报错,可以尝试移除 z 参数,改用 xvf 来解压缩。反正衣服自己洗是放弃了,直接在 windows 平台上用 7z 重新打包,然后上传到 pi 里解压缩来解决的。
最后,通过 python3 -V 来检查版本号是否符合预期。
安装:pip install pipreqs
在项目根目录下,打开控制台,输入:
pipreqs ./ –encoding=utf8
加–encoding=utf8为了避免编码错误
在 Firefly 通过编译安装的升级 python 的时候,编译始终有些乱七八糟的错误。一气之下,就更新了固件到 Ubuntu 18.04 系统上,再编译升级报错就少了很多,一点点终于升级成功了。
可是按照网上的操作安装 opencv-python 时总是提示找不到,怀疑是这个并没有针对 ARM 的版本吧。使用 python-opencv 只有 2.7 的可以安装上。
只好通过网上的帖子,编译安装 opencv,当前最新的版本是 4.3,按照这里 ,还有这里 。经过漫长的等待,虽然有很多警告,不过终于是安装成功了。
先下载最新的版本 wget https://github.com/opencv/opencv/archive/4.3.0.tar.gz
然后解压缩 tar zxvf opencv.4.3.0.tar.gz
进入到其目录,并创建 build 子目录 mkdir build cd build cmake -D CMAKE_BUILD_TYPE=RELEASE .. make -j4 sudo make install
最后可以使用 import cv2 来验证
网上的帖子里说在使用 cmake 时传递的参数会导致很多错误,所以就直接使用了最少的参数。好在没有什么问题。
最近在打算写个工具去获取车辆的停车信息,以提醒自己及时地挪车。
常规地讲,需要先登录内网系统查看,内网在域里,使用了单点登录和 winodws 身份验证机制。Python 里大家使用的比较多的是 requests 库,但是它不支持这样的登录。
我们就需要别的库来帮忙了,经过一番搜索 ,发现 requests_ntlm 满足要求。
import requests from requests_ntlm import HttpNtlmAuth
response = requests.get(url, auth=HttpNtlmAuth(“name”, “password”))
经过实际验证,这个库会有2次的401错误请求。
顺便也搜索了下如何使用 .Net 来获取,看起来更简单:
string url = “http://adm.xxxx.com/Biz/ParkingCarOverTime/List_Employee.aspx”;
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.PreAuthenticate = true; NetworkCredential credential = new NetworkCredential(“name”, “password”); request.Credentials = credential;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine($”Authentication successful {response.StatusCode}”); StreamReader sr = new StreamReader(response.GetResponseStream()); Console.WriteLine(sr.ReadToEnd());
不要问细节,问就是使用 PreAuthenticate 属性
如果要计算一个图片的平均色或者是主题色,过去的做法是遍历图片的像素点,然后分别针对R\G\B做加权平均。但是这样会产生一个意料之外的结果,就是这个平均值的颜色,在这个图片上根本就没有出现过。它仅仅是数学意义上的平均值。
所以另外一种思路就是根据图片里的颜色做聚类分析,只在已经存在的颜色范围里计算。这里可以使用 k-means 传统机器学习算法。
from skimage import io
from sklearn.cluster import KMeans
import numpy as np
# k-means中的k值,即选择几个中心点
k = 3
img = io.imread('city.jpg')
# 转换数据维度
img_ori_shape = img.shape
img1 = img.reshape((img_ori_shape[0] * img_ori_shape[1], img_ori_shape[2]))
img_shape = img1.shape
# 获取图片色彩层数
n_channels = img_shape[1]
# 构造聚类器
estimator = KMeans(n_clusters=k, max_iter= 4000, init='k-means++', n_init=50)
estimator.fit(img1) # 聚类
centroids = estimator.cluster_centers_ # 获取聚类中心
# 生成一个可视化矩阵
result = []
result_width = 200
result_height_per_center = 80
for center_index in range(k):
result.append(np.full((result_width * result_height_per_center, n_channels),
centroids[center_index], dtype=int))
result = np.array(result)
result = result.reshape((result_height_per_center * k, result_width, n_channels))
# 保存矩阵到图片
io.imsave('result.jpg', result)
最后放上测试使用的图片,有兴趣的同学可以试一试,顺序有可能不一样,但是颜色应该是这几个。
在前面接触到阈值处理函数后,又继续了解到 opencv 的腐蚀函数和膨胀函数。腐蚀函数可以用来处理图片里不重要的噪音或者纹理。而膨胀函数如字面意义,处理后图像看起来像气球涨起来了一样,可以借此兼容图片里的孔洞或者边缘的缺陷。
膨胀函数定义如下: cv2.dilate(src, kernel, iteration)
参数说明: src表示输入的图片, kernel表示方框的大小, iteration表示迭代的次数,迭代次数越多,膨胀幅度越大
膨胀操作原理:存在一个kernel,在图像上进行从左到右,从上到下的平移,如果方框中存在白色,那么这个方框内所有的颜色都是白色。有此可见,这个kernel 的尺寸选择,就比较重要了。
下面是效果示意图:
左上角部分是添加了噪音部分,左下角是对其进行腐蚀后的图,可以看到,基本上可以得到我们所需要的内容了。右下角是针对腐蚀后的图进行膨胀,这2个函数都是只进行1次迭代。结果可以看到和原图差不多了。
最近做图片处理时,看别人代码使用了 opencv 的阈值函数 threshold,网上搜索了下这个函数的使用说明。
简单地讲,所谓阈值就是说如果待处理的数据达到了某个临界点后,如何处理的方式。
python里定义如下:cv2.threshold(src, thresh, maxval, type[, dst]) → retval, dst
参数说明如下: src:源图片 thresh:阈值,取值范围0~255 maxval:填充值,取值范围0~255 type:阈值类型,表示的是这里划分的时候使用的是什么类型的算法,常用值为0(cv2.THRESH_BINARY)
图中(x,y)表示的是图像中的坐标 INV 表示的是取反 一般的(BINARY)效果是: 将一个灰色的图片,变成要么是白色要么就是黑色。(大于规定thresh值就是设置的最大值(常为255,也就是白色))
下面是几个方式的效果图
THRESH_BINARY
THRESH_BINARY_INV
THRESH_TRUNC
THRESH_TOZERO
THRESH_TOZERO_INV
实际操作上来说,建议传入已经灰度处理后的图像。
昨天在服务器上安装 python的音频库 pyaudio时,无法正确安装,而在本机Windows上没有遇到这个问题。
网上一番搜索,最后发现安装 protaudio19-dev 这个库解决了我的问题。
sudo apt-get install portaudio19-dev
昨天有按照网上的教程去使用 Python 调用Redis ,代码很简单,就像下面这样子:
但是,运行后的结果显示 b’python’ ,多了一个b,但是获取字符长度的确又是对的,觉得很是奇怪。
今天有向同事妹子请教,后来得出的结论是用回 python 2.7。和妹子继续搜索,发现了解决方法:sys.stdout.buffer.write(r.get(“name”)) ,这么一来需要再引入 sys 库,而且需要自己添加换行符了。
继续搜索,我们可以使用 print(r.get(‘name’).decode(‘utf-8’)),即解码一下然后再显示。稍微好了一点,但是每次要读取 Redis 数值的时候,都要这么来转换下确实显得有点猥琐。
我在想,一定还有更简单的方式。最后看到 stackoverflow 和简书上也讨论了这个事情,有一个剑走偏锋的设置,就是在数据库的连接字符串里多添加一个参数 decode_responses=True,这么一来就会自动将 response 解码。这么做大多数情况下是没有问题的,需要额外注意的是,如果保存在 Redis 数据库里的原始数据就是二进制的,那么通过这种方式,可能得不到自己想要的结果。
在实际运用的时候,就可以灵活考虑了,适当的时候综合使用这两种方式。