Commit f6acbc30 authored by I.K Seneviratne's avatar I.K Seneviratne

Merge remote-tracking branch 'origin/QA_RELEASE' into monitoring_student_behavior_IT17138000

parents e3c708cb f0e57887
......@@ -10,6 +10,7 @@ from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from . import record
from . import test as t
from rest_framework.views import *
......@@ -171,3 +172,29 @@ class InitiateLecture(APIView):
return Response({
"response": "success"
})
class stopRecording(APIView):
def get(self, request):
t.isStop = 1
return Response({
"response": "stopped"
})
def post(self, request):
pass
# test method (delete later)
class TestAPI(APIView):
def get(self, request):
t.isStop = 0
param = request.query_params.get('param')
# t.test()
t.IPWebcamTest()
return Response({
"response": "started"
})
def post(self, request):
pass
\ No newline at end of file
......@@ -23,15 +23,12 @@ maskNet = load_model(os.path.join(settings.BASE_DIR,'face_detector/mask_detector
class IPWebCam(object):
def __init__(self):
self.url = "http://192.168.8.100:8080/shot.jpg"
self._count = 0
self.url = "http://192.168.8.103:8080/shot.jpg"
def __del__(self):
cv2.destroyAllWindows()
def get_frame(self):
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
imgResp = urllib.request.urlopen(self.url)
imgNp = np.array(bytearray(imgResp.read()),dtype=np.uint8)
img= cv2.imdecode(imgNp,-1)
......@@ -46,9 +43,6 @@ class IPWebCam(object):
frame_flip = cv2.flip(resize,1)
ret, jpeg = cv2.imencode('.jpg', frame_flip)
# capture frame and save on a given time in order to run the face recognition
sleep(3); cv2.imwrite("%d.jpg" % self._count, img)
self._count =+1
return jpeg.tobytes()
......
......@@ -43,6 +43,50 @@ function toggleLectureLive() {
y.style.display = "none";
}
}
var timer = false;
//this is a test function
function testAPI() {
timer = true
startTimer()
let param = 'sachith';
//call the API
fetch('http://127.0.0.1:8000/attendance/test-api/?param=' + param)
.then((res) => res.json())
.then((out) => {})
.catch((err) => alert('error: ' + err));
}
var time = 'time';
function f() {
let param = 'sachith';
//call the API
fetch('http://127.0.0.1:8000/attendance/stop-api/?param=' + param)
.then((res) => res.json())
.then((out) => {
timer = false
startTimer();
})
.catch((err) => alert('error: ' + err));
}
function startTimer() {
var min = 0;
var seconds = 0;
if (timer) {
var sec = 0;
function pad ( val ) { return val > 9 ? val : "0" + val; }
setInterval( function(){
min = pad(parseInt(sec/60,10));
seconds = pad(++sec%60)
document.getElementById("seconds").innerHTML=pad(++sec%60);
document.getElementById("minutes").innerHTML=pad(parseInt(sec/60,10));
}, 1000);
} else {
document.getElementById("secondsStop").innerHTML=seconds;
document.getElementById("minutesStop").innerHTML=min;
}
}
</script>
{% endblock %}
......@@ -60,13 +104,21 @@ function toggleLectureLive() {
<div class="card-body">
<button type="button" class="btn btn-success" id="initiate_btn" onclick="toggleLectureLive()">Show Live Stream</button>
{# <button type="button" class="btn btn-success" id="test_btn" onclick="testAPI()">Test</button>#}
</div>
<span id="minutes"></span>:<span id="seconds"></span>
<span id="minutesStop"></span>:<span id="secondsStop"></span>
<div style="vertical-align: middle; border-style: none; background-color: #055270; height: 500px; width: 100%">
<div class="row justify-content-center">
<img id="liveStreamLecture" style="display: none; height: inherit; margin-bottom: -25px;" src="{% url 'webcam_feed' %}">
</div>
<div class="row justify-content-center">
<button style="display: none; width: 70px; height: 70px;" id="liveStreamLectureStartButton" class="btn btn-warning btn-circle"><i class="fas fa-video"></i></button>
<div class="col">
<button style="display: none; width: 70px; height: 70px;" id="liveStreamLectureStartButton" class="btn btn-warning btn-circle" onclick="testAPI()"><i class="fas fa-video"></i></button>
</div>
<div class="col">
<button style="display: block; width: 70px; height: 70px;" id="liveStreamLectureStartButton" class="btn btn-warning btn-circle" onclick="f()"><i class="fas fa-square"></i></button>
</div>
</div>
</div>
</div>
......
import urllib3
import urllib.request as req
import cv2
import numpy as np
import time
isStop = 0
def IPWebcamTest():
# Replace the URL with your own IPwebcam shot.jpg IP:port
# url = 'http://192.168.2.35:8080/shot.jpg'
url = 'http://192.168.8.103:8080/shot.jpg'
# url = 'http://192.168.1.11:8080/startvideo?force=1&tag=rec'
# url = 'http://192.168.1.11:8080/stopvideo?force=1'
size = (600, 600)
vid_cod = cv2.VideoWriter_fourcc(*'XVID')
# vid_cod = cv2.VideoWriter_fourcc('M', 'J', 'P', 'G')
# output = cv2.VideoWriter("cam_video.avi", vid_cod, 20.0, (640, 480))
# output = cv2.VideoWriter("cam_video.mp4", vid_cod, 20.0, size)
output = cv2.VideoWriter("cam_video.mp4", vid_cod, 10.0, size)
no_of_frames = 0
while True:
# Use urllib to get the image from the IP camera
imgResp = req.urlopen(url)
# imgResp = urllib3.respon
# Numpy to convert into a array
imgNp = np.array(bytearray(imgResp.read()), dtype=np.uint8)
# Finally decode the array to OpenCV usable format ;)
img = cv2.imdecode(imgNp, -1)
# resize the image
img = cv2.resize(img, (600, 600))
# put the image on screen
# cv2.imshow('IPWebcam', img)
# write to the output writer
output.write(img)
# To give the processor some less stress
# time.sleep(0.1)
# time.sleep(1)
no_of_frames += 1
if isStop == 1:
break
# imgResp.release()
# cv2.destroyAllWindows()
print('no of frames: ', no_of_frames)
\ No newline at end of file
......@@ -2,7 +2,7 @@ from django.urls import path
from .api import student_list, student_detail, subject_list, subject_detail, attendance_list, StudentAPIView, \
StudentDetails
from django.conf.urls import url
from .api import FileView, InitiateLecture
from .api import *
from . import views
urlpatterns = [
......@@ -19,5 +19,10 @@ urlpatterns = [
url(r'^upload/$', FileView.as_view(), name='file-upload'),
path('webcam_feed', views.webcam_feed, name='webcam_feed'),
# this url will initiate the lecture
url(r'^process-initiate-lecture/$', InitiateLecture.as_view())
url(r'^process-initiate-lecture/$', InitiateLecture.as_view()),
# this url will be used for testing
url(r'^test-api/$', TestAPI.as_view()),
url(r'^stop-api/$', stopRecording.as_view())
]
from django.shortcuts import render
from django.http.response import StreamingHttpResponse
from AttendanceApp.camera import IPWebCam
from FirstApp.MongoModels import LectureVideo
from FirstApp.serializers import LectureVideoSerializer
def initiate_lecture(request):
lecture_video = LectureVideo.objects.all()
lecture_video_ser = LectureVideoSerializer(lecture_video, many=True)
print('lecture video data: ', lecture_video_ser.data)
return render(request, "AttendanceApp/Initiate_lecture.html")
def gen(camera):
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
def webcam_feed(request):
return StreamingHttpResponse(gen(IPWebCam()),
content_type='multipart/x-mixed-replace; boundary=frame')
\ No newline at end of file
return StreamingHttpResponse(gen(IPWebCam()),
content_type='multipart/x-mixed-replace; boundary=frame')
from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
......@@ -10,6 +11,33 @@ from .serializers import *
import datetime
##### LECTURER VIDEO SECTION #####
# this API will handle basic lecturer video retrieval/saving
class LecturerVideoAPI(APIView):
def get(self, request):
lecturer_videos = LectureRecordedVideo.objects.all()
lecturer_videos_ser = LectureRecordedVideoSerializer(lecturer_videos, many=True)
lecturer_videos_ser_data = lecturer_videos_ser.data
return Response({
"response": lecturer_videos_ser_data
})
def post(self, request):
serializer = LectureRecordedVideoSerializer(data=request.data)
if serializer.is_valid(raise_exception=ValueError):
# serializer.create(validated_data=request.data)
serializer.create(validated_data=request.data)
return Response(serializer.data, status=status.HTTP_201_CREATED)
##### END OF LECTURER VIDEO SECTION #####
##### LECTURER ACTIVITY SECTION #####
class ActivityRecognitionAPI(APIView):
......@@ -61,6 +89,23 @@ class GetLectureVideoResultsAPI(APIView):
"response": percentages
})
# this API will process lecturer video frame recognitions
class ProcessLecturerFrameRecognitionsAPI(APIView):
def get(self, request):
video_name = request.query_params.get('video_name')
frame_recognitions, fps = classroom_activity.save_frame_recognition(video_name)
int_fps = int(fps)
# print('frame recognitions: ', frame_recognitions)
return Response({
"frame_recognitions": frame_recognitions,
"fps": fps
})
##### END OF LECTURER ACTIVITY SECTION #####
......@@ -169,6 +214,43 @@ class LectureAudioTextAPI(APIView):
})
# this API will save the lecture audio analysis
class ProcessLectureAudioAnalysis(APIView):
def get(self, request):
# lec_audio_text = ta.run()
# (this is temporary)
lec_audio_text = {
'num_of_words': 5000,
'lexical_count': 300,
'non_lexical_count': 40
}
last_lec_audio_text_id = LecturerAudioText.objects.order_by('lecturer_audio_text_id').last()
new_lec_audio_text_id = "LAT001" if (last_lec_audio_text_id is None) else ig.generate_new_id(
last_lec_audio_text_id.lecturer_audio_text_id)
# retrieve the lecture audio summary object (temporary)
lecture_audio_summary = LectureAudioSummary.objects.filter(lecture_audio_summary_id='LAU004_sum')[0]
# save the lecture audio text object
LecturerAudioText(
lecturer_audio_text_id=new_lec_audio_text_id,
lecturer_audio_text_wordcount=lec_audio_text['num_of_words'],
lecturer_audio_text_lexical_wordcount=lec_audio_text['lexical_count'],
lecturer_audio_text_non_lexical_wordcount=lec_audio_text['non_lexical_count'],
lecturer_audio_text_status='Average',
lecturer_audio_original_text=lecture_audio_summary
).save()
return Response({
"response": "success"
}, status=status.HTTP_201_CREATED)
# this API will retrieve lectuer audio summary for given period
class LecturerAudioSummaryPeriodAPI(APIView):
......@@ -250,4 +332,3 @@ class StudentLecturerIntegratedAPI(APIView):
"fps": fps
})
import requests
# this method lists down the main methods that need to be executed when the lecturer performance module is under operation
def lecturer_batch_process(video_name, audio_name):
# As the first step, calculate the lectuer activity details
lecturer_activity_resp = requests.get('http://127.0.0.1:8000/activities/?video_name=' + video_name)
# save the lecturer video frame recognitions
lecturer_video_frame_recognitions_resp = requests.get('http://127.0.0.1:8000/process-lecturer-video-frame-recognitions/?video_name=' + video_name)
# processing the lecture audio
lecture_audio_text_resp = requests.get('http://127.0.0.1:8000/lecturer/process-lecture-audio-analysis')
# this method will save the lecturer video details
def save_lecturer_video_details(video):
lecturer_video_resp = requests.post('http://127.0.0.1:8000/lecturer-video', video)
\ No newline at end of file
......@@ -2,11 +2,11 @@ import scripts
import re
import os
# change the method signature, IMMEDIATELY
def run():
# this dictionary will be returned
analysis = {}
# define the BASE path
BASE_PATH = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
FILE_PATH = os.path.join(BASE_PATH, "MonitorLecturerApp\\lecture_Notes\\sample_text2.txt")
......@@ -81,7 +81,7 @@ def run():
lexical_count += d[key]
# print('\n number of occurrences (that)', d[key])
# "jest" newei bn "just"
elif (key == "just"):
lexical_count += d[key]
# print('\n number of occurrences (just)', d[key])
......@@ -210,6 +210,8 @@ def get_lecturer_audio_summary_for_period(lecture_audio_text_data):
# append to the list
individual_lec_data.append(individual_lecture)
#saving processed to the db
return individual_lec_data, labels
\ No newline at end of file
from rest_framework import serializers
from FirstApp.MongoModels import Lecturer, Subject
from FirstApp.serializers import LecturerSerializer, SubjectSerializer
from LectureSummarizingApp.models import LectureAudioSummary
from .models import RegisterTeacher, LecturerActivityFrameRecognitions
from .models import LecturerAudioText, LecturerVideoMetaData, LecturerVideo, LectureRecordedVideo
from FirstApp.logic import id_generator as ig
import datetime
class RegisterTeacherSerializer(serializers.ModelSerializer):
class Meta:
model = RegisterTeacher
......@@ -19,7 +24,6 @@ class LecturerVideoSerializer(serializers.ModelSerializer):
class LecturerAudioTextSerializer(serializers.ModelSerializer):
lecturer_audio_original_text = LectureAudioSummary()
class Meta:
......@@ -28,7 +32,6 @@ class LecturerAudioTextSerializer(serializers.ModelSerializer):
class LectureRecordedVideoSerializer(serializers.ModelSerializer):
lecturer = LecturerSerializer()
subject = SubjectSerializer()
......@@ -36,9 +39,47 @@ class LectureRecordedVideoSerializer(serializers.ModelSerializer):
model = LectureRecordedVideo
fields = '__all__'
# this method will override the 'create' method
def create(self, validated_data):
lecturer = None
subject = None
lecturer_data = validated_data.pop('lecturer')
subject_data = validated_data.pop('subject')
# serialize the lecturer data
lecturer = Lecturer.objects.filter(id=lecturer_data)
subject = Subject.objects.filter(id=subject_data)
# retrieve the last lecture video details
last_lec_video = LectureRecordedVideo.objects.order_by('lecture_video_id').last()
# create the next lecture video id
new_lecture_video_id = ig.generate_new_id(last_lec_video.lecture_video_id)
# if both subject and lecturer details are available
if len(lecturer) == 1 & len(subject) == 1:
str_video_length = validated_data.pop('lecture_video_length')
video_length_parts = str_video_length.split(':')
video_length = datetime.timedelta(minutes=int(video_length_parts[0]),
seconds=int(video_length_parts[1]),
milliseconds=int(video_length_parts[2]))
lecture_video, created = LectureRecordedVideo.objects.update_or_create(
lecture_video_id=new_lecture_video_id,
lecturer=lecturer[0],
subject=subject[0],
lecturer_date=validated_data.pop('lecturer_date'),
lecture_video_name=validated_data.pop('lecture_video_name'),
lecture_video_length=video_length
)
class LecturerVideoMetaDataSerializer(serializers.ModelSerializer):
return lecture_video
return None
class LecturerVideoMetaDataSerializer(serializers.ModelSerializer):
lecturer_video_id = LectureRecordedVideoSerializer()
class Meta:
......@@ -46,16 +87,13 @@ class LecturerVideoMetaDataSerializer(serializers.ModelSerializer):
fields = '__all__'
# lecture activity frame recognition serializer
class LecturerActivityFrameRecognitionsSerializer(serializers.ModelSerializer):
lecturer_meta_id = LecturerVideoMetaDataSerializer()
frame_recognition_details = serializers.SerializerMethodField()
# this method will be used to serialize the 'frame_recogition_details' field
def get_frame_recognition_details(self, obj):
return_data = []
for frame_recognition in obj.frame_recognition_details:
......@@ -71,8 +109,6 @@ class LecturerActivityFrameRecognitionsSerializer(serializers.ModelSerializer):
# return the data
return return_data
class Meta:
model = LecturerActivityFrameRecognitions
fields = '__all__'
......@@ -12,6 +12,10 @@ urlpatterns = [
path('lecture-video', views.lecVideo),
# path('Video', views.hello)
##### LECTURER VIDEO SECTION #####
# API to retrieve/save lecturer video details
url(r'^lecturer-video/$', api.LecturerVideoAPI.as_view()),
##### LECTURER ACTIVITY SECTION #####
# API to retrieve activity recognition
url(r'^activities/$', api.ActivityRecognitionAPI.as_view()),
......@@ -22,18 +26,29 @@ urlpatterns = [
# API to retrieve lecturer video frame recognitions
url(r'^get-lecturer-video-frame-recognitions/$', api.StudentLecturerIntegratedAPI.as_view()),
# API to process lecturer video frame recognitions
url(r'^process-lecturer-video-frame-recognitions/$', api.ProcessLecturerFrameRecognitionsAPI.as_view()),
##### END OF LECTURER ACTIVITY SECTION #####
##### LECTURE AUDIO SECTION #####
# API to retrieve audio analysis
url(r'^get-audio-analysis/$', api.GetLectureAudioAnalysis.as_view()),
# API to save audio analysis
url(r'^process-lecture-audio-analysis/$', api.ProcessLectureAudioAnalysis.as_view()),
# API to retrieve lecture audio text
url(r'^get-lecture-audio-text', api.LectureAudioTextAPI.as_view()),
# API to retrieve lecture audio text
url(r'^get-lecturer-audio-summary-for-period', api.LecturerAudioSummaryPeriodAPI.as_view()),
##### END OF LECTURE AUDIO SECTION #####
# test API
url(r'^test-api', api.TestAPI.as_view()),
......
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