Skip to content

2024

期刊之我见

正刊 大子刊 小子刊

第一档:rse lup isprs wrr wr est gcb(顶刊)

第二档:cities tgrs(次顶刊)

第三档:jag scs hi ijgis 大ei(一区)

第四档:jclp stoten(一区守门,仅两本)

第五挡:jem,uf&ug,eco ind (普通二区)

第六档:rs land forests(二区水刊,博士)

第七档:ijgi atmo sus 普通南核(三区-普通南核)

第八档:普通北核(硕士)

第九档:论文

基于树莓派打造你的个人感知终端

cover_image

基于树莓派打造你的个人感知终端

原创 喵喵张 城市感知计算

城市感知计算

微信号 sensingcity

功能介绍 认识世界和改造世界,分享地理信息系统科普知识与学术研究,欢迎加好友学术交流。



哈喽大家好,好久没有给大家带来好玩的东西了。这次给大家介绍下开发的小玩意,让大家联动手机与树莓派,来进行实时的监控。

首先我们用的是一台树莓派4B,加装了一个摄像头,并安装了Raspber ry Pi OS系统。 这个系统大家一般购买的时候店家会发给你,自己按照教程烧录就好啦。

(购买的树莓派)

(进入到系统界面)

然后最关键的是我们要安装Linux版本的opencv,这个步骤相对较难,我直接找了别人装好的镜像,安装到了树莓派里,其他的诸如miniconda等大家自行安装。然后进行以下测试,如果桌面正常采集出 example1.png 那么我们基本上可以完成剩下的步骤!

    import cv2import numpy as npcap = cv2.VideoCapture(0) # 注意:这个地方本文的图片里没有参数0,但是应该传入0f, 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 cv2import numpy as npimg1=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:utf8import osfrom PIL import Image,ImageDraw,ImageFileimport numpyimport pytesseract#import cv2#import imagehashimport collectionsimport 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,timefrom email.mime.text import MIMETextfrom email.mime.image import MIMEImagefrom 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), '温度测试反馈结果')

预览时标签不可点

微信扫一扫
关注该公众号



收藏

精选留言

Accio来自上海

太牛啦!准备入手树莓派当新玩具了哈哈哈

未命名用户来自上海

我也想玩儿,哈哈哈,准备弄个二手的试试

未命名用户来自上海

玩!大胆玩![耶]

未命名用户来自北京

嘿嘿 好滴[好的]

我直接阿炎来自河北

看完直接激发兴趣,研究一下[嘿哈]

wy来自中国香港

太有意思了!我说你桌子上放的是什么呢[哇]

城市感知计算来自

哈哈哈

老张来自河南

我也想买几个玩玩,觉得挺有意思里。可以锻炼自己动手的能力

兰spring来自河南

有意思

哪个城市是中央眼中的心头爱?基于新闻联播文本的大数据分析

cover_image

哪个城市是中央眼中的心头爱?基于新闻联播文本的大数据分析

原创 喵喵张 城市感知计算

城市感知计算

微信号 sensingcity

功能介绍 认识世界和改造世界,分享地理信息系统科普知识与学术研究,欢迎加好友学术交流。



又到了年底数据大盘点的时刻,在过去的一年里,哪个城市在中央眼中获得了更多的关注呢?新闻联播作为国家意志的传声筒,无疑代表了相当程度上的国家关注。本次分析的数据来自于央视网,遍历其页面,检索获取了2023年至今的所有新闻联播文本。

20240120哪个城市是中央眼中的心头爱基于新闻联播文本的大数据分析 共检索了384天的数据,约有9000条各类新闻播报。从这些语料中检索中国344个城市出现次数,以解释这些城市在国家政治、经济或社会方面的重要性。靠前出现的次数是北京、上海、杭州、重庆、成都、吉林(省市)、天津、广州、深圳、西安、台湾、厦门等等。而我国的经济前列的城市则是上海、北京、深圳、重庆、广州、苏州、成都、杭州、武汉、南京,如果建立在更长时间序列,来看城市在新闻联播中的关注度移动,相信也是一个很有趣的话题。

20240120哪个城市是中央眼中的心头爱基于新闻联播文本的大数据分析

20240120哪个城市是中央眼中的心头爱基于新闻联播文本的大数据分析

把这些城市可视化出来~除了长三角城市外,好像北方的城市更容易被提及诶。除了西部三省外,云贵地区的声量也较弱,长江中游的十余个城市除了武汉南昌长沙外,其余城市也基本上属于“小透明”。

20240120哪个城市是中央眼中的心头爱基于新闻联播文本的大数据分析

附送本文所使用的数据抓取代码,如果有时间可以绘制近10年来的城市关注度转移情况,相信也会是很有意思的事情,有空剪辑一个视频出来hhh 。

    import requestsimport pandas as pdfrom bs4 import BeautifulSoupfrom datetime import datetime, timedelta# Function to extract details from a video linkdef get_video_details(video_url): res_video = requests.get(video_url) res_video.encoding = 'utf-8'    soup_video = BeautifulSoup(res_video.text, 'html.parser') title = soup_video.find('title').text description = soup_video.find('meta', {'name': 'description'})['content'] source = soup_video.find('span', class_='laiyuan').text time = soup_video.find('span', class_='time').text    content = soup_video.find('div', id='content_area').text.strip() return f"标题: {title}\n描述: {description}\n来源: {source}\n时间: {time}\n内容: {content}"# Initialize DataFramedf = pd.DataFrame(columns=['Video Title', 'Video Link', 'Video Image', 'Video Duration'])# Specify the date rangestart_date = datetime.strptime('20230101', '%Y%m%d')end_date = datetime.today()

    Iterate over each day in the date rangewhile start_date <= end_date: date_str = start_date.strftime('%Y%m%d') url = f'https://tv.cctv.com/lm/xwlb/day/{date_str}.shtml'

    # Fetch HTML content    res = requests.get(url)    res.encoding = 'utf-8'    html_code = res.text    soup = BeautifulSoup(html_code, 'html.parser')  
    # Extract information from each video entry    for li in soup.find_all('li'):        a_tag = li.find('a', {'alt': True})        if a_tag:            video_title = a_tag.get('alt')            video_link = li.find('a', {'href': True}).get('href')            video_image = li.find('img').get('src')            video_duration = li.find('span').text  
            # Append the extracted information to the DataFrame            df = df.append({'Video Title': video_title,                            'Video Link': video_link,                            'Video Image': video_image,                            'Video Duration': video_duration}, ignore_index=True)    # Print or use the DataFrame as needed    df['Details'] = df['Video Link'].apply(get_video_details)    # Save DataFrame to CSV    df.to_csv(f'videos_{date_str}.csv', index=False)    # Clear the DataFrame for the next iteration    df = pd.DataFrame(columns=['Video Title', 'Video Link', 'Video Image', 'Video Duration'])    # Move to the next day    start_date += timedelta(days=1)
    

预览时标签不可点

微信扫一扫
关注该公众号



收藏