Skip to content

Commit 656b4b7

Browse files
authored
Merge pull request #2 from OpenVisualCloud/master
Merge all changes from master
2 parents c2cd3c3 + 83dc5b3 commit 656b4b7

25 files changed

+20168
-8806
lines changed

analytics/common/Xeon/gst/Dockerfile.1.gst

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ RUN git clone ${VA_GSTREAMER_PLUGINS_REPO} && \
2020
-DGIT_INFO=$(echo "git_$(git rev-parse --short HEAD)") \
2121
-DCMAKE_BUILD_TYPE=Release \
2222
-DDISABLE_SAMPLES=ON \
23-
-DDISABLE_VAAPI=ON \
23+
-DHAVE_VAAPI=OFF \
2424
-DENABLE_PAHO_INSTALLATION=1 \
2525
-DENABLE_RDKAFKA_INSTALLATION=0 \
2626
-DENABLE_AVX2=ON -DENABLE_SSE42=ON \

analytics/common/runva.py

+70-31
Original file line numberDiff line numberDiff line change
@@ -27,38 +27,77 @@ def __init__(self, pipeline, version="2"):
2727
def stop(self):
2828
self._stop=True
2929

30-
def loop(self, sensor, location, uri, algorithm, topic):
31-
pid,msg=PipelineManager.create_instance(self._pipeline,self._version,{
32-
"source": {
33-
"uri": uri,
34-
"type":"uri"
35-
},
36-
"destination": {
37-
"type": "mqtt",
38-
"host": mqtthost,
39-
"clientid": algorithm,
40-
"topic": topic
41-
},
42-
"tags": {
43-
"sensor": sensor,
44-
"location": location,
45-
"algorithm": algorithm,
46-
"office": {
47-
"lat": office[0],
48-
"lon": office[1],
30+
def loop(self, sensor, location, uri, topic, algorithm, algorithmName, resolution={}, zone=0, polygon=[]):
31+
if algorithmName=="crowd-counting":
32+
pid,msg=PipelineManager.create_instance(self._pipeline,self._version,{
33+
"source": {
34+
"uri": uri,
35+
"type":"uri"
4936
},
50-
},
51-
"destination": {
52-
"type": "mqtt",
53-
"host": mqtthost,
54-
"clientid": algorithm,
55-
"topic": topic,
56-
},
57-
"parameters": {
58-
"every-nth-frame": every_nth_frame,
59-
"recording_prefix": "/tmp/" + sensor,
60-
},
61-
})
37+
"destination": {
38+
"type": "mqtt",
39+
"host": mqtthost,
40+
"clientid": algorithm,
41+
"topic": topic
42+
},
43+
"tags": {
44+
"sensor": sensor,
45+
"location": location,
46+
"algorithm": algorithm,
47+
"office": {
48+
"lat": office[0],
49+
"lon": office[1],
50+
},
51+
},
52+
"destination": {
53+
"type": "mqtt",
54+
"host": mqtthost,
55+
"clientid": algorithm,
56+
"topic": topic,
57+
},
58+
"parameters": {
59+
"crowd_count": {
60+
"zone": zone,
61+
"width": resolution["width"],
62+
"height": resolution["height"],
63+
"polygon": polygon
64+
},
65+
"every-nth-frame": every_nth_frame,
66+
"recording_prefix": "/tmp/" + sensor,
67+
}
68+
})
69+
else:
70+
pid,msg=PipelineManager.create_instance(self._pipeline,self._version,{
71+
"source": {
72+
"uri": uri,
73+
"type":"uri"
74+
},
75+
"destination": {
76+
"type": "mqtt",
77+
"host": mqtthost,
78+
"clientid": algorithm,
79+
"topic": topic
80+
},
81+
"tags": {
82+
"sensor": sensor,
83+
"location": location,
84+
"algorithm": algorithm,
85+
"office": {
86+
"lat": office[0],
87+
"lon": office[1],
88+
},
89+
},
90+
"destination": {
91+
"type": "mqtt",
92+
"host": mqtthost,
93+
"clientid": algorithm,
94+
"topic": topic,
95+
},
96+
"parameters": {
97+
"every-nth-frame": every_nth_frame,
98+
"recording_prefix": "/tmp/" + sensor,
99+
},
100+
})
62101
if pid is None:
63102
print("Exception: "+str(msg), flush=True)
64103
return

analytics/crowd-counting/Xeon/gst/Dockerfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# smtc_analytics_crowd_counting_xeon_gst
22

33
FROM smtc_analytics_common_xeon_gst
4-
RUN apt-get update -qq && apt-get install -qq python3-paho-mqtt python3-ply python3-requests python3-watchdog python3-pip && rm -rf /var/lib/apt/lists/*
5-
RUN pip3 install Pillow
4+
RUN apt-get update -qq && apt-get install -qq python3-paho-mqtt python3-ply python3-requests python3-watchdog python3-pillow && rm -rf /var/lib/apt/lists/*
65

76
COPY --from=smtc_common /home/*.py /home/
87
COPY *.py /home/

analytics/crowd-counting/Xeon/gst/pipeline/2/pipeline.json

+30-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"name": "crowd_counting",
3-
"version": 2,
4-
"type": "GStreamer",
5-
"template":"rtspsrc udp-buffer-size=212992 name=\"source\" ! queue ! rtph264depay ! h264parse ! video/x-h264 ! tee name=t ! queue ! decodebin ! videoconvert name=\"videoconvert\" ! video/x-raw,format=BGRx ! queue leaky=upstream ! gvainference infer-config=CPU_BIND_THREAD=NO model=\"{models[CSRNet_IR_model_2019R3][1][network]}\" model-proc=\"{models[CSRNet_IR_model_2019R3][1][proc]}\" name=\"detection\" ! queue ! gvametaconvert converter=json method=detection include-no-detections=true name=\"metaconvert\" ! gvapython name=\"crowdcounting\" module=\"crowd_counting\" class=\"CrowdCounting\" package=\"custom_transforms\" ! queue ! gvametapublish name=\"destination\" ! appsink name=appsink t. ! queue ! splitmuxsink max-size-time=60500000000 name=\"splitmuxsink\"",
2+
"name": "crowd_counting",
3+
"version": 2,
4+
"type": "GStreamer",
5+
"template":"rtspsrc udp-buffer-size=212992 name=\"source\" ! queue ! rtph264depay ! h264parse ! video/x-h264 ! tee name=t ! queue ! decodebin ! videoconvert name=\"videoconvert\" ! video/x-raw,format=BGRx ! queue leaky=upstream ! gvainference infer-config=CPU_BIND_THREAD=NO model=\"{models[CSRNet_IR_model_2019R3][1][network]}\" model-proc=\"{models[CSRNet_IR_model_2019R3][1][proc]}\" name=\"detection\" ! queue ! gvametaconvert converter=json method=detection include-no-detections=true name=\"metaconvert\" ! gvapython name=\"crowdcounting\" module=\"crowd_counting\" class=\"CrowdCounting\" package=\"custom_transforms\" ! queue ! gvametapublish name=\"destination\" ! appsink name=appsink t. ! queue ! splitmuxsink max-size-time=60500000000 name=\"splitmuxsink\"",
66
"description": "Crowd Counting Pipeline",
77
"source": {
88
"type": "object",
@@ -24,9 +24,33 @@
2424
}
2525
}
2626
},
27-
"parameters": {
27+
"parameters": {
2828
"type" : "object",
2929
"properties" : {
30+
"crowd_count": {
31+
"element": {
32+
"name": "crowdcounting",
33+
"property": "args"
34+
},
35+
"type": "object",
36+
"properties": {
37+
"zone": {
38+
"type": "integer"
39+
},
40+
"width": {
41+
"type": "integer"
42+
},
43+
"height": {
44+
"type": "integer"
45+
},
46+
"polygon": {
47+
"type": "array",
48+
"items": {
49+
"type": "number"
50+
}
51+
}
52+
}
53+
},
3054
"every-nth-frame": {
3155
"element":"detection",
3256
"type": "integer",
@@ -56,5 +80,5 @@
5680
"default":"recording"
5781
}
5882
}
59-
}
83+
}
6084
}

analytics/crowd-counting/count-crowd.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,15 @@
2424
runva=None
2525
stop=False
2626

27-
def connect(sensor, location, algorithm, uri):
27+
def connect(sensor, location, uri, algorithm, algorithmName, resolution, zonemap):
2828
global mqtt2db, rec2db, runva
2929

30+
print("==============count-crowd:connect:zonemap=",zonemap,"========================",flush=True)
31+
flatZonemap = []
32+
for sublist in zonemap[0]["polygon"]:
33+
for item in sublist:
34+
flatZonemap.append(item)
35+
3036
try:
3137
mqtt2db=MQTT2DB(algorithm) # this waits for mqtt
3238
rec2db=Rec2DB(sensor)
@@ -39,7 +45,7 @@ def connect(sensor, location, algorithm, uri):
3945

4046
# any VA exit indicates a camera disconnect
4147
with ThreadPoolExecutor(1) as e1:
42-
e1.submit(runva.loop, sensor, location, uri, algorithm, topic)
48+
e1.submit(runva.loop, sensor, location, uri, topic, algorithm, algorithmName, resolution, zonemap[0]["zone"],flatZonemap)
4349

4450
if not stop:
4551
mqtt2db.stop()
@@ -88,7 +94,7 @@ def quit_service(signum, sigframe):
8894

8995
# stream from the sensor
9096
print("Connected to "+sensor["_id"]+"...",flush=True)
91-
connect(sensor["_id"],sensor["_source"]["location"],algorithm,sensor["_source"]["url"])
97+
connect(sensor["_id"],sensor["_source"]["location"],sensor["_source"]["url"],algorithm,sensor["_source"]["algorithm"],sensor["_source"]["resolution"],sensor["_source"]["zonemap"])
9298

9399
# if exit, there is somehting wrong
94100
r=dbs.update(sensor["_id"],{"status":"disconnected"})

analytics/crowd-counting/custom_transforms/crowd_counting.py

+25-37
Original file line numberDiff line numberDiff line change
@@ -5,63 +5,51 @@
55
from PIL import Image, ImageDraw
66

77
class CrowdCounting:
8-
def __init__(self):
9-
self.numZone = 8
10-
self.mask=[0]*self.numZone
11-
self.crowd_count=[0]*self.numZone
12-
self.polygon=[0]*self.numZone
13-
8+
def __init__(self,zone=0,width=1024,height=768, polygon=[865,210,933,210,933,227,968,227,968,560,934,560,934,568,865,568,865,210]):
9+
print("===========CrowdCounting:__init__:zone,width,height,polygon=", zone, width, height, polygon, "================")
10+
1411
#self._sensor = sensor
15-
self.polygon[0] = [865,210,933,210,933,227,968,227,968,560,934,560,934,568,865,568,865,210]
16-
self.polygon[1] = [830,49,861,49,893,56,922,71,946,93,960,122,967,151,967,228,934,228,934,211,899,211,867,209,864,183,854,165,836,149,814,144,759,144,759,114,795,114,795,84,830,83,830,49]
17-
self.polygon[2] = [259,49,259,82,277,82,277,114,323,114,323,146,760,146,760,114,796,114,796,82,832,82,831,49,259,49]
18-
self.polygon[3] = [259,49,259,82,277,82,277,114,322,114,322,144,269,144,246,146,226,156,212,173,204,190,204,212,174,212,172,214,143,214,143,161,157,127,182,103,214,87,231,83,230,49,259,49]
19-
self.polygon[4] = [140,571,174,571,206,563,206,211,140,211,140,571]
20-
self.polygon[5] = [206,563,174,569,142,569,142,599,158,630,182,654,212,668,242,673,298,672,298,644,326,644,326,612,271,612,248,609,227,600,215,583,206,563]
21-
self.polygon[6] = [762,611,762,642,788,642,788,672,811,672,811,704,261,704,261,672,298,672,298,642,325,642,325,611,762,611]
22-
self.polygon[7] = [966,561,966,586,964,615,954,646,933,676,900,695,866,702,810,702,788,674,788,644,762,644,762,611,817,611,840,604,857,587,868,566,896,574,901,567,933,567,933,561,966,561]
12+
# self.polygons=[0]*8
13+
# self.polygons[0] = [865,210,933,210,933,227,968,227,968,560,934,560,934,568,865,568,865,210]
14+
# self.polygons[1] = [830,49,861,49,893,56,922,71,946,93,960,122,967,151,967,228,934,228,934,211,899,211,867,209,864,183,854,165,836,149,814,144,759,144,759,114,795,114,795,84,830,83,830,49]
15+
# self.polygons[2] = [259,49,259,82,277,82,277,114,323,114,323,146,760,146,760,114,796,114,796,82,832,82,831,49,259,49]
16+
# self.polygons[3] = [259,49,259,82,277,82,277,114,322,114,322,144,269,144,246,146,226,156,212,173,204,190,204,212,174,212,172,214,143,214,143,161,157,127,182,103,214,87,231,83,230,49,259,49]
17+
# self.polygons[4] = [140,571,174,571,206,563,206,211,140,211,140,571]
18+
# self.polygons[5] = [206,563,174,569,142,569,142,599,158,630,182,654,212,668,242,673,298,672,298,644,326,644,326,612,271,612,248,609,227,600,215,583,206,563]
19+
# self.polygons[6] = [762,611,762,642,788,642,788,672,811,672,811,704,261,704,261,672,298,672,298,642,325,642,325,611,762,611]
20+
# self.polygons[7] = [966,561,966,586,964,615,954,646,933,676,900,695,866,702,810,702,788,674,788,644,762,644,762,611,817,611,840,604,857,587,868,566,896,574,901,567,933,567,933,561,966,561]
2321

22+
self.zone = zone
23+
self.mask=[0]
24+
self.crowd_count=0
25+
self.polygon=polygon
26+
2427
#no matter what resolution the input video is (currently 720x1280),
2528
#it will resize to 1024x768 before sending to model
2629
#AI data input is 1/8 of image resolution, 768x1024 image, data is 1x96x128x1
27-
self.width = 1024>>3
28-
self.height = 768>>3
29-
for zone in range(self.numZone):
30-
for t in range(len(self.polygon[zone])):
31-
self.polygon[zone][t] = self.polygon[zone][t]>>3
30+
self.width = width>>3
31+
self.height = height>>3
32+
for t in range(len(self.polygon)):
33+
self.polygon[t] = self.polygon[t]>>3
3234

3335
#convert polygon to mask algorithm
3436
#https://stackoverflow.com/questions/3654289/scipy-create-2d-polygon-mask
3537
self.img = Image.new('L', (self.width, self.height), 0)
36-
for zone in range(self.numZone):
37-
self.img = Image.new('L', (self.width, self.height), 0)
38-
ImageDraw.Draw(self.img).polygon(self.polygon[zone], outline=1, fill=1)
39-
self.mask[zone] = numpy.array(self.img).flatten()
38+
ImageDraw.Draw(self.img).polygon(self.polygon, outline=1, fill=1)
39+
self.mask = numpy.array(self.img).flatten()
4040

4141
def process_frame(self, frame):
4242
for tensor in frame.tensors():
4343
data = tensor.data()
4444
imgData = []
4545
imgData.append(tensor.data())
46-
for zone in range(self.numZone):
47-
self.crowd_count[zone] = numpy.sum(self.mask[zone] * imgData)
46+
self.crowd_count = numpy.sum(self.mask * imgData)
4847

4948
if (self.crowd_count):
5049
messages = list(frame.messages())
5150
if len(messages) > 0:
5251
json_msg = json.loads(messages[0].get_message())
53-
json_msg["count"] = {
54-
"zone0":int(self.crowd_count[0]),
55-
"zone1":int(self.crowd_count[1]),
56-
"zone2":int(self.crowd_count[2]),
57-
"zone3":int(self.crowd_count[3]),
58-
"zone4":int(self.crowd_count[4]),
59-
"zone5":int(self.crowd_count[5]),
60-
"zone6":int(self.crowd_count[6]),
61-
"zone7":int(self.crowd_count[7])
62-
}
52+
json_msg["count"] = {"zone"+str(self.zone):int(self.crowd_count)}
6353
messages[0].set_message(json.dumps(json_msg))
64-
else:
65-
print("No JSON messages in frame")
6654

6755
return True

analytics/object-detection/Xeon/gst/pipeline/2/pipeline.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "object_detection",
33
"version": 2,
44
"type": "GStreamer",
5-
"template":"rtspsrc udp-buffer-size=212992 name=source ! queue ! rtph264depay ! h264parse ! video/x-h264 ! tee name=t ! queue ! decodebin ! videoconvert name=\"videoconvert\" ! video/x-raw,format=BGRx ! queue leaky=upstream ! gvadetect infer-config=CPU_BIND_THREAD=NO model=\"{models[mobilenet-ssd_2019R3][1][network]}\" model-proc=\"{models[mobilenet-ssd_2019R3][1][proc]}\" name=\"detection\" ! gvametaconvert converter=json method=detection name=\"metaconvert\" ! queue ! gvametapublish name=\"destination\" ! appsink name=appsink t. ! queue ! splitmuxsink max-size-time=60500000000 name=\"splitmuxsink\"",
5+
"template":"rtspsrc udp-buffer-size=212992 name=source ! queue ! rtph264depay ! h264parse ! video/x-h264 ! tee name=t ! queue ! decodebin ! videoconvert name=\"videoconvert\" ! video/x-raw,format=BGRx ! queue leaky=upstream ! gvadetect infer-config=CPU_BIND_THREAD=NO model=\"{models[person_detection_2019R3][1][network]}\" model-proc=\"{models[person_detection_2019R3][1][proc]}\" name=\"detection\" ! gvametaconvert converter=json method=detection name=\"metaconvert\" ! queue ! gvametapublish name=\"destination\" ! appsink name=appsink t. ! queue ! splitmuxsink max-size-time=60500000000 name=\"splitmuxsink\"",
66
"description": "Object Detection Pipeline",
77
"parameters": {
88
"type" : "object",

analytics/object-detection/detect-object.py

+3-5
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
myAlgorithm=""
2424
version=0
2525

26-
def connect(sensor, location, algorithm, uri):
26+
def connect(sensor, location, uri, algorithm, algorithmName):
2727
global mqtt2db, rec2db, runva
2828

2929
try:
@@ -38,7 +38,7 @@ def connect(sensor, location, algorithm, uri):
3838

3939
# any VA exit indicates a camera disconnect
4040
with ThreadPoolExecutor(1) as e1:
41-
e1.submit(runva.loop, sensor, location, uri, algorithm, topic)
41+
e1.submit(runva.loop, sensor, location, uri, topic, algorithm, algorithmName)
4242

4343
if not stop:
4444
mqtt2db.stop()
@@ -87,16 +87,14 @@ def quit_service(signum, sigframe):
8787
while not stop:
8888
try:
8989
print("Searching...", flush=True)
90-
print("sensor:'camera' and status:'idle' and algorithm='queue-counting' and office:["+str(office[0])+","+str(office[1])+"]")
91-
print("sensor:'camera' and status:'idle' and algorithm='"+myAlgorithm+"' and office:["+str(office[0])+","+str(office[1])+"]")
9290
for sensor in dbs.search("sensor:'camera' and status:'idle' and algorithm='"+myAlgorithm+"' and office:["+str(office[0])+","+str(office[1])+"]"):
9391
try:
9492
# compete (with other va instances) for a sensor
9593
r=dbs.update(sensor["_id"],{"status":"streaming"},seq_no=sensor["_seq_no"],primary_term=sensor["_primary_term"])
9694

9795
# stream from the sensor
9896
print("Connected to "+sensor["_id"]+"...",flush=True)
99-
connect(sensor["_id"],sensor["_source"]["location"],algorithm,sensor["_source"]["url"])
97+
connect(sensor["_id"],sensor["_source"]["location"],sensor["_source"]["url"],algorithm,sensor["_source"]["algorithm"])
10098

10199
# if exit, there is somehting wrong
102100
r=dbs.update(sensor["_id"],{"status":"disconnected"})

0 commit comments

Comments
 (0)