Commit 229e02da authored by I.K Seneviratne's avatar I.K Seneviratne

Committing some implementations in saving the lecture activity frame groupings into the database .

parent 97674ac5
...@@ -124,28 +124,35 @@ class LectureActivity(models.Model): ...@@ -124,28 +124,35 @@ class LectureActivity(models.Model):
return self.lecture_activity_id return self.lecture_activity_id
# this abstract class will define the lecture activity frame group percentages
class LectureActivityFrameGroupPercentages(models.Model):
phone_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
listen_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
note_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1)
class Meta:
abstract = True
# this abstract class will define the details for an activity frame group # this abstract class will define the details for an activity frame group
class LectureActivityFrameGroupDetails(models.Model): class LectureActivityFrameGroupDetails(models.Model):
frame_group = models.CharField(max_length=10) frame_group = models.CharField(max_length=10)
phone_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1) frame_group_percentages = models.EmbeddedField(
listening_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1) model_container=LectureActivityFrameGroupPercentages
writing_perct = models.DecimalField(default=0.0, max_digits=3, decimal_places=1) )
def __str__(self):
return self.frame_group
class meta: class Meta:
abstract = True abstract = True
# this class will contain the activity frame groupings # this class will contain the activity frame groupings
class LectureActivityFrameGroupings(models.Model): class LectureActivityFrameGroupings(models.Model):
name = models.CharField(max_length=15, default="") lecture_activity_frame_groupings_id = models.CharField(max_length=15, default="")
lecture_activity_id = models.ForeignKey(LectureActivity, on_delete=models.CASCADE) lecture_activity_id = models.ForeignKey(LectureActivity, on_delete=models.CASCADE)
frame_group_details = models.ArrayField(LectureActivityFrameGroupDetails) frame_group_details = models.ArrayField(model_container=LectureActivityFrameGroupDetails)
def __str__(self): def __str__(self):
return self.name return self.lecture_activity_frame_groupings_id
# EMOTIONS section # EMOTIONS section
......
...@@ -784,11 +784,56 @@ class GetLectureActivitySummary(APIView): ...@@ -784,11 +784,56 @@ class GetLectureActivitySummary(APIView):
def get(self, request): def get(self, request):
video_name = request.query_params.get('video_name') video_name = request.query_params.get('video_name')
frame_landmarks, frame_group_dict = ve.getFrameLandmarks(video_name)
frame_group_percentages = ar.activity_frame_groupings(video_name, frame_landmarks, frame_group_dict)
return Response({ # checking the existence of lecture activity frame grouping records in the db
"frame_landmarks": frame_landmarks, lec_activity_frame_groupings = LectureActivityFrameGroupings.objects.filter(lecture_activity_id__lecture_video_id__video_name=video_name).exists()
"frame_group_dict": frame_group_dict,
"frame_group_percentages": frame_group_percentages if (lec_activity_frame_groupings):
})
\ No newline at end of file return Response({
"frame_group_percentages": {}
})
else:
frame_landmarks, frame_group_dict = ve.getFrameLandmarks(video_name)
frame_group_percentages, activity_labels = ar.activity_frame_groupings(video_name, frame_landmarks, frame_group_dict)
# save the frame group details into db (temp method)
last_lec_activity_frame_grouping = LectureActivityFrameGroupings.objects.order_by('lecture_activity_frame_groupings_id').last()
new_lecture_activity_frame_grouping_id = "LAFG00001" if (last_lec_activity_frame_grouping is None) else \
ig.generate_new_id(last_lec_activity_frame_grouping.lecture_activity_frame_groupings_id)
# retrieve the lecture activity id
lec_activity = LectureActivity.objects.filter(lecture_video_id__video_name=video_name)
lec_activity_ser = LectureActivitySerializer(lec_activity, many=True)
lec_activity_id = lec_activity_ser.data[0]['id']
# create the frame group details
frame_group_details = []
for key in frame_group_percentages.keys():
obj = {}
obj['frame_group'] = key
obj['frame_group_percentages'] = frame_group_percentages[key]
frame_group_details.append(obj)
new_lec_activity_frame_groupings = LectureActivityFrameGroupings()
new_lec_activity_frame_groupings.lecture_activity_frame_groupings_id = new_lecture_activity_frame_grouping_id
new_lec_activity_frame_groupings.lecture_activity_id_id = lec_activity_id
new_lec_activity_frame_groupings.frame_group_details = frame_group_details
# save
new_lec_activity_frame_groupings.save()
return Response({
"frame_landmarks": frame_landmarks,
"frame_group_dict": frame_group_dict,
"frame_group_percentages": frame_group_percentages,
"activity_labels": activity_labels
})
\ No newline at end of file
...@@ -656,6 +656,7 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict): ...@@ -656,6 +656,7 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict):
# assign the difference # assign the difference
frame_group_diff[key] = diff if diff > 0 else 1 frame_group_diff[key] = diff if diff > 0 else 1
# looping through the frames # looping through the frames
for frame in os.listdir(EXTRACTED_DIR): for frame in os.listdir(EXTRACTED_DIR):
# getting the frame folder # getting the frame folder
...@@ -665,6 +666,7 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict): ...@@ -665,6 +666,7 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict):
phone_count = 0 phone_count = 0
note_count = 0 note_count = 0
listen_count = 0 listen_count = 0
detection_count = 0
# looping through the detections in each frame # looping through the detections in each frame
for detections in os.listdir(FRAME_FOLDER): for detections in os.listdir(FRAME_FOLDER):
...@@ -698,6 +700,11 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict): ...@@ -698,6 +700,11 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict):
elif label == class_labels[2]: elif label == class_labels[2]:
note_count += 1 note_count += 1
# increment the detection count
detection_count += 1
# finding the time landmark that the current frame is in # finding the time landmark that the current frame is in
for i in frame_landmarks: for i in frame_landmarks:
index = frame_landmarks.index(i) index = frame_landmarks.index(i)
...@@ -711,9 +718,13 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict): ...@@ -711,9 +718,13 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict):
if (frame_count >= i) & (frame_count < next_value): if (frame_count >= i) & (frame_count < next_value):
frame_name = "{}-{}".format(i, next_value) frame_name = "{}-{}".format(i, next_value)
frame_group_dict[frame_name]['phone_count'] += phone_count frame_group_dict[frame_name]['phone_count'] += phone_count
frame_group_dict[frame_name]['listen_count'] += listen_count frame_group_dict[frame_name]['listen_count'] += listen_count
frame_group_dict[frame_name]['note_count'] += note_count frame_group_dict[frame_name]['note_count'] += note_count
frame_group_dict[frame_name]['detection_count'] += detection_count
# increment the frame count # increment the frame count
frame_count += 1 frame_count += 1
...@@ -724,18 +735,36 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict): ...@@ -724,18 +735,36 @@ def activity_frame_groupings(video_name, frame_landmarks, frame_group_dict):
frame_group_phone_count = frame_group_details['phone_count'] frame_group_phone_count = frame_group_details['phone_count']
frame_group_listen_count = frame_group_details['listen_count'] frame_group_listen_count = frame_group_details['listen_count']
frame_group_note_count = frame_group_details['note_count'] frame_group_note_count = frame_group_details['note_count']
group_detection_count = frame_group_details['detection_count']
# print('frame group phone count: ', frame_group_phone_count)
# print('frame group listen count: ', frame_group_listen_count)
# print('frame group note count: ', frame_group_note_count)
# print('frame group detection count: ', group_detection_count)
frame_diff = int(frame_group_diff[key]) frame_diff = int(frame_group_diff[key])
frame_group_phone_perct = float(frame_group_phone_count / frame_diff) * 100 # print('frame difference: ', frame_diff)
frame_group_listen_perct = float(frame_group_listen_count / frame_diff) * 100
frame_group_note_perct = float(frame_group_note_count / frame_diff) * 100 frame_group_phone_perct = float(frame_group_phone_count / group_detection_count) * 100
frame_group_listen_perct = float(frame_group_listen_count / group_detection_count) * 100
frame_group_note_perct = float(frame_group_note_count / group_detection_count) * 100
# assign the values to the same dictionary # assign the values to the same dictionary
frame_group_dict[key]['phone_perct'] = frame_group_phone_perct frame_group_dict[key]['phone_perct'] = round(frame_group_phone_perct, 1)
frame_group_dict[key]['listen_perct'] = frame_group_listen_perct frame_group_dict[key]['listen_perct'] = round(frame_group_listen_perct, 1)
frame_group_dict[key]['note_perct'] = frame_group_note_perct frame_group_dict[key]['note_perct'] = round(frame_group_note_perct, 1)
# removing irrelevant items from the dictionary
frame_group_dict[key].pop('phone_count')
frame_group_dict[key].pop('listen_count')
frame_group_dict[key].pop('note_count')
frame_group_dict[key].pop('detection_count')
# print('frame group dict: ', frame_group_dict)
activity_labels = ['phone_perct', 'listen_perct', 'note_perct']
print('frame group percentages: ', frame_group_dict)
# return the dictionary # return the dictionary
return frame_group_dict return frame_group_dict, activity_labels
\ No newline at end of file \ No newline at end of file
...@@ -100,7 +100,8 @@ def getTimeLandmarks(video_name): ...@@ -100,7 +100,8 @@ def getTimeLandmarks(video_name):
initial_landmark = 0 initial_landmark = 0
time_landmarks = ['0:00:00'] # time_landmarks = ['0:00:00']
time_landmarks = []
time_landmarks_values = [0] time_landmarks_values = [0]
# loop through the threshold gap limit to define the time landmarks # loop through the threshold gap limit to define the time landmarks
...@@ -142,6 +143,7 @@ def getFrameLandmarks(video_name): ...@@ -142,6 +143,7 @@ def getFrameLandmarks(video_name):
# define frame landmarks # define frame landmarks
frame_landmarks = [0] frame_landmarks = [0]
# frame_landmarks = []
# loop through the threshold gap limit to define the time landmarks # loop through the threshold gap limit to define the time landmarks
for i in range(THRESHOLD_GAP): for i in range(THRESHOLD_GAP):
...@@ -175,7 +177,7 @@ def getFrameLandmarks(video_name): ...@@ -175,7 +177,7 @@ def getFrameLandmarks(video_name):
# loop through the group names to create a dictionary # loop through the group names to create a dictionary
for name in frame_group_list: for name in frame_group_list:
frame_group_dict[name] = {'phone_count': 0, 'listen_count': 0, 'note_count': 0} frame_group_dict[name] = {'phone_count': 0, 'listen_count': 0, 'note_count': 0, 'detection_count': 0}
return frame_landmarks, frame_group_dict return frame_landmarks, frame_group_dict
\ No newline at end of file
# Generated by Django 2.2.11 on 2020-10-07 12:29
import FirstApp.MongoModels
from django.db import migrations, models
import django.db.models.deletion
import djongo.models.fields
class Migration(migrations.Migration):
dependencies = [
('FirstApp', '0008_auto_20200825_1821'),
]
operations = [
migrations.CreateModel(
name='LectureActivityFrameGroupDetails',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('frame_group', models.CharField(max_length=10)),
('phone_perct', models.DecimalField(decimal_places=1, default=0.0, max_digits=3)),
('listening_perct', models.DecimalField(decimal_places=1, default=0.0, max_digits=3)),
('writing_perct', models.DecimalField(decimal_places=1, default=0.0, max_digits=3)),
],
),
migrations.CreateModel(
name='LectureActivityFrameGroupings',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(default='', max_length=15)),
('frame_group_details', djongo.models.fields.ArrayField(model_container=FirstApp.MongoModels.LectureActivityFrameGroupDetails)),
('lecture_activity_id', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='FirstApp.LectureActivity')),
],
),
]
...@@ -210,6 +210,15 @@ class LectureActivitySerializer(serializers.ModelSerializer): ...@@ -210,6 +210,15 @@ class LectureActivitySerializer(serializers.ModelSerializer):
fields = '__all__' fields = '__all__'
class LectureActivityFrameGroupingsSerializer(serializers.ModelSerializer):
lecture_activity_id = LectureActivitySerializer()
class Meta:
model = LectureActivityFrameGroupings
fields = '__all__'
# EMOTIONS section # EMOTIONS section
# lecture emotions serailzier # lecture emotions serailzier
class LectureEmotionSerializer(serializers.ModelSerializer): class LectureEmotionSerializer(serializers.ModelSerializer):
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
var global_video_name = ''; var global_video_name = '';
var student_behavior_summary = {}; var student_behavior_summary = {};
var lecture_video_time_landmarks = []; var lecture_video_time_landmarks = [];
var lecture_activity_frame_group_percentages = {};
$(document).ready(function () { $(document).ready(function () {
...@@ -56,7 +57,7 @@ ...@@ -56,7 +57,7 @@
let counter = $(this).attr('data-counter'); let counter = $(this).attr('data-counter');
alert('counter: ' + counter); {#alert('counter: ' + counter);#}
let real_date = new Date(global_lecture_date); let real_date = new Date(global_lecture_date);
//extract the day //extract the day
...@@ -250,20 +251,18 @@ ...@@ -250,20 +251,18 @@
//this function will handle the activity 'summary' button //this function will handle the activity 'summary' button
$('#activity_summary_btn').click(function () { $('#activity_summary_btn').click(function (e) {
//change the innerHTML of the clicked button
e.target.innerHTML = "<span class='font-italic'>Processing</span>";
//fetch the activity summary details //fetch the activity summary details
fetch('http://127.0.0.1:8000/get-lecture-activity-summary/?video_name=' + global_video_name) fetch('http://127.0.0.1:8000/get-lecture-activity-summary/?video_name=' + global_video_name)
.then((res) => res.json()) .then((res) => res.json())
.then((out) => alert(out.frame_landmarks)) .then((out) => activityFrameGroupPercentages(out, e))
.catch((err) => alert('error: ' + err)); .catch((err) => alert('error: ' + err));
//open the modal
$('#summaryModal').modal();
//render the chart onto the modal body
renderChart();
}); });
//this function will handle the emotion 'summary' button //this function will handle the emotion 'summary' button
...@@ -287,18 +286,81 @@ ...@@ -287,18 +286,81 @@
}); });
//this function will handle the retrieved activity frame group percentages
function activityFrameGroupPercentages(response, e) {
lecture_activity_frame_group_percentages = response.frame_group_percentages;
let frame_landmarks = response.frame_landmarks;
let frame_group_dict = response.frame_group_dict;
let activity_labels = response.activity_labels;
//change the button back to original
e.target.innerHTML = "Summary";
//open the modal
$('#summaryModal').modal();
//render the chart onto the modal body
renderChart(activity_labels);
}
//this function will call the chart function //this function will call the chart function
function renderChart() { function renderChart(activity_labels) {
//get the activity label length
let activity_label_length = activity_labels.length;
let data = [];
//loop through the activity labels
for (let k = 0; k < activity_label_length; k++) {
let label = activity_labels[k];
let datapoints = [];
let count = 0;
//loop through the activity frame groups
for (let key in lecture_activity_frame_group_percentages) {
let frame_group_details = lecture_activity_frame_group_percentages[key];
let activity_perct = frame_group_details[label];
let point = {label: lecture_video_time_landmarks[count], y: activity_perct};
let datapoints = []; datapoints.push(point);
count++;
}
let obj = {
type: "line",
showInLegend: true,
name: label,
markerType: "square",
{#xValueFormatString: "DD MMM, YYYY",#}
xValueFormatString: "hh:mm:ss",
color: getRandomColor(),
dataPoints: datapoints
};
data.push(obj);
}
//iterate through the time landmarks //iterate through the time landmarks
/*
for (let i = 0; i < lecture_video_time_landmarks.length; i++) { for (let i = 0; i < lecture_video_time_landmarks.length; i++) {
let point = {label: lecture_video_time_landmarks[i], y: Number(Math.round(Math.random() * 1000), 0)}; let point = {label: lecture_video_time_landmarks[i], y: Number(Math.round(Math.random() * 1000), 0)};
datapoints.push(point); datapoints.push(point);
} }
*/
var chart = new CanvasJS.Chart("chartContainer", { var chart = new CanvasJS.Chart("chartContainer", {
animationEnabled: true, animationEnabled: true,
theme: "light2", theme: "light2",
...@@ -315,7 +377,7 @@ ...@@ -315,7 +377,7 @@
} }
}, },
axisY: { axisY: {
title: "Number of Students", title: "Percentage",
includeZero: true, includeZero: true,
crosshair: { crosshair: {
enabled: true enabled: true
...@@ -326,21 +388,12 @@ ...@@ -326,21 +388,12 @@
}, },
legend: { legend: {
cursor: "pointer", cursor: "pointer",
verticalAlign: "bottom", verticalAlign: "top",
horizontalAlign: "left", horizontalAlign: "right",
dockInsidePlotArea: true, dockInsidePlotArea: true,
itemclick: toogleDataSeries itemclick: toogleDataSeries
}, },
data: [{ data: data
type: "line",
showInLegend: true,
name: "Activity",
markerType: "square",
{#xValueFormatString: "DD MMM, YYYY",#}
xValueFormatString: "hh:mm:ss",
color: "#000000",
dataPoints: datapoints
}]
}); });
chart.render(); chart.render();
} }
...@@ -380,7 +433,7 @@ ...@@ -380,7 +433,7 @@
name: label, name: label,
markerType: "square", markerType: "square",
{#xValueFormatString: "DD MMM, YYYY",#} {#xValueFormatString: "DD MMM, YYYY",#}
xValueFormatString: "Lec " + (i+1), xValueFormatString: "lec " + (i+1),
color: getRandomColor(), color: getRandomColor(),
dataPoints: datapoints dataPoints: datapoints
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment