精华内容
下载资源
问答
  • 简易防火墙建置与流量统计 作者:nealy 1.前言 防火墙基本上是为了预防别人来存取你的网络,进而管制网络上资料的进出,防火墙一端连接外部的网络(经由真实的IP),另一端则连接内部的网络(虚拟的IP),将你内部...

    简易防火墙建置与流量统计

    作者:nealy

    1.前言
      防火墙基本上是为了预防别人来存取你的网络,进而管制网络上资料的进出,防火墙一端连接外部的网络(经由真实的IP),另一端则连接内部的网络(虚拟的IP),将你内部的网络与外部的网络给隔离开,防火墙成了进入你内部网络的唯一通道,因此任何进出的资料都要经过防火墙,再经由防火墙来决定是否能够通行,因此对于安全性更多加了一份保障。
      另外在本文中也介绍两个重量级的软件,方便监看网络流量和过往的网络封包,这也应是防火墙中的功能之一。

    2. 防火墙的种类
    2.1 封包过滤器
      封包过滤器的功能为取得每一个数据包,根据设定的规则去进行过滤,看是否允许数据包的传送或是拒绝封包,数据包过滤器存在于网络层,而且不会影响到数据包中的资料。在 RedHat Linux 中有一个 ipchains的 套件(6.0以上已内含),可以经由它来做数据包过滤器。
    2.2 代理服务器(Proxy firewalls)
      代理服务器又常被称为应用程序网关,允许通过防火墙间接进入互连网。

    3. 开始架设防火墙
      网络位址转换 NAT(Netword Address Translation)
      由于互连网的发展愈来愈蓬勃,电脑的数量也跟著急遽增加,导致目前 IP 不足,一 IP 难求的现象,所以解决之道要使用虚拟的 IP,相信虚拟 IP 必会成为未来的趋势。网络上保留了特定 IP 供给私人虚拟网络使用,在真实的网络上将不会找到这三组 IP,这些虚拟 IP 位址为:
      Class A 10.0.0.0 ~ 10.255.255.255
      Class B 172.16.0.0 ~ 172.31.255.255
      Class C 192.168.0.0 ~ 192.168.255.255
    3.1 查看网络卡状态
      首先必须要有两张网络卡介面,一张对外(使用真实 IP)eth1,一张对内(使用虚拟 IP)eth0,执行
      ifconfig -a
      会出现网络卡的设定值,看是否两张网络卡都有抓到。
      在这里要注意的是,可能你抓到的是 eth0 和 eth1的设定值是相反的,也就是说 eth0 对应到的是真实的 IP、eth1 对应到的是虚拟 IP,以笔者的实作,如果是这样的话,必须要做修改,否且网络会连不出去,在下面会提到。
      有可能在装好系统开机时,可能会卡在开机时的画面,可能是这样子的话,建议拿掉一张网络卡重开机,设定完之后再插上。
      ifconfig -A | more
      查看目前所启动的网络卡界面,目前为全设好的状态
    3.2 配置文件/etc/sysconfig/network
      若只有有一张网卡,那我们就直接手动安装另一张网卡,首先切换目录到 /etc/sysconfig 中,有一个档案 network,其内容为:
      其中的 FORWARD_IPV4 要设为 yes,才可以去启动 IP 伪装转换
    3.3 /etc/sysconfig/network-scripts/ifcfg-eth1
      接著到 /etc/sysconfig/network-scripts 目录中,会有下列档案
      目前我们要注意的是 ifcfg-eth0、ifcfg-eth1 这两个档案,在你安装完之后它只有 ifcfg-eth0 这个档案,并没有 ifcfg-eth1。首先将 ifcfg-eth0 复制成 ifcfg-eth1,执行
      cp ifcfg-eth0 ifcfg-eth1
      其中 ifcfg-eth1 为对外网络卡的设定档,依自己的设备去修改,其内容为:
      第一行指定网络卡的界面为:eth1
      第三行指定广播位址为:192.192.73.255
      第四行指定IP位址为:192.192.73.35
      第五行指定网络遮罩为:255.255.255.0
      第六行指定网络号码为:192.192.73.0
      第七行指定是否在开机后去启动网络卡界面
    3.4 配置文件/etc/sysconfig/network-scripts/ifcfg-eth0
      在这我们直接修改设定档 ifcfg-eth0,做为内部虚拟的网络卡介面,其内容为:
      第一行指定网络卡的界面为:eth0
      第三行指定广播位址为:192.168.1.255
      第四行指定IP位址为:192.168.1.1
      第五行指定网络遮罩为:255.255.255.0
      第六行指定网络号码为:192.168.1.0
      第七行指定是否在开机后去启动网络卡界面
      在这我们指定的内部网络,其中网络号码为 192.168.1.0,广播号为 192.168.1.255 所以真正可用的虚拟 ip 位址为 192.168.1.1 ~ 192.168.1.254。
    3.5 启动网卡
      启动 关闭
      执行 ifconfig eth0 up ifconfig eth0 down
      执行 ifconfig eth1 up ifconfig eth1 down
    3.6 设定路由表
      当上述的配置文件设定完、启动之后,我们必须替这两个网络去建立 route(路由)。
      route的命令为:
      route add -net network address netmask device
      网段 真实网段 虚拟网段
      网络号(network) 192.192.73.0 192.168.1.0
      网络号(network) 255.255.255.0 255.255.255.0
      网关(gateway) 192.192.73.1 192.168.1.1
      真实网段路由的设法:
      route add -net 192.192.73.0 netmask 255.255.255.0 gw 192.192.73.1
      虚拟网段路由的设法:
      route add -net 192.168.1.0 netmask 255.255.255.0 gw 192.168.1.1
      其路由表为:
      route -n
      这样子就安装好了两张网络卡,eth1 就做为对外部的网络卡(真实的 IP),eth0 做为对内部的网络卡(虚拟 IP)。
    3.7 测试
      以 eth1 做为对内的网络介面,其虚拟 IP 位址为 192.168.1.0 ~ 192.168.1.255,因为其第一个为网络号码,最后一个为广播号,所以可用的虚拟 IP 为 192.168.0.1 ~ 192.168.255.254,我们将闸道器(gateway)设为 192.168.0.1、子网络遮罩设为 255.255.255.0,将 192.168.1.2 ~ 192.168.1.254 之间的 IP 分配给内部的机器,之后内部的机器就可以互相通讯(‘ping’),但对于要连出去,还需要一个步骤,那就是使用一支程序,ipchains 来达成这个目的。先针对上述的问题,如果要让内部的机器连接到外部的网络,可先执行:
      /sbin/ipchains -A forward -s 192.168.0.0/24 - d 0.0.0.0/0 -j MASQ
      /sbin/ipchains -P forward DENY
      第一个命令会将来源 192.168.0.0 ~ 192.168.255.255 的封包使用 IP 伪装,将伪装的封包送转送给预设的路由,到外部的网络。
      第二个命令会将 forward 的预设政策设为 DENY。
      你可以将这两行命令加在 /etc/rc.d/rc.local 档案中,使其每次开机时执行。对于 ipchains 的使用,会在下面作更详细的说明。

    4. 封包过滤防火墙ipchains
      若你使用的是新版的 Linux,里面都会有 ipchains 的套件,直接使用就可以让你建立封包过滤防火墙。
    4.1 ipchains语法
      其选项、来源 ip、目的地 ip、port 可以不加,表示为全部。
      ipchains语法:
      ipchains 命令 input/forward/output 选项 源ip Port 目的ip port -j目标
      范例:
      ipchains -A input -p all -s 192.168.1.2 -d eef.oit.edu.tw 23 -j DENY
    4.2 ipchains命令
      可以有两种形式来指定,全名方式或缩写方式来表示
      --add -A 增加新的 ipchains 规则
      --delete -D 删除第一个 ipchains 规则,或某一个 ipchains 规则
      --insert -I 插入一个新 ipchains 规则,其插入需指定规则中的数字,如果数字为 1 表示为第一个。
      --replace -R 取代所选择的规则,其取代需指定规则中的数字。
      --list -L 列出所选择设定的 ipchains 规则,如果没有规则被指定,会列出所有的规则出来。
      --flush -F 将某个 ipchains 规则清除(例如:input、output、forward)这相当于去删除掉规则的功效。
      --zero -Z 将所有规则中的封包和位元组计数器归零它也可以去指定-L, --list (list) 选项,会先列出之前的资料,再列出归零的资料。
      --check -C 检查封包是否违反所设的规则,这是一个相当有用的测试,其是-s (来源), -d (目的地), -p(协定), -i (界面)更是必要。
      --new -N 产生一个新的使用者定义规则(user-defined)。
      --delete-chain -X 删除使用者定义的规则,如果没有指定任何的参数,它将会所有的定义的规则。
      --policy -P 设定目标的政策,只有 input,forward,output 可以去设定。
      --masquerade -M 这个选项可以去查看现在的伪装连接状况(须加上-L 选项),或是去设定 kernel 伪装参数(-S选项)。
      --set -S 设定伪装停止时间变数
      --help -h 列出描述命令语法的说明。
    4.3 ipchains参数选项
      可以有两种形式来指定,全名方式或缩写方式来表示
      使用’!’去定义相反的意义:惊叹号’!’有’not’的意义,有许多选项可以加上’!’去使用,表示不是的意思。
      例如: -s ! localhost
      说明: 表示除了localhost的来源位址都可以。
      --proto -p [!] protocol 协定:可以用数字或名字,例如:tcp、icmp、udp及all。
      范例:
      ipchains -A input -p tcp -s 192.168.1.3 -d eef.oit.edu.tw ftp -j DENY
      说明:源地址为 192.168.1.3 的主机不能对 eef.oit.edu.tw 这台主机做 ftp 的动作请求。
      --source -s [!] 指定来源位址。
      --source-port [!] port 指定来源的port。
      --destination -d [!] 指定目的地位址
      --destination-port [!] 指定目的地的port
      --icmp-type [!] 类型名称,指定ICMP类型
      --interface -i [!] 网络接口名称 ,lo、eth0、eth1。
      --jump -j 指定规则的目标,如果没有指定的话,这条规则算是没有用处。
      --numeric -n 取消DNS查询,直接使用IP
      --log -l 将关于ipchains的讯息记录起来,记录于/var/log/messages内。
      --verbose -v 完整模式,会列出界面名称、规则、TOS伪装,封包和位元组计数也会列出,须和-L一起使用。
      [!] --syn -y 只有当SYN设定时才会符合TCP封包
      --TOS -t Type Of Service
      [!] --version -V 列出ipchains的版本
      --bidirectional -b 双向模式5. 封包过滤防火墙ipchains的操作规则

    5 ipchains
    5.1 ipchains规则
      首先列出 ipchains 的规则表出来:
      ipchains -L
      分为三大部分:
      input chains:输入时的过滤规则例如:
      ipchains -A input -p tcp -s 192.168.1.3 -d 192.192.69.36 www -j DENY
      禁止 192.168.1.3 的来源位址去存取目的地 192.192.69.36 的网页
      forward chain :执行 IP 伪装的规则例如:
      ipchains -A forward -s 192.168.1.0/24 -d 0.0.0.0/24 -j MASQ

      启动 192.168.1.0~255 的 IP 伪装
      output chain:输出时的过滤规则(与 input 相反)例如:
      ipchains -A output -p tcp -s 192.192.69.36 www -d 192.168.1.3 -j DENY
      功用与 input 相同,只不过来源地址、目的地位址要对换
      每个所设的规则必须要去符合情况,以及要做些什么(目标)。
      举例来说,你可能要去拒绝从 IP 位址 192.168.1.3 的 ICMP 的封包,所以在这里我们的条件必须是协定 ICMP 及来源位址必须是 192.168.1.3,目的地为 192.192.69.39 这台主机(若不设则为全部),目标是’DENY’。
      指令写法为:ipchains -A input -p icmp -s 192.168.1.3 -d 192.192.73.35 -j REJECT
    5.2 命令的用法
      增加新的规则 -A:
      我们增加(-A)’input’的规则,要指明封包的来源位址(‘-s 192.168.1.3’)及协定(‘-p ICMP’),及应该结果为拒绝(‘-j DENY’)。
      范例:
      ipchains -A input -s 192.168.1.3 -p icmp -j DENY
      说明:拒绝来自192.168.1.3的icmp封包。
      删除规则 -D:
      我们删除 ipchains 规则有两种方法,首先我们知道在’input’的规则中只有一个(刚刚上面所增加的),也是第一个,所以我们可以使用数字来删除.。
      范例:
      ipchains -D input 1
      说明:删除input规则中的第一条。
      第二种方法是跟增加新的规则差不多,只不过是增加(-A)换成了删除(-D),这种方法在你如果设定了很多的规则的时候很好用,你可以不必去数它到底是第几个,只要照打一遍就行了,当然必须要一模一样才行。
      范例:
      ipchains -D input -s 192.168.1.3 -p icmp -j DENY
    5.3 指定协定种类
      使用 '-p'来指定协定种类,其中协定分为 'TCP' (Transmission Control Protocol)、'UDP' (User Datagram Protocol)、'ICMP' (Internet Control Message Protocol)或是全部(all),在这的协定写法没有分大小写,能以数字代替协定。
    在 /etc/protocols 中有注明各种协定,其中 tcp 为 6,udp 为 17,icmp 为 1。
      TCP(传输控制协定):
      位于应用层,如果应用程序(http、ftp)需要可靠性高的资料传输方式,那么就可以采用 TCP,TCP 会去检查资料是否安全到达,否则就重新发送资料。将传输的资料以 TCP 格式成为资料段,交由网络层的 IP 协定去处理,每一段资料含有一个检查值,接收者用它来验证资料是否受损,如果接收的资料没有损坏,会传回确认回去;如果资料有损会便会丢弃。TCP 具有可靠性及连线性。
      UDP(使用者资料协定):
      位于应用层,让应用程序直接使用封包传送服务,如 IP 提供的传送服务,UDP 协定并不会去检查封包是否安全到达目的地,因此传送速度快,但却是一个不可靠、非连线性的封包协定。
      ICMP(网络控制讯息协定):
      属于网际层的一部分,利用 IP 封包的传送,发送它的讯息,ICMP 发送的讯息执行了如侦测远端机器是否运作(‘ping’)、资料流的控制(当封包到得太快来不及处理时,目的主机传回一个 ICMP 的来源抑制讯息给发送者,告诉资料来源暂时停止传送封包)。
    ICMP 并没有 port,但它还是有它的选项参数可以使用,用来选择 ICMP 的类型。
    我们可以指定 ICMP 的名称或是数字代表(可以执行 ipchains -h icmp 去列出详细的名字)。
    5.4 指定UDP和TCP的port
      指定来源和目的地的IP位址 -s -d :
      来源(-s)和目的地(-d)的表示法有3种:
    使用完整的主称名称,例如:‘mouse.oit.edu.tw’ 或 ‘localhost’
    使用IP位址,例如:‘192.192.73.36’
    允许某范围的IP位址,例如:‘192.192.73.0/24’ 或 ‘192.192.73.0/255.255.255.0’ 两者是一样的,都是包含了192.192.73.0 ~ 192.192.73.255的IP位址。
      在斜线(‘/’)的数字代表了IP位址,‘/24’是255.255.255.0,‘/32’是 255.255.255.255,其中比较重要的是’0/0’,指全部。
      范例:
    ipchains -A input -s 0/0 -j DENY
      说明:
    ‘0/0’表示指定所有来源的 IP 位址都会被拒绝,你也可以不加’-s’参数,也是指定所有的来源 IP 位址。
    5.5 重要的指定目标
      除了去指定协定之外,还可以细分去指定它的 port
      例如:
      指所有来源位址的 port 80,其中 80 也可以用名字来表示’www’
      -p tcp -s 0.0.0.0/0 80
      假如要 TCP 封包可以到达 192.168.0.1 的任何 port,但除了 www 这个 port:
      -p tcp -d 192.168.0.1 ! www
      其中惊叹号’!’放置的位址也可以这样指定:
      -p tcp -d ! 192.168.0.1 www
    也可以表示为不是 192.168.0.1 和 www 的 port:
      -p tcp -d ! 192.168.0.1 ! www
    5.6 log 记录 /var/log/message
      若你有加上’-l’选项的话,关于 ipchains 的讯息会被记录在 /var/log/message 档案中,在标准的 Linux 系统上,kernel 的输出讯息经由 klogd(kernel logging daemon)所记录。其中的记录为:
      Jul 18 11:38:28 www kernel: Packet log: input REJECT eth0 PROTO=1
      (1) (2) (3) (4) (5) (6) (7) (8)
      192.168.1.3:8 192.168.1.1:0 L=60 S=0x00 I=7476 F=0x0000 T=32
      (9) (10) (11) (12) (13) (14) (15)
      ipchains记录:
      (1) 日期、时间
      (2) 主机名称
      (3) 使用 kernel 来记录
      (4) 指出从 ipchains 产生讯息
      (5) 所使用的规则:input
      (6) 规则的目标:REJECT
      (7) 封包所经过的网络卡界面:eth0
      (8) 协定号码:1(ICMP)、6(TCP)、17(UDP)
      (9) 来源 IP 位址和 port
      (10) 目的地 IP 位址和 port
      (11) 封包的长度
      (12) TOS(Type of service)
      (13) IP 的 ID
      (14) 资料段偏移

    6. ipchains的范例
      在这里要提醒使用者,千万不要用远端登入来使用ipchains,因为常会不小心就把自个儿给关在房外,进不了家,有时候为了要测试关掉 telnet 的功能,就这样连自己也 telnet 不进去了,当然跑到主机前去修改是免不了的事。
      关闭所有的服务:
      基于安全的理由,我们要把所有对内、对外的窗口给统统关闭起来,执行下列指令将会将进入、输出、转送封包的预设政策设为拒绝,这一步最好放在你最后的时候再来做,因为如果先设了所有 DENY 的规则,则后来设的 ACCEPT 规则会被先前的 DENY 给取代。
      ipchains -P input DENY
      ipchains -P forward DENY
      ipchains -P output DENY
      启动虚拟 IP 的伪装服务:
      将内部虚拟 IP192.168.0.0 ~ 255 启动 IP 封包转送到外界的网络,使之可以连到外界的任何地方去。
      ipchains -A forward -s 192.168.0.0/24 -d 0.0.0.0/0 -j MASQ

    7. 使用ipchains-save、ipchains-restore 储存设定值
      ipchains 有二支程序去储存、反存我们所设的规则,ipchains-save 可以储存一个或所有的规则,它是指令档,会先去读取 ipchains 的设定档并且储存成档案起来,使用时可以加入 -v 参数,列出详细的动作。
      范例:
      ipchains-save -v > filename
      结果:
      若要恢复ipchains规则,执行下面指令
      使用webmin 管理 ipchains
      看了上述的说明或许读者会感到十分困难,其实我们也可以使用 webmin 的 Third Party Modules 中 IPchains Firewalling 来管理,如下图所示:
      其中有 Disable, Low, Medium, High, Full 五个安全等级,或者可自定规则。

    8. 流量统计
      http://www.ntop.org/ 是一个网络使用状况监测软件,在互动式模式下,ntop 会将网络的使用状况显示在使用者的终端机画面上。在 Web 模式中,ntop 会像 Web Server 一样产生出内含网络使用状况的网页传回到使用者的浏览器上。在 RedHat 7.0 powertools 中有 ntop-1.3.1.-2.i386.rpm,所以在 RedHat 7.0 下使用
      rpm -ivh ntop-1.3.1.-2.i386.rpm
      安装,然后用 ntop -d 执行即可,执行 web 输出画面如下:(笔者使用的是 1.1 版)

    9. 流量记录
      Snort (http://www.snort.org)是一个精巧的网络入侵侦测软件(IDS)。具有执行即时流量分析与封包纪录功能的特性,提供了协定的分析,封包内容的搜寻。可用来侦测各种不同的攻击与调查 (如 buffer overflows,stealth port scans,CGI attacks,SMB probes,OS fingerprinting attempts 等等)。Snort 使用 flexible rule based language 来设定那些流量应该被收集,那些应该放行。他也具有模组化的侦测引擎。Snort 具有即时警告的特性,其警告的机制可使用 syslog,使用者自订的档案,UNIX socket 或是使用 Samclient 传递 WinPopup 讯息给 Windows client 端的使用者。(取自 LinuxFAB.cx)
      取得 snort-1.6.3.tar.gz ,然后执行下列步骤安装:
      tar xvfz snort-1.6.3.tar.gz
      cd snort-1.6.3
      ./configure
      make
      make install
      在此笔者只介绍封包纪录功能,其他功能日后再述。假定我们要将记录档至于首页上可以执行 snort -C -d -D -l /home/httpd/html/snort,结果如下:
      当然笔者有作一些安全上的管理,否则所有网络的机密便曝光了,况且因为记录所有资料所以档案会长的很快,所以如果你真要如此记录,请注意控制的细节。底下我们再深入看看。
      看到 USER 了吗?接下来当然是 PASS …….

    转载于:https://www.cnblogs.com/F4ncy/archive/2005/01/03/85756.html

    展开全文
  • nlbwmon流量统计程序的Luci界面需要的包含设备信息的json文件。 注意:本文件可能不是最新的,源文件见https://raw.githubusercontent.com/jow-/oui-database/master/oui.json
  • 利用OpenCV实现对车流量统计

    千次阅读 2020-07-14 09:45:29
    开始正题——OpenCV的车流量统计。 调试平台 OpenCV 4.2 VS 2019 汽车识别原理——背景/前景分割算法 如今,检测和提取车辆时候,常用的方法有MOG2算法和KNN算法。MOG算法是以高斯混合模型(GMM)为基础的背景/...

    此文在我的个人博客地址https://sublimerui.top/archives/48ab4a6e.html

    闲话少絮。开始正题——OpenCV的车流量统计。

    调试平台

    • OpenCV 4.2
    • VS 2019

    汽车识别原理——背景/前景分割算法

    如今,检测和提取车辆时候,常用的方法有MOG2算法和KNN算法。MOG算法是以高斯混合模型(GMM)为基础的背景/前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每一个像素选择一个合适数目的高斯分布。其主要原理为:在一个固定位置和角度固定的视频或图像中,提取分割图像或视频中运动的成分。此算法使用背景建模的方式,将整张图片或一帧视频分为前景和后景。此算法运行时,会将动态的前景与静止的后景相减,得出结果即为徐提取的运动物体的图像。

    K最近邻算法(KNN)是属于机器学习的一种算法。其主要原理为:给定一个已训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近(注:衡量邻近的标准以具体选取的某个特征而言,例如下面示意图中使用的特征为欧式距离)的K个实例,这K个实例的多数属于某个类,则判定该输入实例同属此类。如下图所示:训练者取k值,计算以欧氏距离k为半径的圆内其他类别的个数,图中中心小红点以k为半径的圆内三角形个数最多,则判定中心小红点为三角形。

    KNN

    整体结构

    整体流程框架图

    本程序的主要运行流程为:程序运行开始,首先从文件中获取上次保存的光流量检测矩形框数据(顶点坐标和矩形的长宽);其后,分别初始化背景提取对象,使用MOG2和KNN两种算法。与此同时,建立一个鼠标回调函数,用于捕获鼠标左键(绘制矩形框)、中键(取消操作)和右键(保存矩形框数据到文件)的操作。

    此后,程序进入主循环状态。程序循环从视频中获取一帧的图像,先进行压缩处理,以提高后续运算速度。之后,将这一帧图片从RGB转为灰度图片。为了祛除灰度后可能出现的小毛刺杂点,再进行平滑滤波处理。此后,分别通过MOG2和KNN算法提取前景,并将提取后的视频显示出来。与此同时,获取每个矩形框中积分后的亮度和。

    最后,两个算法中,分别将实时得到的亮度和与所预设的阈值进行比较,当满足条件后,便认为一辆汽车通过矩形框,使得计数器加一。如此重复,统计整个视频中的车流量。

    流程图

    主要参数

    1. int detectTHD

    此参数为预设的亮度阈值。确定是否有汽车经过检测框中,其需要联合上一帧积分亮度和本次积分亮度后综合做出决定。

    1. cv::Size newSize(frame.cols / 2, frame.rows / 2);

    此参数可以储存一帧视频缩小后的大小。

    1. cv::Mat showMat;

    此参数用于储存最终显示的图像矩阵。

    主要函数

    1. static void onMouse(int event, int x, int y, int flags, void\*)

    此函数主要用于检测鼠标左键、滑轮(中键)和右键的一些操作,用于绘制矩形检测框。

    1. cv::resize(frame, newframe, newSize);

    此函数主要用于缩小原视频比例,提高计算机运算速度。

    1. bgMOG2-\>apply(greyFrame, mog2RES, update_bg_model ? -1 : 0);以及bgKNN-\>apply(greyFrame, KNN, update_bg_model ? -1 : 0);

    apply函数主要用于两种算法的前景提取。此后,前景提取后的这帧视频保存于bgMOG2和bgKNN之中。

    1. cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3);

    此函数主要用于前景提取后在其上面绘制矩形框。

    1. cv::integral(subMat, sumMat, CV_32S);

    计算车道矩形框亮度积分图。

    1. cv::putText();

    此函数可以按照要求,在视频图像上显示文字和统计数字。

    测试结果

    1. 功能测试

    进行车流量统计前,应当首先根据矩形框中出现车辆时,估算其亮度平均值作为亮度阈值,使其设定为一个较为合适的值,增强检测的灵敏性。由下图可知,当程序运行后,通过手动标记车道检测区域,得到2个矩形检测区。每次获得矩形中的积分亮度结果,当上从亮度结果大于阈值,且此次亮度结果小于阈值时,使车辆统计结果加一。

    功能测试

    1. 算法处理时间

    由测试结果可知,相较于MOG2算法,KNN算法在运算处理上花费更多的时间,KNN算法时间约为MOG2时间的2倍。同时,算法处理总时间也相对较长,除了两个算法所带来的开销外,仍有其他附加代码所花费的时间。

    时间处理

    1. 缩放图片前后比较

    程序中,可以使用cv::resize();函数进行图片的压缩,缩放图片对于检测速度有较大的影响。不使用缩放时,将视频中原始一帧的图像进行计算,经测试发现,处理速度很慢,显示的图片有明显的脱帧和卡顿现象,CPU占用率相当高,与压缩后(上图)相比,无论使用MOG2还是KNN算法,其处理时间均成倍增加。下图为不使用缩小图片尺寸条件下的处理时间。

    时间对比

    1. 矩形检测区亮度阈值的影响

    阈值设置的合理性也是车流量检测准确性的一个重要指标。过高或过低的阈值均不能很好地反映车辆的经过和实现的统计。阈值过低,将会把视频中环境干扰噪声和其他运动对象(如三轮车和行人)当做汽车统计,使得统计结果偏大;同理,阈值过高,将很难检测到车辆的通过,当车辆进过矩形检测区时,无法实现车辆的统计。本程序中,经过检测矩形框内平均值的大致估算,将阈值detectTHD设置为900000。

    下图中显示了当阈值设定过小时的状况。右端矩形框(右车道)经过了一辆电动车,程序误认为汽车,并错误地将统计结果L1的值从1加为2。

    阈值过小

    同理,当阈值设置过大,也会造成统计的不准确。下图显示了当阈值设定过大时的状况。可以发现,即使是车辆经过了矩形框,车辆统计变量L0和L1仍为0。

    阈值过大

    结论

    由以上分析可知,汽车流量的统计可以借助设定矩形区域内的亮度阈值来确定。为识别运动对象(汽车)的状态,可使用背景提取算法,如本软件中使用到的MOG2和KNN算法。通过比较不同算法间的处理时间,我们应当合理选择一种耗时短且提取车辆准确性高的一种算法。此外,识别统计车流量较为重要的一环便是设置合理的亮度阈值,亮度阈值设置的合理性直接关系到车流量统计准确性。

    附:程序源代码

    此项目Github地址: https://github.com/cwxyr/traffic-detection

    #include "stdafx.h"
    #include <Windows.h>
    #include <string>
    #include <opencv2/core.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/features2d.hpp>
    #include <opencv2/video.hpp>
    
    #ifdef _DEBUG
    #pragma comment(lib, "opencv_world420d.lib") 
    #else
    #pragma comment(lib, "opencv_world420.lib") 
    #endif
    
    //===【鼠标事件回调函数】===
    int detectTHD = 900000;		//亮度阈值:有车辆经过的;
    std::vector<int>		myLanneLightSum_Last;			//车道亮度和:上一帧的
    std::vector<int>		myLanneVihicleCnt;				//车道车辆计数器
    
    std::vector<cv::Rect>		myLanneRect;			//车道矩形框;显示为红色;
    std::vector<cv::Point>		myMousePoints;		//鼠标点向量;显示为蓝色;
    int	myMouseEventBusy = 0;							//鼠标回调事件忙:简单的资源锁
    static void onMouse(int event, int x, int y, int flags, void*)
    {
    	myMouseEventBusy = 1;
    	cv::Point  mPoint;
    	cv::Rect mRect;
    	switch (event)
    	{
    	case cv::EVENT_LBUTTONDOWN:		//左键按下:增加myMousePoints中的点数
    		mPoint = cv::Point(x, y);
    		myMousePoints.push_back(mPoint);	//将当前鼠标点推送到向量中;
    		if (myMousePoints.size() > 4)
    			myMousePoints.erase(myMousePoints.begin());	//保证myMousePoints向量中节点数不大于4;
    		break;
    	case cv::EVENT_RBUTTONDOWN:		//右键键按下:将myMousePoints中的4个点推送到矩形框向量myLanneRect
    		if (myMousePoints.size() == 4)
    		{
    			int Xmin = 100000; int Ymin = 100000;
    			int Xmax = 0; int Ymax = 0;
    			for (int k = 0; k < 4; k++)
    			{
    				Xmin = std::min(Xmin, myMousePoints.at(k).x);
    				Ymin = std::min(Ymin, myMousePoints.at(k).y);
    				Xmax = std::max(Xmax, myMousePoints.at(k).x);
    				Ymax = std::max(Ymax, myMousePoints.at(k).y);
    			}//for k   <<< === 用四个点构成矩形框的参数
    			mRect = cv::Rect(Xmin, Ymin, Xmax - Xmin, Ymax - Ymin);		//构成矩形框
    			myLanneRect.push_back(mRect);
    			myLanneLightSum_Last.push_back(0);
    			myLanneVihicleCnt.push_back(0);
    			myMousePoints.clear();  //清除鼠标点向量
    
    		}///if
    		break;
    	case cv::EVENT_MBUTTONDOWN:		//中间键键按下:删除myMousePoints中的一个点;myMousePoints为空时,删除myLanneRect中的节点;
    		printf("EVENT_MBUTTONDOWN\n");
    		if (myMousePoints.size() > 0)
    			myMousePoints.pop_back();
    		else
    		{
    			myLanneRect.pop_back();
    			myLanneLightSum_Last.pop_back();
    			myLanneVihicleCnt.pop_back();
    		}
    		break;
    
    	}/switch
    myMouseEventBusy = 0;
    return;
    }
    
    int main(int argc, char* argv[])
    {
    	char errorMSG[256];
    	char curPathName[384] = ""; char curModulerPath[384] = "";
    	GetCurrentDirectory(383, curModulerPath); 
    	printf("Line39: curModulerPath = %s\n", curModulerPath);
    
    	//=======读取标记的矩形框文件内容到myLanneRect:=======
    	#ifndef READ_RECT_FILE
    		FILE *pFILE = fopen("MarkRect.txt", "r");
    		if (pFILE != NULL)
    		{
    			cv::Rect  mRect;
    			while (fgets(errorMSG, 255, pFILE) != NULL)
    			{
    				int rtn = sscanf(errorMSG, "%d %d %d %d", &mRect.x, &mRect.y, &mRect.width, &mRect.height);
    				if (rtn == 4) {
    					myLanneRect.push_back(mRect);
    					myLanneLightSum_Last.push_back(0);
    					myLanneVihicleCnt.push_back(0);
    					}
    			}
    			fclose(pFILE);
    		}///if
    	#endif // !READ_RECT_FILE
    
    	std::string  imgName = "video-02.mp4";
    	char FilePath[384];
    	if (strlen(curPathName) > 0)
    		sprintf(FilePath, "%s\\%s", curPathName, imgName.c_str());	//图片文件路径
    	else
    		sprintf(FilePath, "%s", imgName.c_str());	//图片文件路径
    
    	//==【01】== 打开视频文件或摄像头
    		cv::VideoCapture cap; //VideoCapture类实例化,使用缺省摄像头
    
    		if (0 && "UsingCam")
    			cap.open(0);
    		else
    			cap.open(FilePath);
    		if (!cap.isOpened()) // check if we succeeded
    		{
    			printf("error#73: 打开设备或文件失败,检查是否存在!回车退出!\n路径=%s\n", FilePath);
    			fgets(FilePath, 127, stdin);
    			return -1;
    		}
    		cv::Mat frame, newframe, greyFrame, floatFrame, lastFrame, frame2, mog2RES, KNN, out_frame, avgFrame;
    		std::vector<cv::Mat> diffIMGvec;
    
    	//==【02】== 创建运动视频背景提取对象:用于分离背景和运动对象
    		cv::Ptr<cv::BackgroundSubtractorMOG2> bgMOG2 = cv::createBackgroundSubtractorMOG2();
    		cv::Ptr<cv::BackgroundSubtractorKNN> bgKNN = cv::createBackgroundSubtractorKNN();
    		bgMOG2->setVarThreshold(30);
    		bool update_bg_model = true;
    	//==【03】== 命名几个显示窗口
    		cv::namedWindow("RawWnd", cv::WINDOW_NORMAL);
    		cv::setMouseCallback("RawWnd", onMouse, &newframe);		//设置鼠标事件回调函数("RawWnd"窗口的):同时传递彩色图像指针;
    		cv::namedWindow("Out_KNN", cv::WINDOW_NORMAL);
    		cv::namedWindow("Out_MOG2", cv::WINDOW_NORMAL);
    
    	int frameNums = 0;
    	for (;;)
    	{
    		frame.rows = 0;
    		double t1 = (double)cv::getCPUTickCount();  //开始统计时间
    		cap.read(frame);
    		if (frame.rows == 0)
    			break;
    		cv::Size newSize(frame.cols / 2, frame.rows / 2);  //压缩图像,将其尺寸缩小
    		cv::resize(frame, newframe, newSize);
    		cv::cvtColor(newframe, greyFrame, cv::COLOR_RGB2GRAY);  //转换为灰度图
    		cv::blur(greyFrame, greyFrame, cv::Size(3, 3));		//使用平滑运算
    	
    		double t2 = (double)cv::getCPUTickCount();
    		bgMOG2->apply(greyFrame, mog2RES, update_bg_model ? -1 : 0);   //使用MOG2算法提取前景
    		double t3 = (double)cv::getCPUTickCount();  //获取处理时间
    
    		double t4 = (double)cv::getCPUTickCount();
    		bgKNN->apply(greyFrame, KNN, update_bg_model ? -1 : 0);			//使用KNN算法提取前景
    		double t5 = (double)cv::getCPUTickCount();  //获取处理时间
    		printf("MOG2 Time = %.3fms\n", 1e0 * (t3 - t2) / (double)cv::getTickFrequency());
    		printf("KNN Time = %.3fms\n", 1e0 * (t5 - t4) / (double)cv::getTickFrequency());
    		printf("Total Time = %.3fms\n", 1e0 * (t5 - t1) / (double)cv::getTickFrequency());
    		printf("--------------------\n");
    
    		if (!mog2RES.empty())  //计算MOG2算法下矩形框的积分亮度值
    		{
    			cv::Mat showMat;
    			mog2RES.copyTo(showMat);
    			if (myMouseEventBusy == 0)
    			{
    				for (int k = 0; k < myLanneRect.size(); k++)
    				{
    					cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3);
    					cv::Mat subMat = mog2RES(myLanneRect.at(k));	//再MOG2的前景提取结果中,取车道标记矩形框区域为subMat矩阵
    					cv::Mat sumMat;		//积分图 == subMat的积分矩阵
    					cv::integral(subMat, sumMat, CV_32S);		//设置积分矩阵的数据类型为uint;
    					int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值,就是矩形框内亮度和;
    					sprintf(errorMSG, "sum = %d;", sumValue);
    					cv::putText(showMat, errorMSG, cv::Point(myLanneRect.at(k).x, myLanneRect.at(k).y + 4), 0.2, 1, cv::Scalar(255, 0, 0), 2);//显示矩形框内的亮度和;
    
    				}//for k
    			}if
    			cv::imshow("Out_MOG2", showMat);
    		}
    
    		if (!KNN.empty())   //计算KNN算法下矩形框的积分亮度值
    		{
    			cv::Mat showMat;
    			KNN.copyTo(showMat);
    			if (myMouseEventBusy == 0)
    			{
    				for (int k = 0; k < myLanneRect.size(); k++)
    				{
    
    					cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3);
    					cv::Mat subMat = KNN(myLanneRect.at(k));	//再KNN的前景提取结果中,取车道标记矩形框区域为subMat矩阵
    					cv::Mat sumMat;		//积分图 == subMat的积分矩阵
    					cv::integral(subMat, sumMat, CV_32S);		//设置积分矩阵的数据类型为uint;
    					int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值,就是矩形框内亮度和;
    					sprintf(errorMSG, "sum = %d;", sumValue);
    					cv::putText(showMat, errorMSG, cv::Point(myLanneRect.at(k).x, myLanneRect.at(k).y + 4), 0.2, 1, cv::Scalar(255, 0, 0), 2);//显示矩形框内的亮度和;
    				}//for k
    			}if
    			imshow("Out_KNN", showMat);
    		}			
    
    		//===>>> 显示原始图像:显示车道标记信息 + 矩形框内亮度和 + 车流量统计
    		#ifndef SHOW_RAW_MAT
    			cv::Mat showMat;
    			newframe.copyTo(showMat); //矩阵复制
    			sprintf(errorMSG, "mL=add Point; mR=add Rect; mM=delete Point;");
    			cv::putText(showMat, errorMSG, cv::Point(8, 32), 0.2, 1, cv::Scalar(255, 0, 0), 2);//显示提示信息;
    			//==>> 显示车道矩形框为红色 + 车流量统计 + 车流量显示
    			if (myMouseEventBusy == 0)
    			{
    				for (int k = 0; k < myLanneRect.size(); k++)
    				{
    					cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(0, 0, 255), 3);
    					cv::Mat subMat = mog2RES(myLanneRect.at(k));	//再MOG2的前景提取结果中,取车道标记矩形框区域为subMat矩阵
    					cv::Mat sumMat;		//积分图 == subMat的积分矩阵
    					cv::integral(subMat, sumMat, CV_32S);		//设置积分矩阵的数据类型为int,计算车道矩形框内亮度积分图;
    					int sumValue = (int)sumMat.at<int>((int)sumMat.rows - 1, (int)sumMat.cols - 1);  //获取积分图右下角的值,就是矩形框内亮度和;
    					sprintf(errorMSG, "sum = %d;", sumValue);
    					cv::putText(showMat, errorMSG, cv::Point(myLanneRect.at(k).x, myLanneRect.at(k).y + 4), 0.2, 1, cv::Scalar(255, 255, 0), 2);//显示矩形框内的亮度和;
    					//===>>> 车流量统计:
    					if (myLanneLightSum_Last.at(k) > detectTHD && sumValue <= detectTHD)
    					{
    						//:: 车辆通过了矩形框:上一帧亮度和大于阈值,本帧亮度和小于阈值;车辆计数器自加;
    						myLanneVihicleCnt.at(k)++;
    						myLanneLightSum_Last.at(k) = sumValue;
    					}
    					else 
    						myLanneLightSum_Last.at(k) = sumValue;  //存储当前亮度和到myLanneLightSum_Last				
    				}//for k
    
    				//===>> 车流量统计结果显示
    				cv::Mat topareaMat = showMat(cv::Rect(0, 0, showMat.cols, 75));		//最顶部48行置0;
    				topareaMat *= 255;
    
    				std::string strVihicleCnt = "VihicleCnt: ";
    				for (int k = 0; k < myLanneRect.size(); k++)
    				{
    					sprintf(errorMSG, "L%d = %d;", k, myLanneVihicleCnt.at(k));
    					strVihicleCnt += errorMSG;
    				}
    				cv::putText(showMat, strVihicleCnt.c_str(), cv::Point(8, 64), 0.2, 1, cv::Scalar(0, 0, 255), 2); //流量统计显示到彩色图片上
    
    			}if
    			 //==>> 显示正在标记的坐标点为蓝色:
    			if (myMouseEventBusy == 0)
    			{
    				for (int k = 1; k < myMousePoints.size(); k++)
    				{
    					cv::line(showMat, myMousePoints.at(k - 1), myMousePoints.at(k), cv::Scalar(255, 0, 0), 15);
    				}//for k
    				if(myMousePoints.size() == 4)
    					cv::line(showMat, myMousePoints.at(0), myMousePoints.at(3), cv::Scalar(255, 0, 0), 2);
    			}if
    
    			imshow("RawWnd", showMat);
    		#endif // SHOW_RAW_MAT
    		int keycode = cv::waitKey(100);		//等待100ms
    		if (keycode == 'q')
    			break;
    		else if (keycode == ' ')
    		{
    			update_bg_model = !update_bg_model;
    			printf("Learn background is in state = %d\n", update_bg_model);
    		}
    		else if (keycode == 'w')
    		{
    			//写文件:记录标记的矩形框到文件中:
    			#ifndef WRITE_RECT_FILE
    			FILE *pFILE = fopen("MarkRect.txt", "w");
    			if (pFILE != NULL)
    			{
    				for (int k = 0; k < myLanneRect.size(); k++) {
    					fprintf(pFILE, "%d %d %d %d\n", myLanneRect.at(k).x, myLanneRect.at(k).y, myLanneRect.at(k).width, myLanneRect.at(k).height);
    				}
    				fclose(pFILE);
    			}///if
    			#endif // !WRITE_RECT_FILE
    
    		}
    		frameNums++;
    		Sleep(50);
    	}//for 
    	cap.release();
    	return 0;
    }
    
    展开全文
  • 沙漏流量瓶,针对现在流量监控软件的不精确而推出的,本软件使用了友好,动感的界面,给用户带来一种时尚的气息,本软件...需要流量统计功能的朋友可以下载看一下,有意见欢迎在评论中指出。)编译版本2.3.3 编码GBK
  • 1.用户行程的取消率 Trips表中存所有出租车的行程信息。每段行程有唯一键 Id,Client_Id 和Driver_Id 是Users表中 Users_Id 的外键。Status 是枚举类型,枚举成员为 (‘completed’, ‘cancelled_by_driver’, ...

    1.用户行程的取消率

    Trips 表中存所有出租车的行程信息。每段行程有唯一键 Id,Client_Id 和 Driver_Id 是 Users 表中 Users_Id 的外键。Status 是枚举类型,枚举成员为 (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’)。

    +----+-----------+-----------+---------+--------------------+----------+
    | Id | Client_Id | Driver_Id | City_Id |        Status      |Request_at|
    +----+-----------+-----------+---------+--------------------+----------+
    | 1  |     1     |    10     |    1    |     completed      |2013-10-01|
    | 2  |     2     |    11     |    1    | cancelled_by_driver|2013-10-01|
    | 3  |     3     |    12     |    6    |     completed      |2013-10-01|
    | 4  |     4     |    13     |    6    | cancelled_by_client|2013-10-01|
    | 5  |     1     |    10     |    1    |     completed      |2013-10-02|
    | 6  |     2     |    11     |    6    |     completed      |2013-10-02|
    | 7  |     3     |    12     |    6    |     completed      |2013-10-02|
    | 8  |     2     |    12     |    12   |     completed      |2013-10-03|
    | 9  |     3     |    10     |    12   |     completed      |2013-10-03| 
    | 10 |     4     |    13     |    12   | cancelled_by_driver|2013-10-03|
    +----+-----------+-----------+---------+--------------------+----------+
    

    Users 表存所有用户。每个用户有唯一键 Users_Id。Banned 表示这个用户是否被禁止,Role 则是一个表示(‘client’, ‘driver’, ‘partner’)的枚举类型。

    +----------+--------+--------+
    | Users_Id | Banned |  Role  |
    +----------+--------+--------+
    |    1     |   No   | client |
    |    2     |   Yes  | client |
    |    3     |   No   | client |
    |    4     |   No   | client |
    |    10    |   No   | driver |
    |    11    |   No   | driver |
    |    12    |   No   | driver |
    |    13    |   No   | driver |
    +----------+--------+--------+
    

    写一段 SQL 语句查出 2013年10月1日 至 2013年10月3日 期间非禁止用户的取消率。基于上表,你的 SQL 语句应返回如下结果,取消率(Cancellation Rate)保留两位小数。

    +------------+-------------------+
    |     Day    | Cancellation Rate |
    +------------+-------------------+
    | 2013-10-01 |       0.33        |
    | 2013-10-02 |       0.00        |
    | 2013-10-03 |       0.50        |
    +------------+-------------------+
    select t.Request_at Day,(round(count(if(status!="completed",status,null))/count(status),2) )  `Cancellation Rate` 
    from  Users u inner join Trips t
    on  u.Users_id = t.Client_Id and  u.banned != 'Yes'
    where  t.Request_at >= '2013-10-01' and  t.Request_at <= '2013-10-03'
    group by  t.Request_at

    说明:

      IF(expr1,expr2,expr3)

      如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。

      IF() 的返回值为数字值或字符串值

    2.人流量高峰时段

    每日人流量信息被记录在:序号 (id)、日期 (date)、 人流量 (people)

    请编写一个查询语句,找出高峰期时段,要求连续三天及以上,并且每天人流量均不少于100。

    例如,表 stadium

    +------+------------+-----------+
    | id   | date       | people    |
    +------+------------+-----------+
    | 1    | 2017-01-01 | 10        |
    | 2    | 2017-01-02 | 109       |
    | 3    | 2017-01-03 | 150       |
    | 4    | 2017-01-04 | 99        |
    | 5    | 2017-01-05 | 145       |
    | 6    | 2017-01-06 | 1455      |
    | 7    | 2017-01-07 | 199       |
    | 8    | 2017-01-08 | 188       |
    +------+------------+-----------+
    

    对于上面的示例数据,输出为:

    +------+------------+-----------+
    | id   | date       | people    |
    +------+------------+-----------+
    | 5    | 2017-01-05 | 145       |
    | 6    | 2017-01-06 | 1455      |
    | 7    | 2017-01-07 | 199       |
    | 8    | 2017-01-08 | 188       |
    +------+------------+-----------+
    

    Note:
    每天只有一行记录,日期随着 id 的增加而增加。

    select distinct s1.* from stadium s1,stadium s2,stadium s3 
    where 
        s1.people>=100 and s2.people>=100 and s3.people>=100
    and (
        (s1.id = s2.id-1 and s2.id=s3.id-1) or
        (s1.id = s2.id-1 and s1.id=s3.id+1) or
        (s1.id = s2.id+1 and s2.id=s3.id+1) 
    ) order by s1.id

     

    转载于:https://www.cnblogs.com/baby123/p/10838486.html

    展开全文
  • 流量监控流量沙漏瓶

    2021-03-16 16:49:46
    流量监控流量沙漏瓶针对现在流量监控软件的不精确而推出的,本软件使用了友好,动感的界面,给用户带来一种时尚的气息,...需要流量统计功能的朋友可以下载看一下,有意见欢迎在评论中指出。)编译版本2.3.3 编码GBK。
  • 流量监控流量沙漏瓶针对现在流量监控软件的不精确而推出的,本软件使用了友好,动感的界面,给用户带来一种时尚的气息...需要流量统计功能的朋友可以下载看一下,有意见欢迎在评论中指出。)编译版本2.3.3 编码GBK。 
  • PV Page View,页面访问量,指页面浏览的次数,用以衡量网站用户访问的网页数量。也就是曝光量。一般来说,PV与来访者的数量成正比,但是PV并不直接决定...PV是指页面刷新的次数,每一次页面刷新,就算做一次PV流量...
    • PV

    Page View,页面访问量,指页面浏览的次数,用以衡量网站用户访问的网页数量。也就是曝光量。一般来说,PV与来访者的数量成正比,但是PV并不直接决定页面的真实来访者数量,如同一个来访者通过不断的刷新页面,也可以制造出非常高的PV。具体的说,PV值就是所有访问者在24小时(0点到24点)内看了某个网站多少个页面或某个网页多少次。PV是指页面刷新的次数,每一次页面刷新,就算做一次PV流量。


    • UV

    UniqueVisitor,独立访客数,指一天内访问某站点的人数,以cookie为依据。1天内同一访客的多次访问只记录为一个访客。通过IP和cookie是判断UV值的两种方式。通常情况下是依靠浏览器的cookies来确定访客是否是独立访客(之前是否访问过该页面),在同一台电脑上使用不同的浏览器访问或清除浏览器缓存后重新访问相同的页面,也相当于不同的访客在访问,会导致UV量增加。

    • 用Cookie分析UV值

    当客户端第一次访问某个网站服务器的时候,网站服务器会给这个客户端的电脑发出一个Cookie,通常放在这个客户端电脑的C盘当中。在这个Cookie中会分配一个独一无二的编号,这其中会记录一些访问服务器的信息,如访问时间,访问了哪些页面等等。当你下次再访问这个服务器的时候,服务器就可以直接从你的电脑中找到上一次放进去的Cookie文件,并且对其进行一些更新,但那个独一无二的编号是不会变的。

    • 怎么标记用户?

    cookie+uuid,判断客户端(即浏览器)是否存在cookie,不存在则分配uuid并写入cookie
    IP,用IP来标记用户,则统计出来的uv数会等于IP数,个人认为有点奇怪,但确实看过相关资料有此方案. 此方案不需要依赖cookie。
    注意到使用 cookie+uuid 方案还有一些细节:要写磁盘cookie还是内存cookie? cookie多久失效?答:个人认为要写磁盘且失效时间设置较长的时间。



    • 新UV

    新访客,新UV指一天内的新增用户数

    实现:参考上述UV的实现方式,只要新分配uuid,则说明是新用户



    • IP

    独立IP数,指一天内使用不同IP地址的用户访问网站数量,同一IP无论访问了几个页面,独立的IP数均为1.但是假如说两台机器访问而使用的是同一个IP,那么只能算是一个IP的访问。

    每次请求的IP,跟当天已经统计在内的IP集合进行比较,不重复则加1,重复则忽略,跨天后IP集合清空。
    IP和UV之间的数据不会有太大的差异,通常UV量和比IP量高出一点,每个UV相对于每个IP更准确地对应一个实际的浏览者。

    • ①UV大于IP

    这种情况就是在网吧、学校、公司等,公用相同IP的场所中不同的用户,或者多种不同浏览器访问您网站,那么UV数会大于IP数。

    • ②UV小于IP

    在家庭中大多数电脑使用ADSL拨号上网,所以同一个用户在家里不同时间访问您网站时,IP可能会不同,因为它会根据时间变动IP,即动态的IP地址,但是实际访客数唯一,便会出现UV数小于IP数。



    • UIP

    Unique IP,独立IP,和UV类似,正常情况下,同一个IP可能会有很多个UV,同一个UV只能有一个IP。


    • VV

    Visit View,访问次数(或称访问频次、打开次数、会话数),用以记录所有访客一天内访问量多少次网站。当访客完成所有的浏览并最终关掉该网站的所有页面时,便完成了一次访问,同一访客一天内可能有多次访问行为,访问次数累计。

    实现:内存cookie+失效时间30分钟,查看浏览器是否存在cookie,不存在则分配会话ID(sid),并写入到cookie,在整个会话期间都携带sid,判断一天内不重复的sid数即可

    怎么样为一次?业界一般定义30分钟,符合下图:
    在这里插入图片描述

    • CPC

    Cost PerClick,每次点击费用,即点击单价。


    • CPM

    Cost Per Mile千次展示费用,即广告展示一千次需要支付的费用。


    • RPM

    Revenue PerMille 千次展示收入,和CPM类似,RPM是针对广告展示商(比如Adsense商户)而言的。


    • CTR

    Click-throughRate,点击率,点击次数占展示次数的百分比。


    • CV

    Content View,内容播放数, 是指在一个统计周期内,视频被打开,且视频正片内容(除广告)被成功播放的次数之和


    • PR

    PageRank,即网页的级别技术,或网站权重或受欢迎度。网页排名,它是Google排名运算法则(排名公式)的一部分,用来标识网页的等级/重要性。级别从1到10级,10级为满分。PR值越高说明该网页越受欢迎。

    是网页等级的一个标准(0-10)。PR值越高说明这个网站越受欢迎。=1,说明网站不太流行;=7~10,网站非常受欢迎。当PR值达到4时就已经很不错。


    • QPS

    Query Per Second),每秒查询率,每秒的响应请求数,也即是最大吞吐能力。QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量。每秒的响应请求数,也即是最大吞吐能力。

    QPS = req/sec = 请求数/秒
    QPS统计方式 [一般使用 http_load 进行统计]
    QPS = 总请求数 / ( 进程总数 * 请求时间 )
    QPS:单个进程每秒请求服务器的成功次数



    • 峰值QPS和机器计算

    原理:每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间
    公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
    机器:峰值时间每秒QPS / 单台机器的QPS = 需要的机器

    服务器数量计算:服务器数量 =ceil( 每天总PV / 单台服务器每天总PV )

    问:每天100w PV 的在单台机器上,这台机器需要多少QPS?
    答:( 1000000 * 0.8 ) / (86400 * 0.2 ) = 46 (QPS)


    问:如果一台机器的QPS是18,需要几台机器来支持?
    答:46/ 18 = 3



    • TPS

    Transactions Per Second 的缩写,每秒处理的事务数目。一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程。客户机在发送请求时开始计时,收到服务器响应后结束计时,以此来计算使用的时间和完成的事务个数,最终利用这些信息作出的评估分。

    TPS 的过程包括:客户端请求服务端、服务端内部处理、服务端返回客户端。

    例如,访问一个 Index 页面会请求服务器 3 次,包括一次 html,一次 css,一次 js,那么访问这一个页面就会产生一个“T”,产生三个“Q”。



    • GMV

    Gross Merchandise Volume,成交金额,主要包括付款金额和未付款的。GMV是流水,只要你下了订单,生成订单号,产生的订单中往往会包括付款订单和未付款的订单,而gmv统计的指标就是其二者之和。

    电商平台给出的计算指标是:GMV=销售额+取消订单金额+拒收订单金额+退货订单金额。



    • 转换率

    转换率=转换次数/总点击量 * 100%
    定义:就是说 在一个统计时间内,完成转换行为的次数占总点击次数的比率。

    转换率是网站最最终是否盈利的核心,提升网站转换率是网站综合运营实力的结果。

    举例,一天 UV为5000,有50个用户有了后续的转换行为,转换率=50/5000 *100% =1%



    • 跳出率(蹦失率)

    用户(独立用户)来到网站之后,只浏览了一个页面就离开与总的访问数量的百分比。
    跳出率的作用:是网站分析的主要指标,跳出率越高,说明网站的吸引力越低,当跳出率达到一定程度时,说明你的网站页面需要优化或者页面更新了。

    降低跳出率方法:
    a.服务器要快
    b.没有欺骗性的跳转
    c.采用面包屑导航,每个分页上都加上导航
    d.网站的质量要高



    • 退出率

    用户推出网站的次数除以用户浏览网站的次数的百分比。

    退出率百分比的作用:反映了网站对于访客的吸引力,如果退出率很高的话就要想办法改善网站的内容来吸引更多的客户。

    举例,对于一个IP 可能会产生5个PV,有2种可能,第一是他点了5个不同的页面,第二是连续打开5次首页。第二种的跳出率是100%。

    跳出率是衡量访问的质量的关键。

    跳出率高,说明很多新用户来了,看了一页就离开。

    跳出率低,说明新老客户来了点击很多页面才离开。

    跳出率与退出率区别:
    跳出率和退出率都能是以网页为基数的,而且都是反映出网站质量的重要参数,严格来区分的话,跳出率是表达访客仅访问了一个页面就离开,反映的是某个网页的质量好坏,能体现的网站问题也比较重要,而退出率能是表达访客仅访问了网站几个(≥1)页面就离开,反映的是多个网页的综合质量。同时由于退出率的计算复杂。

    跳出率:针对的是网站,指一定时间内,只访问了一页的就走的会话占会话总数的比率
    退出率:某个页面作为会话的结束页面,占会话总数的比率
    明显"跳"的动作比较大,"跳"是针对网站的,"退"的动作幅度比较小,是针对某个页面的



    附录

    上述的多数统计指标,需要有两种cookie

    • 磁盘cookie+无失效时间(暂且叫uic,user identification cookie)
    • 内存cookie+30分钟失效时间(sc,session cookie)

    磁盘cookie:cookie写入到磁盘中,关闭浏览器再次打开依然存在.

    内存cookie:仅仅存在于浏览器进程内存中,关闭浏览器后消失。又叫持久cookie、临时cookie



    参考

    https://blog.csdn.net/w8y56f/article/details/87512732

    https://blog.51cto.com/linuxnote/1653958

    展开全文
  • 本文,基于某电商海量的全链路数据,简明扼要的分享自己工作三年的时间内在实时数据统计分析以及数据挖掘方面的经验。
  • 浏览器的云加速可能导致IP统计异常

    千次阅读 2015-09-24 19:01:13
    前段时间弄个流量统计相关的东西,请求展示图片时根据请求的IP进行 md5 签名生成点击链接的验证参数,结果发现一个莫名其妙的问题发现点击日志中有一小部分点击的IP居然不一致,如果是开放给别人用可能存在作弊的...
  • Linux TC 流量限速

    2019-07-06 03:27:13
    Linux TC 流量限速 2011年01月07日 12:50:00sahusoft阅读数 6916 # !/bin/sh touch /var/lock/subsys/local echo 1 > /proc/sys/net/ipv4/ip_forward route add default gw 10.0.0.0 (这是加入电信网关,如果...
  • CucusoftNet Guard网络流量统计条可实时统计自己电脑上网所耗费的流量数据大小多少,可以明明白白的看清楚每个程序耗费的流量有多少,有多少网络连接,还可以设定流量报警和流量限额。 特别提示:安装时会提示安装...
  • tc流量控制

    千次阅读 2016-08-09 17:50:25
    通过设置不同类型的网络接口队列,从而改变数据包发送的速率和优先级,达到流量控制的目的。内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(队列规则)把数据包加入队列,然后内核会...
  • Netty | 流量整形

    2020-02-28 11:36:43
    Netty 对读写流控的判断是基于固定窗口(相对于滑动窗口、令牌)的判断,按照一定时间段 checkInterval (1s) 来统计; 当 writeLimit / readLimit 设置为 0 时,表示关闭写 / 读整形; 等待时间的范围控制 10ms...
  • 摄像头统计人数

    2013-09-16 10:28:40
    运用opencv采集摄像头,进行人数统计,可运用于商场进出口试验程序
  • 如何使用流量精灵刷网站流量

    千次阅读 2017-10-17 21:48:38
    1 一定要设置访问时间在什么时候是高峰,比如除非是黄色网站,否则不可能高峰时间总是在凌晨1-3点这种时间段,同样,不同类型的网站需要模拟真实的流量曲线图,不要和真实情况相差太多,尤其是对于那些流量曲线是会...
  • AWS S3 监控请求数及流量

    千次阅读 2019-12-10 20:01:30
    AWS S3 云存储 是按照存储容量,请求数,及网络流量三个维度进行收费。而如果涉及到使用S3 对外提供SaaS服务,成本分布及估算自然称为比较重要的需求。自然而言需要监控以上三个指标。 先上官网说明性文档:...
  • tc流量控制模型

    千次阅读 2018-11-07 11:49:57
    在Linux操作系统中流量控制器(TC)主要是在输出端口处建立一个队列进行流量控制,控制的方式是基于路由,亦即基于目的IP地址或目的子网的网络号的流量控制。流量控制器TC,其基本的功能模块为队列、分类和过滤器。...
  • 三大电信运营商发布公告称,自2018年7月1日起,将取消流量“漫游”费,新老手机用户的省内通用流量升级为国内流量,看起来这对于国内手机用户来说是一件好事,不过这对于农村用...
  • charles进行流量监测

    2017-09-28 10:55:00
    滤掉 Windows的网络请求,方法:Proxy->确保 Windows Proxy和 MozillaFirefox Proxy 为 取消勾选的状态 在测试机上进行操作,即可获取操作时使用的网络信息,包括流量数据,如下图所示 转载于:...
  • 恶意流量分析训练三

    2020-02-05 10:03:08
    了解使用wireshark进行恶意流量分析,培养流量分析的思维和能力,本次实验涉及知识包括善用搜索引擎、技术分析文章整合、snort日志分析、以及关于Locky ransomware和Angler EK部分攻击流量特征。 试根据给出的...
  • APP统计分析 用户画像 对程序员来说,用户画像就是用户的属性和行为;通俗地说,用户画像是包括了个人信息、兴趣爱好、日常行为等血肉丰满的客户实体。用户画像是精准营销的产物,企业通过收集用户的行为,然后...
  • 百度最近发布了一条轰动站长圈的消息,说的是百度将逐渐取消referer关键词显示,这绝对是...同时,百度将逐步取消referer中关于关键词的显示,保护站点流量关键词数据信息,第三方将不再可以轻易地窃取到流量关键词,令
  • 流量明星全面崩塌!

    千次阅读 2018-07-29 10:11:02
    这样一场闹剧不仅牵出了人们对于饭圈文化的关注,也引发了对于流量明星们的讨论。               流量明星是什么?简单的说,年轻颜好是他们的基本标签。他们可以通过强大的粉丝应援,时时刻刻上热...
  • Linux流量控制(SFQTBFPRIOCBQHTB原理介绍)

    千次阅读 2014-10-27 20:58:13
    Linux流量控制控发不控收,所以只能对产生瓶颈网卡处的发包速率进行控制..而网络瓶颈分析亦为Linux网络流控的第一步。 二种流控算法上分: 无类算法 用于树叶级无分支的队列 SFQ TBF pFIFO 分类算法 用于多分支的...
  • 如何隐藏CNZZ统计图标

    2019-07-25 15:05:43
    直接修改统计代码的样式 在统计代码的样式: 在统计代码 javascript 中的ducument.write(unescape("%3Cspan和id='cnzz_stat_icon'中间加上 style='display:none;' 就可以了。 下面是修改后的代码。 <...
  • 网络流量监控mrtg

    千次阅读 2013-04-19 09:11:52
    indexmaker --output=/usr/local/nginx/html/mrtg/index.html --title=服务器流量统计 /usr/local/nginx/html/mrtg/mrtg.cfg //定时更新 crontab -e 自动调用viw编辑器,然后输入下面内容 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,810
精华内容 5,924
关键字:

如何取消流量统计