tutorial_2

差分

このページの2つのバージョン間の差分を表示します。

この比較画面へのリンク

両方とも前のリビジョン 前のリビジョン
次のリビジョン
前のリビジョン
tutorial_2 [2022/01/03 01:50] satoshitutorial_2 [2022/05/02 14:09] (現在) satoshi
行 1: 行 1:
-====== 第2章 スターターコード【初級編 エリア判定(立ち止まり判定)】 ======+====== 第2章 エリア判定(立ち止まり判定)【初級編】 ======
  
-===== 第一項 SCORER Edge SDKの利用準備 ===== 
-SCORER People Trackerがインストールされた状態を想定しているため、カメラの設定などはすでに済んでいるものとします。\\ 
  
-SCORER Edgeに接続した状態で[[http://解析端末のIP:20001/]]にアクセスし、メニューのSDK→projectを開く\\ 
-新規でプロジェクトを作成し、 
-  * Instance ID:lesson 
-  * Nickname:(空欄) 
-  * Environment:Gstreamer 
-  * Network Access: Allow all 
-とします。\\ 
-{{::sdk01.png|}}\\ 
  
-SDKインスタンスが立ち上がったらOpen Jupyter Labで起動し、dev@scorerでログインしましょう。\\ +===== 第項 スターターコードの中身を確認する =====
-立ち上げ時はあまりコマンドが登録されていないため\\ +
-<code> +
-apt update +
-apt install zip +
-</code> +
-を行い、ここにあるチュートリアル用zipファイルをダウンロードし、ホームディレクトリにDrag&Dropでアップロード。\\ +
-<code> +
-unzip tutorial.zip +
-</code> +
-で展開し、\\ +
-<code> +
-cd tutorial +
-</code> +
-に行けば2章に必要なファイルが一式揃う形になります。\\ +
- +
-===== 第項 スターターコードの中身を確認する =====+
 第2章のスターターコードは2つのプログラムコードに分かれます\\ 第2章のスターターコードは2つのプログラムコードに分かれます\\
-一つがSCORER People Trackingからログを受信して1分ごとにjson形式で保存するプログラム。\\+一つがSCORER People Trackerからログを受信して1分ごとにjson形式で保存するプログラム。\\
 もう一つが保存したログからあらかじめ指定したエリア内で立ち止まりがあるかどうかを調べるプログラムとなります。 もう一つが保存したログからあらかじめ指定したエリア内で立ち止まりがあるかどうかを調べるプログラムとなります。
  
行 37: 行 11:
 <sxh Python;title:02capture_final.py> <sxh Python;title:02capture_final.py>
 #!/usr/bin/env python3 #!/usr/bin/env python3
 +
 # This script dumps various streams # This script dumps various streams
  
行 49: 行 24:
 import math import math
 from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
 +
  
 # Handle arguments # Handle arguments
行 67: 行 43:
 DEFAULT_INGRESS_ADDR="tcp://localhost:5002" DEFAULT_INGRESS_ADDR="tcp://localhost:5002"
 DEFAULT_INGRESS_TOPICS=[ 'VideoFrame', 'JpegFrame', 'LogFrame' ] DEFAULT_INGRESS_TOPICS=[ 'VideoFrame', 'JpegFrame', 'LogFrame' ]
 +
  
 ap = argparse.ArgumentParser( ap = argparse.ArgumentParser(
行 89: 行 66:
  
 args = ap.parse_args() args = ap.parse_args()
 +
  
 # Flatten the lists # Flatten the lists
行 111: 行 89:
 else: else:
     json_opts = {'sort_keys': True}     json_opts = {'sort_keys': True}
 +
 +
  
 # -------------------------------- # --------------------------------
行 129: 行 109:
     if args.verbose >= level_:     if args.verbose >= level_:
         print(*args_, **kwargs_)         print(*args_, **kwargs_)
 +
 +
  
 # -------------------------------- # --------------------------------
行 137: 行 119:
 TOPIC_JPEG_FRAME = b'JpegFrame' TOPIC_JPEG_FRAME = b'JpegFrame'
 POLL_WAIT_TIME  = 30           # milliseconds POLL_WAIT_TIME  = 30           # milliseconds
 +
  
 def subscribe_streams(ctx_, stream_addrs_): def subscribe_streams(ctx_, stream_addrs_):
行 168: 行 151:
          
     raw_json_file = open(dirpath+'/'+datestr0[:8]+'/raw_'+datestr0+'.json', 'w')     raw_json_file = open(dirpath+'/'+datestr0[:8]+'/raw_'+datestr0+'.json', 'w')
 +
                  
     while True:     while True:
行 175: 行 159:
         if events.get(socki) != zmq.POLLIN:         if events.get(socki) != zmq.POLLIN:
             continue    # Poller time out             continue    # Poller time out
 +
  
         # Receive a message         # Receive a message
行 249: 行 234:
     socki.close()     socki.close()
     dprint(4,'Exiting the stream subscriber.')     dprint(4,'Exiting the stream subscriber.')
 +
 +
  
 # Main # Main
行 290: 行 277:
          
     json_open = open(area_def_file, 'r')     json_open = open(area_def_file, 'r')
-    result_json_file = open('result_'+sys.argv[1]+'.json', 'w')+    result_json_file = open('result_'+area_def_file[:len(area_def_file)-5]+'_'+sys.argv[1]+'.json', 'w')
     areadef = json.load(json_open)     areadef = json.load(json_open)
     resultarr = {}     resultarr = {}
-    for area in areadef: +    for areaidx, area in enumerate(areadef['areas'])
-        resultarr[area['name']]={}+        areaname='areaID'+str(areaidx) 
 +        print(areaname) 
 +        resultarr[areaname]={}
     print("集計・・")     print("集計・・")
-    for area in areadef: +    for areaidx, area in enumerate(areadef['areas'])
-        print(area['name'])+        areaname='areaID'+str(areaidx) 
 +        print(areaname)
         polygon = []         polygon = []
         for point in area['points']:         for point in area['points']:
行 306: 行 296:
  
         for filename in file_list:         for filename in file_list:
-            print(area['name']+"_"+filename)+            print(areaname+"_"+filename)
             if os.path.getsize(filename) == 0:             if os.path.getsize(filename) == 0:
                 continue                 continue
行 318: 行 308:
                 for person in people:                 for person in people:
                                          
-                    #print(area['name']+'_'+person['tracking_id']+'_'+str(judgenum))+                    #print(areaname+'_'+person['tracking_id']+'_'+str(judgenum))
                     personpos = [(person["x0"]+person["x1"])/2,person["y1"]]                     personpos = [(person["x0"]+person["x1"])/2,person["y1"]]
                     test = cv2.pointPolygonTest(contour, personpos, False)                     test = cv2.pointPolygonTest(contour, personpos, False)
                     if test>0:                     if test>0:
-                        if person['tracking_id'] in resultarr[area['name']]: +                        if person['tracking_id'] in resultarr[areaname]: 
-                            resultarr[area['name']][person['tracking_id']]['end_time'] = frame['frame_time'+                            resultarr[areaname][person['tracking_id']]['end_time'] = frame['frame_time'
-                            resultarr[area['name']][person['tracking_id']]['duration'] = frame['frame_time']-resultarr[area['name']][person['tracking_id']]['start_time'+                            resultarr[areaname][person['tracking_id']]['duration'] = frame['frame_time']-resultarr[areaname][person['tracking_id']]['start_time'
-                            resultarr[area['name']][person['tracking_id']]['end_time_jp'] = jptime.isoformat() +                            resultarr[areaname][person['tracking_id']]['end_time_jp'] = jptime.isoformat() 
-                            if resultarr[area['name']][person['tracking_id']]['duration'] > duration: +                            if resultarr[areaname][person['tracking_id']]['duration'] > duration: 
-                                resultarr[area['name']][person['tracking_id']]['stop_judge'] = True+                                resultarr[areaname][person['tracking_id']]['stop_judge'] = True
                         else:                         else:
-                            resultarr[area['name']][person['tracking_id']]={'area':area['name'],'start_time_jp':jptime.isoformat(),'end_time_jp':jptime.isoformat(),'start_time':frame['frame_time'],'end_time':frame['frame_time'],'stream_id':frame['stream_id'],'duration':0,'stop_judge':False}+                            resultarr[areaname][person['tracking_id']]={'area':areaname,'start_time_jp':jptime.isoformat(),'end_time_jp':jptime.isoformat(),'start_time':frame['frame_time'],'end_time':frame['frame_time'],'stream_id':frame['stream_id'],'duration':0,'stop_judge':False}
  
     json.dump(resultarr,result_json_file)     json.dump(resultarr,result_json_file)
行 335: 行 325:
     for areaname, records in resultarr.items():     for areaname, records in resultarr.items():
         print(areaname)         print(areaname)
-        f = open(sys.argv[1]+"_"+areaname+".csv", 'w', encoding='utf-8', newline='')+        f = open(area_def_file[:len(area_def_file)-5]+"_"+sys.argv[1]+"_"+areaname+".csv", 'w', encoding='utf-8', newline='')
         write = csv.writer(f)         write = csv.writer(f)
         write.writerow(["stream_id","areaname","tracking_id","start_time_jp","end_time_jp","total_duration","stop_judge"])         write.writerow(["stream_id","areaname","tracking_id","start_time_jp","end_time_jp","total_duration","stop_judge"])
行 341: 行 331:
             write.writerow([record['stream_id'],areaname,tracking_id,record['start_time_jp'],record['end_time_jp'],record['duration'],record['stop_judge']])             write.writerow([record['stream_id'],areaname,tracking_id,record['start_time_jp'],record['end_time_jp'],record['duration'],record['stop_judge']])
                  
-        f.close()+        f.close()    
 </sxh> </sxh>
  
行 347: 行 337:
  
 <sxh JavaScript;title:02area.json> <sxh JavaScript;title:02area.json>
-[   +
-  +    "areas": [ 
-    "name": "Shape_1", +        { 
-    "points":+            "points":
-      { +                {"x": 110, "y": 351}, 
-        "x": 110, +                {"x": 571, "y": 369}, 
-        "y": 351 +                {"x": 601, "y": 567}, 
-      }, +                {"x": 147, "y": 709} 
-      { +            ] 
-        "x": 571, +        }
-        "y": 369 +
-      }, +
-      { +
-        "x": 601, +
-        "y": 567 +
-      }, +
-      { +
-        "x": 147, +
-        "y": 709 +
-      }+
     ]     ]
-  } +}
-]+
 </sxh> </sxh>
-===== 第項 座標ログをSCCORERシステムから受け取る ===== +===== 第項 座標ログをSCORERシステムから受け取る ===== 
-以下、第二項でのプログラムの解説を中心に、最終形を作る過程のプログラムも併せて掲載します。+以下、項でのプログラムの解説を中心に、最終形を作る過程のプログラムも併せて掲載します。
  
 SCORERでのデータのやり取りは様々な機能を実現するため、メッセージングキューという比較的複雑な手法で行っています。 SCORERでのデータのやり取りは様々な機能を実現するため、メッセージングキューという比較的複雑な手法で行っています。
行 619: 行 598:
 次はログの情報を記録するプログラムに変更しましょう。\\ 次はログの情報を記録するプログラムに変更しましょう。\\
  
-===== 第項 座標ログを保存する ===== +===== 第項 座標ログを保存する ===== 
-第三項でログが取得できることが確認できました。\\+項でログが取得できることが確認できました。\\
 受信したデータを一つのファイルに保存してもよいのですが、これらのログは人が多く映っている時は非常に大量にあり、1分間に300-600レコードものデータとなります。\\ 受信したデータを一つのファイルに保存してもよいのですが、これらのログは人が多く映っている時は非常に大量にあり、1分間に300-600レコードものデータとなります。\\
 今回は1分に1ファイル、書きこんでいるファイルに60秒分書きこんだらファイルを次の時刻に切り替えて保存する方式とします。\\ 今回は1分に1ファイル、書きこんでいるファイルに60秒分書きこんだらファイルを次の時刻に切り替えて保存する方式とします。\\
行 626: 行 605:
  
 ちなみに取得したログを見ると、どのカメラからのデータなのか、いつのフレームの時刻なのかの情報がありません。\\ ちなみに取得したログを見ると、どのカメラからのデータなのか、いつのフレームの時刻なのかの情報がありません。\\
-こちらはデータ取得時の時間を追記して保存しましょう(将来のSCORER People Trackingのバージョンアップで改善するかもしれません)。\\+こちらはデータ取得時の時間を追記して保存しましょう(将来のSCORER People Trackerのバージョンアップで改善するかもしれません)。\\
  
 さて変更した部分をハイライトしておきます。 さて変更した部分をハイライトしておきます。
行 864: 行 843:
 これでログを保存することができるようになりました。\\ これでログを保存することができるようになりました。\\
  
-===== 第項 SCORER People Trackerから取得できる情報 =====+===== 第項 SCORER People Trackerから取得できる情報 =====
 SCORER People Trackerの内容やログ形式については1章でも書いたものとなっており、再掲すると\\ SCORER People Trackerの内容やログ形式については1章でも書いたものとなっており、再掲すると\\
 {{:peopletrackerログ説明.png?linkonly|}}\\ {{:peopletrackerログ説明.png?linkonly|}}\\
 となっています。\\ となっています。\\
-なお、項で保存したログのサンプルデータ(最初3フレーム分)は+なお、項で保存したログのサンプルデータ(最初3フレーム分)は
 <sxh JavaScript;title:02capture_example.json> <sxh JavaScript;title:02capture_example.json>
 [ [
行 1043: 行 1022:
 SCORER People Trackerでは1秒間に5-10回もの高頻度で検知を行っているため、前後の検知結果同士を見比べれば同じ人物であることが容易に推定されます。\\ SCORER People Trackerでは1秒間に5-10回もの高頻度で検知を行っているため、前後の検知結果同士を見比べれば同じ人物であることが容易に推定されます。\\
 {{::peopletracker_saikinbo.png|}}\\ {{::peopletracker_saikinbo.png|}}\\
-本来は複数の人物がすれ違った時や、画面の外に出てまた入ってきた場合はどうなるかなどいろいろ考えるべきことはありますが、そのあたりはSCORER People Trackingがうまくやってくれています。\\+本来は複数の人物がすれ違った時や、画面の外に出てまた入ってきた場合はどうなるかなどいろいろ考えるべきことはありますが、そのあたりはSCORER People Trackerがうまくやってくれています。\\
 今回は画面内にある人物の判定と前提があるため、あまり気にせず固有IDをそのまま活用していきましょう。\\ 今回は画面内にある人物の判定と前提があるため、あまり気にせず固有IDをそのまま活用していきましょう。\\
  
-===== 第項 エリア座標判定処理の考え方 =====+===== 第項 エリア座標判定処理の考え方 =====
 さて、ここでどのようなデータを取得したいか具体的に定義していきましょう。\\ さて、ここでどのようなデータを取得したいか具体的に定義していきましょう。\\
  
行 1078: 行 1057:
   - 固有IDが初めて出てきたら配列に固有IDと座標等を登録。2回目以降は配列に座標を追加。   - 固有IDが初めて出てきたら配列に固有IDと座標等を登録。2回目以降は配列に座標を追加。
   - 同時にエリア内にいたかどうかを判定。いた場合は固有ID配列に時刻ごとに「通過したフラグ」を立てる。   - 同時にエリア内にいたかどうかを判定。いた場合は固有ID配列に時刻ごとに「通過したフラグ」を立てる。
-  - 5秒前の情報からエリアにいた(検知漏れも考慮し9割以上の頻度で)場合は立ち止まったと判断して固有IDに「立ち止まったフラグ」を立てる。+  - 5秒前の情報からエリアにいた場合は立ち止まったと判断して固有IDに「立ち止まったフラグ」を立てる。
   - 全部の集計が完了したら配列をCSVにして出力する。   - 全部の集計が完了したら配列をCSVにして出力する。
 という流れになります。\\ という流れになります。\\
行 1116: 行 1095:
 なお、これらはカメラの数や試行回数が多くなると途端に面倒になるものですので、次の章ではWEB画面で簡単に設定できるようにしていきます。\\ なお、これらはカメラの数や試行回数が多くなると途端に面倒になるものですので、次の章ではWEB画面で簡単に設定できるようにしていきます。\\
  
-<sxh Python;title:01area.json(再掲);> +<sxh Python;title:02area.json;> 
-[   +
-  +    "areas": [ 
-    "name": "Shape_1", +        { 
-    "points":+            "points":
-      { +                {"x": 110, "y": 351}, 
-        "x": 110, +                {"x": 571, "y": 369}, 
-        "y": 351 +                {"x": 601, "y": 567}, 
-      }, +                {"x": 147, "y": 709} 
-      { +            ] 
-        "x": 571, +        }
-        "y": 369 +
-      }, +
-      { +
-        "x": 601, +
-        "y": 567 +
-      }, +
-      { +
-        "x": 147, +
-        "y": 709 +
-      }+
     ]     ]
-  } +}
-]+
 </sxh> </sxh>
 取得した座標と立ち止まり判定継続時間(秒)を設定します。\\ 取得した座標と立ち止まり判定継続時間(秒)を設定します。\\
 また、今回のスターターコードでは複数のエリアを同時に設定しても問題ないように書いてあります。\\ また、今回のスターターコードでは複数のエリアを同時に設定しても問題ないように書いてあります。\\
  
-<sxh Python;title:01area_multi.json;> +<sxh Python;title:02area_multi.json;> 
-[   +
-  +    "areas": [ 
-    "name": "Shape_1", +        { 
-    "points":+            "points":
-      { +                {"x": 0, "y": 0},  
-        "x": 110, +                {"x": 500, "y": 0},  
-        "y": 351 +                {"x": 500, "y": 200},  
-      }, +                {"x": 0, "y": 200} 
-      +            ] 
-        "x": 571+        }, 
-        "y": 369 +        
-      }, +            "points":
-      +                {"x": 725, "y": 499},  
-        "x": 601, +                {"x": 1225, "y": 499},  
-        "y": 567 +                {"x": 1225, "y": 699},  
-      }, +                {"x": 725, "y": 699} 
-      +            ] 
-        "x": 147+        }
-        "y": 709 +
-      }+
     ]     ]
-  }+}
-  { +
-    "name": "Shape_2", +
-    "points":+
-      { +
-        "x": 210, +
-        "y": 451 +
-      }, +
-      { +
-        "x": 671, +
-        "y": 469 +
-      }, +
-      { +
-        "x": 701, +
-        "y": 667 +
-      }, +
-      { +
-        "x": 247, +
-        "y": 809 +
-      } +
-    ] +
-  } +
-]+
 </sxh> </sxh>
  
-===== 第項 スターターコードの完成 =====+===== 第項 スターターコードの完成 =====
 さて、前項でエリア情報をファイルで定義し、判定する手順も決めたため集計プログラムを作成するうえで必要な情報はすべてそろいました。\\ さて、前項でエリア情報をファイルで定義し、判定する手順も決めたため集計プログラムを作成するうえで必要な情報はすべてそろいました。\\
 再掲となりますが判定プログラムがこちらです。 再掲となりますが判定プログラムがこちらです。
行 1219: 行 1163:
          
     json_open = open(area_def_file, 'r')     json_open = open(area_def_file, 'r')
-    result_json_file = open('result_'+sys.argv[1]+'.json', 'w')+    result_json_file = open('result_'+area_def_file[:len(area_def_file)-5]+'_'+sys.argv[1]+'.json', 'w')
     areadef = json.load(json_open)     areadef = json.load(json_open)
     resultarr = {}     resultarr = {}
-    for area in areadef: +    for areaidx, area in enumerate(areadef['areas'])
-        resultarr[area['name']]={}+        areaname='areaID'+str(areaidx) 
 +        print(areaname) 
 +        resultarr[areaname]={}
     print("集計・・")     print("集計・・")
-    for area in areadef: +    for areaidx, area in enumerate(areadef['areas'])
-        print(area['name'])+        areaname='areaID'+str(areaidx) 
 +        print(areaname)
         polygon = []         polygon = []
         for point in area['points']:         for point in area['points']:
行 1235: 行 1182:
  
         for filename in file_list:         for filename in file_list:
-            print(area['name']+"_"+filename)+            print(areaname+"_"+filename)
             if os.path.getsize(filename) == 0:             if os.path.getsize(filename) == 0:
                 continue                 continue
行 1247: 行 1194:
                 for person in people:                 for person in people:
                                          
-                    #print(area['name']+'_'+person['tracking_id']+'_'+str(judgenum))+                    #print(areaname+'_'+person['tracking_id']+'_'+str(judgenum))
                     personpos = [(person["x0"]+person["x1"])/2,person["y1"]]                     personpos = [(person["x0"]+person["x1"])/2,person["y1"]]
                     test = cv2.pointPolygonTest(contour, personpos, False)                     test = cv2.pointPolygonTest(contour, personpos, False)
                     if test>0:                     if test>0:
-                        if person['tracking_id'] in resultarr[area['name']]: +                        if person['tracking_id'] in resultarr[areaname]: 
-                            resultarr[area['name']][person['tracking_id']]['end_time'] = frame['frame_time'+                            resultarr[areaname][person['tracking_id']]['end_time'] = frame['frame_time'
-                            resultarr[area['name']][person['tracking_id']]['duration'] = frame['frame_time']-resultarr[area['name']][person['tracking_id']]['start_time'+                            resultarr[areaname][person['tracking_id']]['duration'] = frame['frame_time']-resultarr[areaname][person['tracking_id']]['start_time'
-                            resultarr[area['name']][person['tracking_id']]['end_time_jp'] = jptime.isoformat() +                            resultarr[areaname][person['tracking_id']]['end_time_jp'] = jptime.isoformat() 
-                            if resultarr[area['name']][person['tracking_id']]['duration'] > duration: +                            if resultarr[areaname][person['tracking_id']]['duration'] > duration: 
-                                resultarr[area['name']][person['tracking_id']]['stop_judge'] = True+                                resultarr[areaname][person['tracking_id']]['stop_judge'] = True
                         else:                         else:
-                            resultarr[area['name']][person['tracking_id']]={'area':area['name'],'start_time_jp':jptime.isoformat(),'end_time_jp':jptime.isoformat(),'start_time':frame['frame_time'],'end_time':frame['frame_time'],'stream_id':frame['stream_id'],'duration':0,'stop_judge':False}+                            resultarr[areaname][person['tracking_id']]={'area':areaname,'start_time_jp':jptime.isoformat(),'end_time_jp':jptime.isoformat(),'start_time':frame['frame_time'],'end_time':frame['frame_time'],'stream_id':frame['stream_id'],'duration':0,'stop_judge':False}
  
     json.dump(resultarr,result_json_file)     json.dump(resultarr,result_json_file)
行 1264: 行 1211:
     for areaname, records in resultarr.items():     for areaname, records in resultarr.items():
         print(areaname)         print(areaname)
-        f = open(sys.argv[1]+"_"+areaname+".csv", 'w', encoding='utf-8', newline='')+        f = open(area_def_file[:len(area_def_file)-5]+"_"+sys.argv[1]+"_"+areaname+".csv", 'w', encoding='utf-8', newline='')
         write = csv.writer(f)         write = csv.writer(f)
         write.writerow(["stream_id","areaname","tracking_id","start_time_jp","end_time_jp","total_duration","stop_judge"])         write.writerow(["stream_id","areaname","tracking_id","start_time_jp","end_time_jp","total_duration","stop_judge"])
行 1270: 行 1217:
             write.writerow([record['stream_id'],areaname,tracking_id,record['start_time_jp'],record['end_time_jp'],record['duration'],record['stop_judge']])             write.writerow([record['stream_id'],areaname,tracking_id,record['start_time_jp'],record['end_time_jp'],record['duration'],record['stop_judge']])
                  
-        f.close()+        f.close()    
 </sxh> </sxh>
 実行は\\ 実行は\\
行 1284: 行 1231:
 24行目でエリア情報のファイルを開きます。(JSON形式のため26行目で配列に変換しています)\\ 24行目でエリア情報のファイルを開きます。(JSON形式のため26行目で配列に変換しています)\\
 25行目で結果CSVファイルを新規で開きます。\\ 25行目で結果CSVファイルを新規で開きます。\\
-28-29行目では結果データの配列をエリアごとに事前に初期化します。\\+28-31行目では結果データの配列をエリアごとに事前に初期化します。\\
  
 さて、今回多角形のエリアに対応した判定ができるようなコードとなっています。\\ さて、今回多角形のエリアに対応した判定ができるようなコードとなっています。\\
 ここで初めて出てきますが、映像解析でよく使われる計算ライブラリにOpenCVというものがあります。\\ ここで初めて出てきますが、映像解析でよく使われる計算ライブラリにOpenCVというものがあります。\\
 このライブラリを利用して多角形内にある点が入っているか入っていないかが簡単に判明します。\\ このライブラリを利用して多角形内にある点が入っているか入っていないかが簡単に判明します。\\
-54-55行目\\+57-58行目\\
 <code> <code>
 personpos = [(person["x0"]+person["x1"])/2,person["y1"]] personpos = [(person["x0"]+person["x1"])/2,person["y1"]]
行 1307: 行 1254:
 これは結果データを個体IDごとに集計しなおすことで、一つのIDに判定情報を蓄積していく形としています。\\ これは結果データを個体IDごとに集計しなおすことで、一つのIDに判定情報を蓄積していく形としています。\\
  
-56-64行目ではエリア内だった場合に、初めてその個体IDが現れた場合は初期化をし時刻を書きこみます。二回目以降出てきた場合は時刻を更新して、最初に検知された時刻との差分を増やしていき、5秒以上になった場合は立ち止まり判定フラグにTrueを入れます。\\+59-67行目ではエリア内だった場合に、初めてその個体IDが現れた場合は初期化をし時刻を書きこみます。二回目以降出てきた場合は時刻を更新して、最初に検知された時刻との差分を増やしていき、5秒以上になった場合は立ち止まり判定フラグにTrueを入れます。\\
 なお、エリアに一度も入っていない場合は今回集計対象からは外しています。\\ なお、エリアに一度も入っていない場合は今回集計対象からは外しています。\\
  
-68-76行目では一度すべての情報を配列で集計し終わった後、CSVファイルに書き込む処理をしています。CSVファイルの1行目には列のヘッダー情報を入れておきます。\\+71-79行目では一度すべての情報を配列で集計し終わった後、CSVファイルに書き込む処理をしています。CSVファイルの1行目には列のヘッダー情報を入れておきます。\\
  
 細かいところなどは省きましたが、上記の動作するコードに対して様々な変更を加えて自分なりに動作を確認してみましょう。\\ 細かいところなどは省きましたが、上記の動作するコードに対して様々な変更を加えて自分なりに動作を確認してみましょう。\\
 次の章ではエリア座標を設定する手間を大幅に軽減するためにWEB画面で変更できるところなども学んでみましょう。 次の章ではエリア座標を設定する手間を大幅に軽減するためにWEB画面で変更できるところなども学んでみましょう。
  • tutorial_2.1641142209.txt.gz
  • 最終更新: 2022/01/03 01:50
  • by satoshi