Opencv 高级进阶Python

欢迎访问个人博客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 模块
在这里插入图片描述

  1. 几个简单的方法
  • 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()
  1. 访问图像属性

图像属性包括:

  • 行数
  • 列数
  • 通道数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()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值