1. 安装opencv视觉库
OpenCV 是一个开源的计算机视觉库,OpenCV 库用C语言和 C++ 语言编写,可以在 Windows、Linux、Mac OS X 等系统运行。同时也在积极开发 Python、Java、Matlab 以及其他一些语言的接口,将库导入安卓和 iOS 中为移动设备开发应用。
OpenCV 库包含从计算机视觉各个领域衍生出来的 500 多个函数,包括工业产品质量检验、医学图像处理、安保领域、交互操作、相机校正、双目视觉以及机器人学。
首先我们来引入我们需要的模块:pip install opencv-python
pip的仓库一般都是在国外的服务器上,加了镜像源可以提供下载的速度。
pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple
常见 pip 镜像源(国内源)
清华镜像源:https://pypi.tuna.tsinghua.edu.cn/simple
阿里云镜像源:http://mirrors.aliyun.com/pypi/simple/
中国科技大学镜像源: https://pypi.mirrors.ustc.edu.cn/simple/
华中理工大学镜像源:http://pypi.hustunique.com/
山东理工大学镜像源:http://pypi.sdutlinux.org/
豆瓣镜像源:http://pypi.douban.com/simple/
临时使用pip镜像源可以在使用pip的时候加参数:-i https://pypi.tuna.tsinghua.edu.cn/simple
2. 图片像素矩阵读写原理
首先我们测试如何使用opencv查看一张图片,我们下载的是opencv视觉库,但是引入的时候是引入cv2,调用 imshow函数进行开启窗口查看图片。
import cv2
image = cv2.imread("image/test.jpeg")
cv2.imshow("window", image)
运行结果:窗口一闪而过
因为程序一旦停止运行,图片就不会展示了,所以会出现一闪而过的窗口展示,所以为了让图片长时间展示出来,那么需要加:cv2.waitKey()
图片像素矩阵概念
数字图像数据可以用矩阵来表示,因此可以采用矩阵理论和矩阵算法对数字图像进行分析和处理。由于数字图像可以表示为矩阵的形式,所以在计算机数字图像处理程序中,通常用二维数组来存放图像数据。
cv库中的函数cv.image
读取的是图片的像素矩阵,矩阵单元是rbg的向量形式。下面举例读取纯色图片来解释原理情况:
import cv2
image = cv2.imread("image/test_98_98.jpeg")
# 返回矩阵 矩阵的每个是rgb行向量,[r,g, b]
"""
· The function imread loads an image from the specified file and returns it. If the image cannot be
. read (because of missing file, improper permissions, unsupported or invalid format), the function
. returns an empty matrix ( Mat::data==NULL ).
"""
print(len(image)) # 像素:高
print(len(image[0])) # 像素:宽
print(image) # 像素矩阵(3维列表)
cv2.imshow("window", image)
cv2.waitKey(0)
三维列表:最外维是高,中间维度是宽,最里面的维度是rgb
就比如读取一张纯色(40,44,52)的jpeg图片,发现矩阵的每个是rgb行向量都是相同的。
jpeg与png区别:png可以存储透明的图片,因为png图片的像素单元,是4个数值的元组进行存储,分别对应 Red、Green、Blue、透明度
而我们采用传统的文件读取方式,读出结果都是二进制的格式:
with open('./image/test_98_98.png', 'rb') as f:
print(f.read())
3. 调用电脑本地摄像头
在进行连接手机摄像头之前,我们可以尝试调用电脑本地摄像头做预测试,代码如下
import cv2
capture = cv2.VideoCapture(0)
# 0为电脑内置摄像头
while True:
ret, frame = capture.read()
# 摄像头读取, ret为是否成功打开摄像头, true, false:frame为视频的每一帧图像
frame = cv2.flip(frame, 1)
# 摄像头是和人对立的,将图像左右调换回来正常显示。
cv2.imshow("video", frame)
c = cv2.waitKey(50)
if c == 27: # 27 对应是 esc 键
break
运行结果:开启video的窗口,展示摄像头实时的图像。
代码相关参数介绍
关于函数waitKey(delay=None)
的介绍:@param delay 参数,等待的时长,会发生同步阻塞,单位是milliseconds毫秒,如果传值为0,那么就是永久阻塞直到键盘事件发生。
关于函数flip(src, flipCode, dst=None)
的介绍:@param flipCode 参数,翻转码,分别有三种取值:大于0,小于0,等于0,下面的源码注释也详细地介绍了。
def waitKey(delay=None): # real signature unknown; restored from __doc__
# @param delay Delay in milliseconds. 0 is the special value that means "forever".
def flip(src, flipCode, dst=None): # real signature unknown; restored from __doc__
"""
. The function cv::flip flips the array in one of three different ways (row
. and column indices are 0-based):
. The example scenarios of using the function are the following:
. * Vertical flipping of the image (flipCode == 0) to switch between
. top-left and bottom-left image origin. This is a typical operation
. in video processing on Microsoft Windows\* OS.
. * Horizontal flipping of the image with the subsequent horizontal
. shift and absolute difference calculation to check for a
. vertical-axis symmetry (flipCode \> 0).
. * Simultaneous horizontal and vertical flipping of the image with
. the subsequent shift and absolute difference calculation to check
. for a central symmetry (flipCode \< 0).
. * Reversing the order of point arrays (flipCode \> 0 or
. flipCode == 0).
"""
视频播放案例测试:
import cv2 # 导入库
cv2.namedWindow("camera", 1) # 定义启动窗口名称
video = "https://klxxcdn.oss-cn-hangzhou.aliyuncs.com/histudy/hrm/media/bg3.mp4"
# 此处根据IP摄像头生成的局域网地址
capture = cv2.VideoCapture(video)
# 引入视频地址,video其实也可以换成你电脑中的视频地址或者网络视频资源可以制作成一个播放器。
while True:
success, img = capture.read() # 读取视频
cv2.imshow("camera", img)
cv2.waitKey(10)
另外,我们也可以将其他视频引入进来,当然你可以换一个网络视频地址或者本地视频地址,把它变成视频播放器,然后我们就需要去读取我们引入的视频地址。
网络视频地址比如:https://klxxcdn.oss-cn-hangzhou.aliyuncs.com/histudy/hrm/media/bg3.mp4
4. 内网IP连接手机摄像头
android手机上安装一款APP:IP摄像头
如果应用商店没有,那么打开手机百度进行下载,安装成功后,点击软件界面下方“打开IP摄像头服务器”,选择局域网的IP地址。
展示手机端摄像头实时图像
要想连接成功,必须保持手机与电脑处于同一局域网下,例如同一热点,同一WIFI。
既然实时的,而且要长时间运行,那当然少不了while true
import cv2 # 导入库
cv2.namedWindow("camera", 1) # 定义启动窗口名称
video = "http://admin:admin@192.168.0.101:8081/"
# 此处根据IP摄像头生成的局域网地址
capture = cv2.VideoCapture(video)
# 引入视频地址,video其实也可以换成你电脑中的视频地址可以制作成一个播放器。
num = 0
while True:
success, img = capture.read() # 读取视频
img = cv2.flip(img, 1)
cv2.imshow("camera", img)
key = cv2.waitKey(10)
if key == 27: # esc键退出
break
if key == ord(' '):
num = num + 1
filename = "frames_%s.jpg" % num
cv2.imwrite(filename, img) # 保存一张图像
capture.release()
# The method is automatically called by subsequent VideoCapture::open and by VideoCapture destructor.
cv2.destroyWindow("camera")
# The function destroyWindow destroys the window with the given name.
运行结果如下所示:cv2.imwrite(filename, img)
保存一张图像,filename传文件的地址值和文件名称
在Windows中用python处理图像时遇到问题 -!_src.empty() in function 'cv::cvtColor'
在运行时报错,根据显示,应该是没有对cvtColor传入源图像。逐步检查:
文件路径正确,是绝对路径,文件名中有中文,最后是因为文件名中有中文,将处理后文件进行保存后发现英文文件名的图像正常,而中文错误。
5. opencv实现人脸检测
梳理一下实现人脸识别需要进行的步骤:
流程大致如此,在此之前,要先让人脸被准确的找出来,也就是能准确区分人脸的分类器,在这里我们可以用已经训练好的分类器,网上种类较全,分类准确度也比较高,我们也可以节约在这方面花的时间。
下载人脸检测xml文件
需要下载人脸模型库文件“ haarcascade_frontalface_default.xml ”,帮助摄像头获取的画面去对比,下载成功后,将“haarcascade_frontalface_default.xml”文件放在上面的代码文件目录里。
链接:https://pan.baidu.com/s/1lxZrI9ZjXWreJvKPYgyQRQ 提取码:w96c
人脸位置检查代码展示如下:
import cv2
# 读取视频信息。
cap = cv2.VideoCapture("http://admin:admin@192.168.0.101:8081/") # @前为账号密码,@后为ip地址
face_xml = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") # 导入XML文件
while cap.isOpened():
f, img = cap.read()
# 读取一帧图片
img = cv2.flip(img, 1)
# 镜像翻转图片
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 转换为灰度图
face = face_xml.detectMultiScale(gray, 1.3, 10)
# 检测人脸,并返回人脸位置信息
for (x, y, w, h) in face:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 255, 255), 2)
# x、y 位置坐标值,w 、h矩形框的大小:width、height
# 最后参数 2 的意思是,矩形框的border(前端css中的div border类似)值
# (255, 255, 255) 捕捉人脸位置的矩形框颜色
cv2.imshow("camera", img)
if cv2.waitKey(10) == 27:
break
cap.release()
实验结果是:在人脸的位置出现白色的矩形框:就好比这样,由于博主不想露脸,效果就像如下所示的那样。
6. 人脸身份信息标注
在我们的人脸呈现的图像中,我们需要进行身份信息的匹配确认,这些的信息需要进行标注起来,展示如下所示:
那么我们将之前的代码进行改进,这次加标注需要字体库,凡是支持中文的字体库都可以,当然如果你是老外,只是需要英文标注,也是可以不用字体库的。
谐体 ttl 链接:https://pan.baidu.com/s/1ocvqJuJ9K2Vq_RvQcqk6dg 提取码:oqdf
代码具体展示,如下所示:
import cv2
import numpy as np
from PIL import Image, ImageDraw, ImageFont
# 读取视频信息。
cap = cv2.VideoCapture("http://admin:admin@192.168.0.101:8081/") # @前为账号密码,@后为ip地址
face_xml = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") # 导入XML文件
while cap.isOpened():
# ret, frame = cap.read()
frame = cv2.imread("img.jpg")
# 读取一帧图片
frame = cv2.resize(frame, (0, 0), fx=0.75, fy=0.75)
# 利用opencv的缩放函数改变摄像头图像的大小,图像越小,所做的计算就少
frame = cv2.flip(frame, 1)
# 镜像翻转图片
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# 转换为灰度图
face = face_xml.detectMultiScale(gray, 1.3, 10)
# 检测人脸,并返回人脸位置信息
for (x, y, w, h) in face:
# CV库有自己的编码规范,要想在图像上输出中文,需将图片格式转化为PIL库的格式,用PIL的方法写入中文,然后在转化为CV的格式
# cv2和PIL中颜色的hex码的储存顺序不同
cv2img = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pilimg = Image.fromarray(cv2img)
draw = ImageDraw.Draw(pilimg)
font = ImageFont.truetype("楷体_GB2312.ttf", 25, encoding="utf-8")
# 参数1:字体文件路径,参数2:字体大小
draw.text((x + 10, y - 40), "北大韦神", (255, 255, 255), font=font)
frame = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)
cv2.rectangle(frame, (x, y), (x + w, y + h), (255, 255, 255), 2)
# x、y 位置坐标值,w 、h矩形框的大小:width、height
# 最后参数 2 的意思是,矩形框的border(前端css中的div border类似)值
# (255, 255, 255) 捕捉人脸位置的矩形框颜色
cv2.imshow("camera", frame)
if cv2.waitKey(10) == 27:
break
cap.release()
当然我们,也可以进行多个人物的标注,不仅仅只是1个人物而已。
7. 结合Flask框架直播画面
首先设计Camera相机捕捉画面的camera.py文件:
import cv2
class VideoCamera(object):
def __init__(self):
# Using OpenCV to capture from device 0. If you have trouble capturing
# from a webcam, comment the line below out and use a video file
# instead.
self.video = cv2.VideoCapture(0)
# If you decide to use video.mp4, you must have this file in the folder
# as the main.py.
# self.video = cv2.VideoCapture('video.mp4')
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
image = cv2.flip(image, 1)
# We are using Motion JPEG, but OpenCV defaults to capture raw images,
# so we must encode it into JPEG in order to correctly display the
# video stream.
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
在Python中用url_for构造URL,他接受函数名作为第一个参数,也接受对应URL规则的变量部分的命名参数,未知的变量部分会添加到URL末尾作为查询参数。
实现实时视频流式传输主要采用服务器推送技术
服务器在响应请求时,HTTP使用MIME报文格式来封装数据。通常一个HTTP响应只能包含一个数据块。但MIME有一种机制可用一个报文(或HTTP响应)表示将多个数据块,这种机制就是成为“multipart/mixed”的标准MIME类型。
在服务器推送技术中,“multipart/x-mixed-replace”类型的报文由唯一的边界线组成,这些边界线分割每个数据块。每个数据块都有自己的头标,因而能够指定对象相关的内容类型和其他信息。由于“multipart/x-mixed-replace”的特性是每一新数据块取代前一数据对象,因而浏览器中总是显示最新的数据对象。
“multipart/x-mixed-replace”报文没有结尾。也就是说,服务器可以永远保持连接,并发送所需的数据。如果用户不再在浏览器窗口中显示数据流,或者浏览器到服务器间的连接中断(例如用户按“STOP”按钮),服务器的推送才会中断。这是人们使用服务器推送的典型方式。
最后是主文件,利用生成器不断读取摄像头的每一帧图像:
from flask import Flask, render_template, Response
from camera import VideoCamera
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index.html')
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n Content-Type: image/jpeg\r\n\r\n' + frame)
@app.route('/video_feed')
def video_feed():
return Response(gen(VideoCamera()), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='192.168.43.247', debug=True, threaded=True)
客户端的页面:
<html>
<head>
<title>唤醒手腕视频捕捉监控</title>
</head>
<body>
<h1>唤醒手腕视频捕捉监控</h1>
<img id="bg" src="{{ url_for('video_feed') }}">
</body>
</html>
8. 腾讯云API人脸动漫化
如何把人脸进行动漫化的操作,借助腾讯云的API来简单实现下:
人像动漫化API文档:https://cloud.tencent.com/document/api/1202/47891
接口描述
接口请求域名: ft.tencentcloudapi.com 。
输入一张人脸照片,生成个性化的二次元动漫形象,可用于打造个性头像、趣味活动、特效类应用等场景,提升社交娱乐的体验。
默认接口请求频率限制:50次/秒。
腾讯云人脸动漫化接口API:输入参数
腾讯云人脸动漫化接口API:输出参数
如果想要在本地项目中进行调用,要申请腾讯云的API密钥:
API密钥的申请地址:https://console.cloud.tencent.com/cam/capi,具体展示如下:
可通过 pip 安装方式将腾讯云 Python SDK 安装至您的项目中。若您的项目环境未安装 pip,请前往 pip 官网 完成安装。
pip install --upgrade tencentcloud-sdk-python
中国大陆地区的用户可以使用国内镜像源提高下载速度,例如:pip install -i https://mirrors.tencent.com/pypi/simple/ --upgrade tencentcloud-sdk-python
地域列表:采用的是就近原则,离得越近API请求速度也越快,比如我在杭州的话,那么我的项目就使用华东地区(ap-nanjing)
使用 SDK:以查询实例列表接口为例
import json
from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.ft.v20200304 import ft_client, models
try:
SecretId = "AKIDjHacNr52j************Lp2yd2A1b" # 你的SecretId
SecretKey = "KOBhvta0A************mxrUrxmK4Y" # 你的SecretKey
cred = credential.Credential(SecretId, SecretKey)
httpProfile = HttpProfile()
httpProfile.endpoint = "ft.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = ft_client.FtClient(cred, "ap-shanghai", clientProfile)
# 详见产品支持的 地域列表。
req = models.FaceCartoonPicRequest()
params = {
"Url": "https://c-ssl.duitang.com/uploads/item/201812/28/20181228201944_eE2F4.thumb.1000_0.jpeg", # 图片地址
"RspImgType": 'url', # 返回图像方式(base64 或 url ) ,二选一。url有效期为1天。
}
req.from_json_string(json.dumps(params))
resp = client.FaceCartoonPic(req)
print(resp.to_json_string())
except TencentCloudSDKException as err:
print(err)
运行结果展示如下所示:ResultUrl就是生成图片的地址文章来源:https://www.toymoban.com/news/detail-488806.html
{"ResultImage": "",
"ResultUrl": "https://faceeffect-1254418846.cos.ap-guangzhou.myqcloud.com/ft/FaceCartoonPic/1302200370/251a9e41-cf7c-4ccc-b6b8-21acb6cb0683",
"RequestId": "251a9e41-cf7c-4ccc-b6b8-21acb6cb0683"}
接下来我们进行请求,获取的就是处理后图片的URL,(左边是原图、右边是请求结果)展示如下:
文章来源地址https://www.toymoban.com/news/detail-488806.html
到了这里,关于基于opencv第三方视觉库,通过内网IP调用手机摄像头,实现人脸识别与图形监测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!