欢迎访问个人博客http://www.jkraise.top
from functools import reduce
def funcl(x, y):
return x - y
list01 = [1,2,3,4,5,6,7,8]
# reduce 把列表中1,2元素 进行函数运算得到的结果再和第3个元素用函数运算 依次后推
result = reduce(func1, list01)
from functools import reduce
def func1(x):
# 返回一个布尔值
return x % 2 == 0
list01 = [1, 2, 3, 4, 5, 6, 7, 8]
# filter 过滤 把列表数据传入函数 返回值为True的保留到新的列表
list02 = list(filter(func1, list01))
print(list02)
def func1(x, y):
return x + y
list01 = [1, 2, 3, 4, 5, 6, 7, 8]
list02 = [3, 4, 7, 8, 5]
# map 参1传入一个函数 参2.3.4。。。 传入需要的列表
list03 = list(map(func1, list01, list02))
print(list03)
opencv 模块
- 几个简单的方法
- ov2.imread() 读入图片,共两个参数, 参数1 为要读取图片文件名, 参数2为如何读取图片
- cv2.imshow() 创建一个窗口显示图片, 共两个参数, 参数1 窗口名字, 可以创建多个窗口,但是每个窗口不能重名;, 参数2 是读入图片
- cv2.imwrite() 保存图片, 共两个参数, 参数1, 保存文件名, 参数2 为读入图片
- cv2.waitkey() 键盘绑定函数, 一个参数, 表示等待毫秒数,将等待特定的几毫秒, 看键盘是否有输入,返回值是ascll值, 如果其参数为0, 则表示无限期等待,假盘输入
- cv2.destroyAIIWindows(): 删除建立的全部窗口
- cv2.destroyWindows(): 删除指定的窗口
使用 cv2.imread() 函数读取图像
注意点1:
图像应该在和我们文件一起的目录中,或者在程序里应该给出图像的完整路径
。
注意点2:(指定图像读取方式的flag)`
cv2.IMREAD_COLOR # :1 加载一个彩色图像,图像的任何透明度都将被忽略。这是默认标志
cv2.IMREAD_GRAYSCALE # :0 以灰度模式 (grayscale mode) 加载图像
cv2.IMREAD_UNCHANGED # :-1 加载图像,包括alpha channel (透明通道)
小窍门:
我们除了输入上面三个中的flag ,我们也可以用1,0,-1来代替`
import cv2 # 导入cv2 也就是opencv-python 包
# 导入灰度模式的彩色图片一张
img = cv2.imread('dog.jpeg', 0) # 我已经将照片放入和我的python 文件一起的文件夹了;0代表灰度模式
合并后的代码
# coding=utf-8
import cv2
# 1.读取图片
img = cv2.imread("dog。jpeg", 0)
# 2 看一下读取的图片数据
print(img)
# 3.1 命名一个创建, 并设置可以自动缩放
cv2.namedWindow("dog", cv2.WINDOW_NORMAL)
# 3.2 在刚刚的窗口中显示 图片数据
cv2.imshow("dog", img)
# 4 等待按下任意键
cv2.waitKey(0)
# 5 保存灰度图片
cv2. imwrite("black_white_dog.jpg", jmg)
# 6 关掉所有窗口
cv2.destroyAllWindows()
- 访问图像属性
图像属性包括:
- 行数
- 列数
- 通道数channels
- 图像数据类型像素数
- 。。。等等。。。
图像的形状可以由img.shape 来得到,它会返回以元组为形式的的行数,列数和通道数(如果图像是彩色的):
一幅完整的图像,是由红色绿色蓝色三个通道组成的。他们共同作用产生了完整的图像,
注意:
- 读取彩色图的通道数是3
- 如果图像是灰度的,返回的元组就只会包含行数和列数,没有通道数灰度图没有通道数,所以
- 用shape 来检测加载的图像是灰度图像还是彩色图像是一种很实用的方法print(img.shape)
# 得到结果如下
(540, 720, 3)
# 图像的行数、列数、通道数
像素的总数(行数x列数x通道数)可以用img.size来得到:
print(img.size)
# 得到结果如下
1166400
图像的数据类型可以通过img.dtype来获得:
print(img.dtype)
# 得到结果如下
uint8
img.dtype
在debug 过程中是非常重要的,因为OpenCV-Python 代码中的大量错误都是由无效的数据类型引起的。
- uint8 是值 无符号的8位整数 图片rgb每一种颜色的取值是0-255,最多8位
Numpy简介
NumPy 是一个运行速度非常快的数学库,主要用可用来存储和处理大型矩阵,包含:
- 一个强大的N维数组对象 ndarray
- 广播功能函数
- 整合 C/C++/Fortran 代码的工具
- 线性代数、傅里叶变换、随机数生成等功能
import cv2
import numpy as np
img = cv2.imread("dog2.jpg")
我们可以通过图片的行和列坐标访问特定的像素值。
对于BGR映像,它返回的是一个蓝、绿、红值数组。
对于灰度图像,只返回相应的强度。步骤2打印图片的BGR
px = img[100,100]
print(px)
# 得到结果如下(表示 100,100标记的那个像素的BGR是)
[ 97 111 169]
步骤3
输出蓝色(BGR,B是0,G是1,R是2)的像素值大小
# 最后一个0标识获取的是蓝色
blue = img[100, 100, 0]
print(blue)
# 结果为97
步骤4
用同样的方式修改像素值
img[100, 100] = [255, 255, 255]
print(img[100,100])
# 得到结果为(改为白色)
[255 255 255]
步骤5
尝试修改图片
import cv2
# 1. 读取图片
img = cv2.imread("dog2.jpg", 1)
# 2. 循环的方式修改某个位置的BGRfor i in range(100):
img[i, i] = [255, 255, 255]
# 3. 保存这个图片
cv2.imwrite("dog2_change.jpg", img)
步骤6
从另外一个图片中获取部分像素值,对一个图片进行"粘贴"
import cv2
img1 = cv2.imread("dog.jpeg")
img2 = cv2.imread("dog2.jpg")
# 行50-250 像素, 列50-250 像素的位置放上另外一个小狗的图片
# 第一个0: 200 表示 在行0-200
# 第二个 0:200 表示 在列0-200
img1[50:250, 50:250] = img2[0:200, 0:200]
cv2.imwrite("dog_change.ipg", img1)
分割和合并图像
当需要时, 图像的 B-G-R通道channels 可以被分割成各自独立的平面
b, g, r, = cv2.split(img) # 把b,g,r 分割出来
img = cv2.merge((b, g, r)) # 把它们再重新组合起来
# 或者我们可以用以下代码
b = img[:, :,0] #得到蓝色
还有,如果你想让所有的红色像素都为零,我们不需要像这样分割然后让它等于零。有个更快的方法,我们可以简单地使用Numpy索引。
img[:,:,2] = 0
说明
cv2.split() 函数其实是一个很费时的操作,所以基本上只在必要时使用它。Numpy 索引则要高效得多,如果可能的话应该尽可能使用它。
通过Numpy生成一个图片
import cv2
import numpy as np
# `图片的分辨率为200*300(看参数3) 这里 b, g, r 设为随机值, 随机范围是参数1到参数2之间,注意dtype属性
b = np.random.randint(0, 255, (200, 300), dtype=np.uint8)
g = np.random.randint(0, 255, (200, 300), dtype=np.uint8)
r = np.random.randint(0, 255, (200, 300), dtype=np.uint8)
# 合并通道, 形成图片
img = cv2.merge([b,g,r])
# 显示图片
cv2.imshow("test", img)
xc2.waitKey(0)
cv2.destroyWindow("test")
案例2
# 自定义一张三通道图片
def creat_image():
img = np.zeros([400, 400, 3], np.uint8) # 将所有像素点的各通道数值赋0
img[:, :, 0] = np.ones([400, 400])*255
# 0通道代表 B
img[:, :, 1] = np.ones([400, 400])*255
# 1通道代表 G
img[:, :, 2] = np.ones([400, 400])*255
# 1通道代表 R
cv2.imshow("new_image",img)
creat_image()
cv2.waitKey(0)
cv2.destroyAllWindows()
- img 图形: 我们想要绘制形状的图像
- color 颜色: 形状的颜色, 对于BGR, 将其作为元组传递, 例如, (255,0,0)对应的就是蓝色对于灰度图像, 我们只需传递标量值
- thickness 厚度 : 线或圆等形状的厚度, 对于圆形这样的闭合图形, 如果该参数传递-1, 就会填充颜色进形状中 默认厚度为 1
- lineType 线类型:线的类型,是否8连接,反锯齿线 anti-aliased line等。这个参数默认为8 连接。cv2.LINE_AA 提供了反锯齿的线条,在绘制曲线上很实用
* 画线
import numpy as np
import cv2
# 创建一个黑色的背景图
# 大小为500x500 的图片,有3个channels,分别对应蓝色,绿色,红色
# 因为我们使用了np.zeros, 会对这三个channels 分别赋予0,(0,0,0)也就是黑色
# np.uint8 代表我们数组的类型
img = np.zeros((500, 500, 3), np.uint8)
# 画一条对角蓝线,厚度为5 px
# 参数分别是起始点,重点,颜色:蓝色,厚度:5 px
cv2.line(img, (0, 0), (500, 500), (255, 0, 0), 5)
print(img)
# 展示图像
cv2.imshow('', img)
k = cv2.waitKey(0)
cv2.destroyAllWindows()
监控客户端模拟
import socket
import traceback
import cv2
class Client(object):
"""客户端"""
def __init__(self, addr_port=('', 11000)):
# 连接的服务器的地址
# 连接服务器的端口
self.addr_port = addr_port
# 创建套接字
self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 地址端口可以复用
self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
# 分辨率
self.resolution = (640, 400)
def connect(self):
"""连接服务器"""
try:
self.client.connect(self.addr_port)
return True
except Exception as exp:
traceback.print_exc() # 打印原始的异常信息
print("连接失败")
return False
def send2server(self):
"""读摄像头数据 发送给服务器"""
camera = cv2.VideoCapture(0) # 摄像头对象
print("isOpened:", camera.isOpened())
# while camera.isOpened() and ((cv2.waitKey(100) & 0xFF)) != ord("q")):
while camera.isOpened():
try:
# h获取摄像头数据
ret, frame = camera.read()
# 对每一帧图片的大小处理 和大小的压缩
frame = cv2.resize(frame, self.resolution)
# 参1图片后缀名 参2原图片的数据 参3图片质量 0-100 越大越清晰
ret, img = cv2.imencode('.jpg', frame, [cv2.IMRITE_JPEG_QUALITY, 100])
# img 是被压缩后的数据 无法正常显示
print(img)
print("-----------")
print(img.tostring()) # 转换二进制
img = img.tostring()
# 获取数据长度
length = len(img)
# 发送的数据 大小 宽 高 图片数据
# 数据打包变为 二进制
# pack 方法参数1 制定打包数据的数据大小 i 4字节 h 代表2 字节
all_data = struct.pack('ihh', length, self.resolution[0], self.resolution[1]) + img
self.client.send(all_data)
except:
camera.release() # 释放摄像头
traceback.print.exc()
return
if __name__ == "__main__":
client = Client()
if client.connect():
client.send2server()