哈喽大家好,好久没有给大家带来好玩的东西了。这次给大家介绍下开发的小玩意,让大家联动手机与树莓派,来进行实时的监控。
首先我们用的是一台树莓派4B,加装了一个摄像头,并安装了Raspberry Pi OS系统。这个系统大家一般购买的时候店家会发给你,自己按照教程烧录就好啦。
(购买的树莓派)
(进入到系统界面)
然后最关键的是我们要安装Linux版本的opencv,这个步骤相对较难,我直接找了别人装好的镜像,安装到了树莓派里,其他的诸如miniconda等大家自行安装。然后进行以下测试,如果桌面正常采集出example1.png那么我们基本上可以完成剩下的步骤!
import cv2
import numpy as np
cap = cv2.VideoCapture(0) # 注意:这个地方本文的图片里没有参数0,但是应该传入0
f, frame = cap.read() # 此刻拍照
cv2.imwrite("example1.png", frame) # 将拍摄内容保存为png图片
cap.release() # 关闭调用的摄像头
print('采集完成')
如果我们想对摄像头采集的内容进行感知,来判断是否存在场景变化(例如实现有行人经过进行抓拍),那么最简单的思路是,间隔一秒钟进行拍照,然后对比一秒钟前后的图像变化,计算哈希相似度,如果相似度低于0.8那么我们判断有人经过或者场景发生了改变~
def compare_image(self, file_image1, file_image2, size=(256, 256), part_size=(64, 64)):
'''
'file_image1'和'file_image2'是传入的文件路径
可以通过'Image.open(path)'创建'image1' 和 'image2' Image 对象.
'size' 重新将 image 对象的尺寸进行重置,默认大小为256 * 256 .
'part_size' 定义了分割图片的大小.默认大小为64*64 .
返回值是 'image1' 和 'image2'对比后的相似度,相似度越高,图片越接近,达到1.0说明图片完全相同。
'''
image1 = Image.open(file_image1)
image2 = Image.open(file_image2)
img1 = image1.resize(size).convert("RGB")
sub_image1 = self.split_image(img1, part_size)
img2 = image2.resize(size).convert("RGB")
sub_image2 = self.split_image(img2, part_size)
sub_data = 0
for im1, im2 in zip(sub_image1, sub_image2):
sub_data += self.calculate(im1, im2)
x = size[0] / part_size[0]
y = size[1] / part_size[1]
pre = round((sub_data / (x * y)), 6)
# print(str(pre * 100) + '%')
print('Compare the image result is: ' + str(pre))
return pre
(写一下对比的代码)
同时我们设置While循环,这个系统就可以一直运行啦。但是仅仅计算出来,没办法传送到移动设备,感觉这还是不够智能。我们就引入邮件的SMTP服务,让他自动进行戒备。我们这里使用的是网易163邮箱,相关授权请自行百度。
构造一个发邮箱请求:
def sendEmail(content,title):
sender = 'XXX@163.com'# 我用的163邮箱
receivers = ['XXXX'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
message_content = MIMEText(content, 'plain', 'utf-8')# 内容, 格式, 编码
message = MIMEMultipart('related')
message['Subject'] = '摄像头识别检测'
message['From'] = "{}".format(sender)
message['To'] = ",".join(receivers)
# message['Subject'] = title
# 第三方 SMTP 服务
mail_host = "smtp.163.com" # SMTP服务器
mail_user = "" # 用户名
mail_pass = "" #你的smtp密钥
img = MIMEImage(open('example1.png', 'rb').read(), _subtype='octet-stream')
img.add_header('Content-Disposition', 'attachment', filename='example1.png')
message.attach(img)
message.attach(message_content)
try:
smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 启用SSL发信, 端口一般是465
smtpObj.login(mail_user, mail_pass)# 登录验证
smtpObj.sendmail(sender, receivers, message.as_string())# 发送
print("mail has been send successfully.")
except smtplib.SMTPException as e:
print(e)
测试效果:
(手机收到邮件)
其他的 一些好玩的,例如在树莓派上进行图像的边缘检测:
import cv2
import numpy as np
img1=cv2.imread('/home/pi/Desktop/example1.png')
img2=cv2.imread('/home/pi/Desktop/example2.png')
# 从文件中读取图像
image = cv2.imread('/home/pi/Desktop/example2.png', cv2.IMREAD_COLOR)
# 将图像转换为灰度图
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 使用Canny算法进行边缘检测
edges = cv2.Canny(gray, threshold1=30, threshold2=100)
# 保存边缘检测结果的图像
cv2.imwrite('edges_image.jpg', edges)
# 显示原始图像和边缘检测结果
cv2.imshow('Original', image)
cv2.imshow('Edges', edges)
# 等待用户按下任意键,然后关闭窗口
cv2.waitKey(0)
cv2.destroyAllWindows()
还可以部署yolos-tiny来进行目标检测与识别~返回手机的信息可以更多,甚至可以接入大模型接口来进行场景描述(参见:城市字幕,教你如何利用图像跨模态推理空间知识)。后期我们还集成了人脸的年龄、情绪、族裔以及性别检测算法,也会将在接下来的教程中公开。
做科学实验,数据的获取是非常关键的步骤,计划未来开发城市感知微型基站,集成更加多源的传感器,获取声热音光等多源信息,部署在车辆上,采集一手的城市数据,欢迎大家继续关注。
(采购了一些小的传感器)
下一期继续给大家推送微博数据相关的技术与方法,教大家如何构建自己的公共事件社交媒体数据集,以下是一些前期文档:
最后是本文分享的全部代码:
# -*- coding: UTF-8 -*-
__author__ = 'zy'
__time__ = '2020/5/24 20:21'
#coding:utf8
import os
from PIL import Image,ImageDraw,ImageFile
import numpy
import pytesseract
#import cv2
#import imagehash
import collections
import cv2,time
def compare_image_with_hash(image_file1,image_file2, max_dif=0):
"""
max_dif: 允许最大hash差值, 越小越精确,最小为0
推荐使用 cv2.img_hash.averageHash
"""
ImageFile.LOAD_TRUNCATED_IMAGES = True
hash_1 = None
hash_2 = None
with open(image_file1, 'rb') as fp:
hash_1 = cv2.img_hash.averageHash(Image.open(fp))
print(hash_1)
with open(image_file2, 'rb') as fp:
hash_2 = cv2.img_hash.averageHash(Image.open(fp))
print(hash_2)
dif = hash_1 - hash_2
print(dif)
if dif < 0:
dif = -dif
if dif <= max_dif:
return True
else:
return False
class CompareImage():
def calculate(self, image1, image2):
g = image1.histogram()
s = image2.histogram()
assert len(g) == len(s), "error"
data = []
for index in range(0, len(g)):
if g[index] != s[index]:
data.append(1 - abs(g[index] - s[index]) / max(g[index], s[index]))
else:
data.append(1)
return sum(data) / len(g)
def split_image(self, image, part_size):
pw, ph = part_size
w, h = image.size
sub_image_list = []
assert w % pw == h % ph == 0, "error"
for i in range(0, w, pw):
for j in range(0, h, ph):
sub_image = image.crop((i, j, i + pw, j + ph)).copy()
sub_image_list.append(sub_image)
return sub_image_list
def compare_image(self, file_image1, file_image2, size=(256, 256), part_size=(64, 64)):
'''
'file_image1'和'file_image2'是传入的文件路径
可以通过'Image.open(path)'创建'image1' 和 'image2' Image 对象.
'size' 重新将 image 对象的尺寸进行重置,默认大小为256 * 256 .
'part_size' 定义了分割图片的大小.默认大小为64*64 .
返回值是 'image1' 和 'image2'对比后的相似度,相似度越高,图片越接近,达到1.0说明图片完全相同。
'''
image1 = Image.open(file_image1)
image2 = Image.open(file_image2)
img1 = image1.resize(size).convert("RGB")
sub_image1 = self.split_image(img1, part_size)
img2 = image2.resize(size).convert("RGB")
sub_image2 = self.split_image(img2, part_size)
sub_data = 0
for im1, im2 in zip(sub_image1, sub_image2):
sub_data += self.calculate(im1, im2)
x = size[0] / part_size[0]
y = size[1] / part_size[1]
pre = round((sub_data / (x * y)), 6)
# print(str(pre * 100) + '%')
print('Compare the image result is: ' + str(pre))
return pre
import smtplib,time
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
def sendEmail(content,title):
sender = 'XXX@163.com'# 我用的163邮箱
receivers = ['XXXX'] # 接收邮件,可设置为你的QQ邮箱或者其他邮箱
message_content = MIMEText(content, 'plain', 'utf-8')# 内容, 格式, 编码
message = MIMEMultipart('related')
message['Subject'] = '摄像头识别检测'
message['From'] = "{}".format(sender)
message['To'] = ",".join(receivers)
# message['Subject'] = title
# 第三方 SMTP 服务
mail_host = "smtp.163.com" # SMTP服务器
mail_user = "" # 用户名
mail_pass = "" #你的smtp密钥
img = MIMEImage(open('example1.png', 'rb').read(), _subtype='octet-stream')
img.add_header('Content-Disposition', 'attachment', filename='example1.png')
message.attach(img)
message.attach(message_content)
try:
smtpObj = smtplib.SMTP_SSL(mail_host, 465) # 启用SSL发信, 端口一般是465
smtpObj.login(mail_user, mail_pass)# 登录验证
smtpObj.sendmail(sender, receivers, message.as_string())# 发送
print("mail has been send successfully.")
except smtplib.SMTPException as e:
print(e)
if __name__=='__main__':
while True:
cap = cv2.VideoCapture(0) # 注意:这个地方本文的图片里没有参数0,但是应该传入0
f, frame = cap.read() # 此刻拍照
cv2.imwrite("example1.png", frame) # 将拍摄内容保存为png图片
cap.release() # 关闭调用的摄像头
print('采集完成')
time.sleep(1)
cap = cv2.VideoCapture(0) # 注意:这个地方本文的图片里没有参数0,但是应该传入0
f, frame = cap.read() # 此刻拍照
cv2.imwrite("example2.png", frame) # 将拍摄内容保存为png图片
cap.release() # 关闭调用的摄像头
compare_image = CompareImage()
result=compare_image.compare_image("example1.png","example2.png")
print(result)
if result<0.8:
sendEmail(str(result), '温度测试反馈结果')