Virtual Quiz Game using OpenCV Python | CVZone

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome to my channel in this video we are going to create a virtual quiz game using artificial intelligence we will import all the question using a csv file and then use our hand in the air to answer them we will go step by step so that it is easy to follow if you would like to level up your computer vision skills do check out our premium courses for the first time ever we have a computer vision with arduino course available now for pre-order the links are in the description below so without further ado let's get started so here we are in our pyjama project and you can see that the name of the project is virtual quiz and what we will do is we'll first go to file settings and the project python interpreter and we will add now here we are going to add cv zone cv zone we have to use version 1.5.1 so this or above this so we have to use this and then we have media media pipe and we are going to again hit install so these are the two libraries that we will be needing and all of the dependencies they are automatically installed as you can see here so i've already done that i'm not going to repeat that and this is our main file i'm going to remove everything from here and we are going to add our code within this file now the idea here is that we are going to first use our webcam and once we have the webcam running we are going to import the data from a file a csv file and then we are going to add the questions uh on our webcam so let's go ahead and try that out so we will import here cv2 and then we are going to write here cv2 dot video capture and we will put the id of number two you should put the id of zero i have multiple cameras that's why i'm putting two and then we are going to increase the size of our image so we will write here cap dot set we want to make it the width to be 120 or 1 2 8 0 and the cap dot sets the height to be 720 and then we are going to write while true and then we will write success and image is equals to cap dot read and then we are going to write cv2 dot im show we will write here img and then img and then we will write cv2 dot weight key and we will give a delay of 1 milliseconds so this should run our webcam so lets go ahead and try it out so there we have it so this is the webcam we are going to use our hand probably the left one but here you can see the images flipped so let's go ahead and flip it so we are going to write here image is equals to image is equals to cv2 dot flip and we are going to write image and we want to flip it in the horizontal direction so let's run that again and hopefully yeah now it's fine so this is the right side and this is the left side okay so now what we have to do is we have to create the data first so what you can do is you can go to something like google sheet or microsoft excel and you can create a csv file so here you can see you have question choice one two three and then the answer so you can either do this or you can right click here creates a new file and let's call it mmcqs dot csv and here we are going to add so we can write here that the first heading will be the question then the csv stands for comma separated values so whenever we want a new value we will add a comma so then we will have choice 1 then we will have choice 2 then choice 3 and then choice 4 and the last thing will be the answer so we need to know which is the correct answer so here for example we will write the first question how many corners does a rectangle triangle have so then we are going to put a comma and then we will write the answers so two three four and five so these are the options and the last thing we have to write is the actual answer so this time uh for this this part this question we can see the answer is three so we will write here two so this is choice number one choice number two so we are writing the answer is choice number two the same way we can write for example what is the variable type of a where a is equals to yes so we can write the answers or the first one is integer then we have float and then we have string and then we have character so the answer the correct one is number three so one two and three so we will write here three so i hope you understand the concept here and each of these is uh written on a new line so that is how we are going to separate them when we are about to load it when we will import it so we will save it and do we need to change anything no so far it looks fine so we can go to our main file and here the first thing we will do we are going to import the c csv file uh let's say data so import csv data so that's the main idea so we are going to write here path c s v is equals to uh the name of the file so mcqs dot csv mcqs dot csv so this is the path and then we are going to open it so we will write here with open we are going to say path path csv and then uh we need to separate it with the new line so the new line is represented y by slash n so this is how the new line is presented and we will open it as f and then we are going to say that our reader is equals to csv dot reader and we are going to read from the file f but what is this csv we are going to import the library so import cscsv so it will read the csv file and then we need to store it in a list so we are going to write here data is equals to lists and we are going to convert the reader into list and we want to ignore the first one and i will show you why let's just print out the data so this will print the data over here there you go so you can see now it's a list and you can see this is uh let's say question one this is question two but this part here is the heading so we don't really want the heading so what we can do is either you can remove it from here but i don't recommend that because if somebody is looking at it they might not understand what is happening so what i do recommend is that we go here and we remove the first element so we are saying ignore zero starting from one till the end so if i run this now you will see it will only show us the questions so this is question one then question two uh yeah we added only two questions if we want to check the total length we can write here length of data and that will tell us how many questions do we have and this information is very important to us because later on we are going to use this information to calculate the total score and see how many questions are left okay so this is done and what we can do is we can create for example question number is equals to zero and then question total the total number of questions is equals to length of data so these two variables we are going to use later on and we can remove this part for now so now we have to create a class this class is basically an mcq so each mcq will be an object and we can have the correct answer for the object we can check where exactly is the correct answer located and then we can update whether the user answered it properly or not so this can be done with functional programming as well but it will be better suited with object oriented programming so that's why we are going to create a class so what we will do is we will go up and we are going to right here we are going to write here class and we will simply write mcq so each mcq will be an object uh forgot to add the colon okay so then def this is the initialization and in the initialization we need the data now this data is not this here uh okay let me change this um let's say data all so that it's not confusing so this is the data of all the questions and this is for one single question so one single mcq so what we need to do is we need to create some variables so we will write here self dot question now question is basically the first element so here you can see this is the first element this is the question the second element is the choice the third element is the choice so we need to write it down here so we will say that data at 0 is basically our question and then we have the choice so we are going to write here choice one and this is at one and we can duplicate it multiple times and we can write here choice two three and four and again we can write here two three and four so these are our choices and the last thing we have the last thing we have is the answer so so we will write here answer is equals to data at number five but the answer we are going to check it later on with an integer value so we are going to see that if the actual value was uh if the actual index was 2 for example here if it was 2 and the user clicked at 2 then it is a correct answer so we need to check that later on so what we will do is we will change this to integer so that later on we can compare it with an actual value so if it doesn't make that much sense at this point it's fine later on we will look at it in detail now the last thing we need uh for the initialization is the user answer so this is the correct answer but we also need what did the user answer so we will write here user ons is equals to none so initially it will be none and if there is a value it means the user has given an input for this particular answer and if that is the case then we can proceed to the next question again that i will explain later on but for now we are going to keep it like this and now what we will do is we will create objects for each of these what do you call each of these lines so each of these questions will be an object so how can we do that it is very simple we are going to simply write it down here we are going to write here creates objects for each mcq so we are going to write uh that there is a list of mcq so mcq list is empty and then we are going to say for let's say question in data all we are going to write here mcq this is how we can create an object mcq and then we are sending in the data so this is the data and then we have already all the information how to retrieve the appropriate values so we just need to send the value of q that's it so this is how you can create an object but then you need to store it in the list this list so we are going to write here dot append and then we are going to put it inside here so if i print now uh print the length of mcq mcq list it should give me uh the value of two so let's run that and there you go so this is the value of two so it means it is working so far so this is good now we have our questions and each of these question is basically what do you call an object so what is the next step the next step is basically first of all finding our hand so here we can simply write using the uh hand detector first of all we need to import it so we will write here from cv zone dot hand detector hand tracking module import hand detector and here we are going to create the hand detector so we will write a detector detector is equals to hand detector and we will give the minimum confidence um is it the tracking contract no we need the detection detection confidence as 0.8 so we are just making it a little bit harder to detect because we want more accurate values we don't want to accidentally uh click the wrong answer so we are giving a larger probability okay so once that is done we can simply go down and here we can say that hands and image will be returned from the detector dot hands uh not fans find hands yeah find hands and then we will write image and yeah that's pretty much it what we require so if we run this now it should show me the hand there you go so even though it's not my right hand um okay let's fix it you can you can write it here flip type is equals to false so by default it is flipping uh because we flipped here if we didn't flip here we would not have to do anything here it would work by default but because we are flipping over here above so we need to remove the flip so here now it's showing me that it is the left hand so this is the left hand this is the right hand so that is working fine okay so now what we can do is uh we can basically put the questions on the webcam image and then we can check whether they have been clicked or not so how can we do that first of all what we will do is we will just put one question because we don't want to complicate things at the very beginning we will put one question and then we will loop through all the questions so how can you put a question now you can simply put the text but it will not be very visible because uh you might have different colors on your webcam image if the background image is black and your text is black it will not show if the background is white and your text is bright again it will not show so the best idea is to put a rectangle behind the text but this is quite difficult because there's no function by default that allows you to have the rectangle and the text on top of each other so what we have done is in the cv zone package we have created a function that will allow you to do this and it will rescale it will size and do everything for you all you have to write it all you have to do is call the function so let me show you how it works so we are going to write the question first so right now all the questions are stored in mcq list so we are going to see my first mcq is equals to mcq list mcq list at zero okay again later on we are going to loop through that but for now we are just going to keep it at zero so this will be the first question now the interesting part we are going to put a rectangle we are going to put the text with the background of rectangle so normally you would write cv2 dot put text to put the text but with cv zone you can put it with the rectangle so you can write here cv zone dot put text uh why is it not showing because we didn't import it so we need to write here import cv zone and yeah so we will go down here and we will write here put text rectangle so here we have a lot of parameters because there's a lot of possibilities but most of them they are already declared so you don't have to write them down you just have the option to change them if you want so here we are going to first of all write the image so this is the image that we want to put it on and then we have the text so the text will be the question the question of our object so we will write here mcq dot question so this will be the text and then we need to give it a position so let's say we will give it hundred by hundred and then we have the scale and the thickness so let's put the value of two and two so these are random values you can change as you wish now this is pretty much what is required even these two are not required only these three things are required to make it run so let me show you how it will look like uh no actually we need to return so we need to write here image and then there is another parameter that is given we um okay let me discuss that as well it is basically the bounding box information when you are putting the text you don't know how big the text will be so you don't know how big the rectangle will be the bounding box that is behind the text so uh this function basically returns us this value in case we want to use it because in this uh quiz program we need to use it to know if we have clicked on that rectangle or the text or not so we need that information so we can write here bounding box uh okay so that is good let's run that and there you go how many corners does a triangle have so this is the question but again you can see uh it is very basic now let me show you a few things you can do uh the first thing you can do is you can write an offset an offset will give it a little bit of a margin at the end a little bit of clearance so let's say 50. i will put a big value so you can see the difference there you go so now the question is really big and you can see there is boundary left right up and down so uh let's keep it at 50 why not then we also have the option of border the border will create an outline that will be of a different color so let's put a width of 5. if you want to change the color you can write here color for the border is equals to whatever color you want but by default i believe it is green so let's check that out yeah so there you go so now we have a rectangle uh we have a border we have a margin or an offset and the text is perfectly aligned in the center so this is what exactly what we want the same thing we need to do with all our all our choices so we will put it four times and what we will do is we will write here bounding box one bounding box two three and four and then the mcq question will be replaced with choice 1 then choice 2 and then choice choice 3 and then choice 4. there you go now we need to change the positioning the positioning let's start it from where we began so let's keep this hundred and hundred and let's move this 400 and 400. and for the y-axis let's keep these two at 250 and then the other two at 400. um border and this yeah let's keep it the same let's see if it looks nice if it does we can keep it same otherwise we can change it okay there you go so i think it looks good so we have how many corners does a triangle have two three five four and we have those options now uh if you wanted to change the question you can simply write one and it will change the question so there you go what is the variable type what did i write type po of a let me change that what is that type okay let me save that so you get the idea you can change the questions from here but again as i mentioned before we are not going to change it now uh the only thing we want to do now is to check whether we have clicked or not and whether we are storing the correct answer or not so we will go step by step and we will change it later on okay so now this is drawing all the questions that is good but then the next step we have to do is to we have to check if we have clicked on an answer so what do we need to do first of all we will check if there are any hands available so this hand is basically coming from this fine hands method and if there are any hands then only we are going to check if it is clicked or not and so on so we need the points so this hand will basically return multiple hands so first of all we need to get the first hand that we get so hands at zero so this is the first hand and then within that we have multiple attributes that we can grab so the one that we need is the landmark list so within that landmark list we will have the information of our index finger so we need to move around and see where is our index finger and whether our index finger is on one of the answers or not and we are also going to check whether it clicked or not so the clicking will happen with the index finger and the middle finger so again i will explain this a little bit more further as we go along so we will write here we need the lm list l here is capital this one is capital this one is small and then we are going to store it in lm list a variable called lm list and then we need the cursor so the cursor is like the mouse so your cursor is basically the tip of your index finger so wherever you move it we need that information so we will call it cursor is equals to lm list at eight so how do i know that this is point number eight this is provided by mediapipe and they have mentioned all the details of which point is which number so point number eight is basically the tip of the index finger similarly point number 12 is the tip of the middle finger so we will use that later on in fact we need to use it now so the first thing we need to check is whether we have clicked or not so to check that we need to find the distance between our index finger and the middle finger so we will write here detector dot find distance between lm list at point eight at point eight and lm lists lm list at point twelve so this and then we can simply return we can send in our image so that it can return us the image back so it will give us length and then it will give us the information extra information and then it will return us the image that has the drawing on it so let me show you how that looks like before we go any further so there is my hand and you can see this is the tip of the index finger this is the tip of the middle finger and we are finding the distance between them so when i click this is how we will click so we are checking the distance between these two the length between these two when it is low it means we have clicked this is how we will send in our answer so we need to print out the length so we will write here length and then we will print it out and there you go so i am close to my table and at this point you can see it is around actually i will do it with my left hand so i'm going to try it from here um so i want this distance it's around 50ish this is 100 ish so i want to be clicking like this so it's less than 50 so let's say less than 60 so if the length is less than 60 then we are going to print uh clicked so we can remove that and we will format and we will run so now it's not clicked and let's bring in my hand and if i click you can see it's a it says clicked again clicked i need to go back a little bit clicked clicked there you go so this is working now and what we need to do next is we need to check where exactly did it click because if it's clicking anywhere i don't care about that i care when it is clicking on one of the choices so that is what we need to find next so how can we do that we need to create a method within our mcq so that it will check all of the four answers and it will check whether it was clicked or not so any of those answers were clicked or not so how can we do that let's write it down here we are going to write a new method here called updates updates and do we need anything yeah we need the cursor so this is the index um tip of the index finger and then we need the bounding boxes information so all of the bounding boxes so we will need four of them one two three four so all of these these are all the bounding box information of the four choices so we will go one by one to each choice and we will check whether that choice has been clicked or not so how can we do this it's very simple we will simply write four box in bounding boxes we will loop through all of them and then we will extract the information x1 y1 x2 and y2 is equals to the bounding box and then we will create our if statement if our x1 is less than x2 and y1 is less than y2 i forgot to write the end so less than what so we are saying that if our cursor cursor at point zero which is x basically so this is the x value of our index tip so if that tip is in between x one and x two then it is good and then it will also check if the cursor cursor at 1 which is the value of y is in between y1 and y2 so that will mean it is within that box if that is the case then we are going to write self dot user answer is equals to our x value but what is the x value we don't know because uh we are not counting the number of loops so we need to count that by writing x and we will write here enumerate you can write i as well a lot of people use i so you can write that so this will be our value so for example if choice number three is clicked then user answer will be choice three actually it will be choice two because it is starting from zero so zero one two three but our choices are one two three four so what we can do is we can just write plus one because in the mcqs uh i'm not writing this as zero if this was zero one two three then it will be fine but we are writing it like one two three four so we need to write the same thing here so we'll write x plus one so that's the basic idea and to give the user a little bit of feedback what we will do is we will color it with green so do we have it anywhere written rectangle are we drawing a normal rectangle anywhere no okay what we will do here is we will write cb2 dot rectangle and we will give in our image we will give in x one y one and then we will give an x to y two and what else the color zero two five five which is green and then the thickness will be cb2 dot fill filled there you go so that is basically the idea and if we run this now it will be interesting to see no i'm going too fast we need to first why is this an error uh we need to first call it here we need to update this method so once we get the information once we know that we are simply going to write mcq dot update and now we need to send in two things as we have seen here we need to send in the cursor and the bounding boxes so the cursor is basically cursor we have the same name and then the bounding boxes it should be a list so we will write here bounding box one bounding box two bounding box three and bounding box four so these are the bounding boxes that we are sending and do we need to do anything else okay let's just run this now and later on we will check what is missing there you go so if i bring in my hand and if i click on five you can see it turns green so that is a very good sign that it is working if i do it three two and four so this this drawing is happening above the question that's why it's um hiding it a little bit i don't like that so what we can do is we can go to the distance part and we can remove the image here and we can remove the image here so it will not draw on it so this way it will not be annoying so let's try that again so if i click there you go five uh let me go back a little bit four and two there you go so now we need to check whether we are saving the value or not so here we are actually saving it but we don't know what is happening is it actually working or not so we can write here that we want to print the value mcq dot what was the name user answer yes user answer and we want to print it so by default it should be none because if you remember in the initialization we wrote it as none so once we go through all of this if it is the correct one if user has selected some then it will change it to a number so that is what we are going to observe so we will observe what will happen so it will print out the value here just keep looking on the terminal on the console so here you can see right now it should be none but it's not giving yeah it is none when i'm clicking it says none because nothing is happening but if i go to three and i click now it is giving me the value of two so this is one two three four so if i click on five it should give me four there you go but you can see it is giving multiple times three three three three three so it should be just one click because that will be annoying because if we loop through the questions and if it clicks one more than one time it will answer maybe three four questions at the same time so the easiest method to solve this is using the lazy method of importing time and we just write here time time dot sleep for 0.3 let's see i think three should be enough let's try that so if i click on three there you go if i click on five there you go so now it's just saving it once so it means we can use this method to go to the next question and it should be fine okay so how exactly do we go to the next question so we will say that if the mcq dot user answer is not none then we are going to do this okay so we will do this and then we will say our question number plus plus equals 1 so it will add to the question number so when you add to the question number basically it will change it here uh where is that question number we are not using question number now okay yeah it will add to the question number here and what we can say is that over here we can say if question number is less than question total then keep doing this and use the question number instead of 0 use the question number so it will keep looping through the questions and we can put all of this in that there you go so let's run that so i have my hand if i click on five there you go the question changes so that is very good and if i click on float and that's it so the questions are done and uh we should give a little bit of feedback because um it will be good to see what did you score and when the quiz has ended so we are going to do all of that but before we do let me check if we are missing something apart from these drawings um maybe we can add like two more questions or okay let's let's keep it like this because it will be easier to go through the questions and then later on we can add more questions now uh what we need to do is we need to add we don't need to but we can add a progress bar so we can write here draw progress bar so we need to just draw rectangles and what we will do is so we will first of all create a rectangle so we will write here rectangle and we will give in our image and then we need to give in a value of the bar so let's say the bar starts at 150 and the height is 600 and then the bar value in the beginning is 150 and then it is still 650 but let's let's put it still let's say 1000 150 so it will show a complete batch we can see that and later on we can change so here we are going to write 0 2 5 5 0 it will be green and then we are going to write here cv2 dot filled so this will be the progress bar inside and then we will add an outline so the outline will be pretty much the same thing let's make it eleven hundred and then we need to add a thickness let's say of five and we will change the color to two five five zero and two five five so that will be our main difference so let's run that and see if we have our progress bar there you go so you can see at the bottom we have a progress bar but right now it is full so that is not accurate so what we have to do is we have to find out the bar value so our bar value let's say bar value [Music] let's say val or let's say value it's fine bar value is equals to 150 this is the starting point this will be the starting point plus whatever the value is so plus we will do the total width of the bar the total width of the bar is 1100 minus 150 which is 950 so that is the total value and then we will divide it up into x number of uh parts based on the questions so if we have five questions we will divide it up into five parts if we have three questions we will divide it up into three parts so we will divide this by question total and then we will simply multiply that with our question number so if question number is zero nothing will happen zero zero progress if question number is one then it will add one part here that's basically the idea and now we can simply replace this with our bar value and that should be enough so let's run that and see if it works there you go right now it is zero and then if i bring in my hand and i click on three you can see it updates and then i click on float and there you go it updates and the bar will stay there it will tell us that the progress is completed everything is working fine but um yeah so what we can do is we can also add the percentage because the percentage will look good so we can write here and we can put it in our what you call a rectangle with the background text with the background so here we can write here and we can remove this and we will put it on our image what do we need to write here we will write an f string and what we will do is we will write question number divided by question total oh i forgot to add the brackets that's not good so we need to write it like this and uh what else so we will do that and we can multiply it by hundred we will multiply it by hundred to get the percentage and we will round it off by let's say yeah let's just round it i don't want any decimal places okay so that should be fine and the placement let's put a percentage in front of it and the placement let's put it at one one three zero and six three five and the offset as 16 and border none so let's run that there you go so now you can see there's a percentage uh right there and you can see the person didn't update why then the percentage updates what is going on question number and question total multiplied by a hundred seems about right are updating the question number so why didn't it maybe it didn't save the value let me try again no ah now it's saying hundred uh let me add one more question maybe it is the number of questions let's run that no wait now it's showing 100 something is very very wrong we are not getting it correct oh i didn't save it i believe i need to press save what did i say okay let's go at the bottom and here we are getting the length so let's write it down here total total mcq objects created there you go so now it will be easy to see where is the mistake hopefully total mcq object created three okay that's good so let's now once i click on it nothing changes the progress here changes but the percentage is not changing so okay let's try to remove this and let's see what exactly is happening if we just do we need to put the brackets okay if we just do this let's see what does it give us terms of percentage it's giving us in decimal places okay so did i divide it by 100 or did i multiply it by 100 i think i divided by 100 that was my mistake no i multiplied it by hundred then what's the problem oh i think the brackets are wrong so this round oh it should be here like this i believe now it should work yeah wrong brackets come on so yeah that's the idea now it's showing 100 60 and 33. so this is good and what else do we need to do we need to store the values and later on at the end we need to show the progress so not the progress the the total score so what we will do is we will check the score once all of the questions are done so if this is true it means the questions are still there and it is checking and it is asking the questions so if that is not the case we will write else to this if then we are going to write score is equals to zero so this is the zero value and then we are going to loop through all the mcqs and check their answers so we are going to write for mcq in mcq list we are going to check if the mcq answer mcq dot answer this answer is basically the one that we have written here this one the one we did integer 4 because we are going to compare this is why we did it so if you see here this is that value so we are checking that if 3 is equals to is equals to mcq dot user answer so if the user gave this as the answer then we are going to write score plus equals one so we are going to add to the score otherwise we will ignore it so what we can do is we can write here and we can print here the score so again it will not show as you are doing it it will show at the very end so how many corners does a triangle have it has three uh what is the type i will do this wrong it is let's say it is a character but the next one i will do it correct let's say it's a string so my total score should be 2. so here i i'm seeing 2 because i gave two correct answers out of 3. so now i need to convert it into percentage so i will write here score is equals to score divided by total number of questions and then we can multiply it by hundred so that will give us the value and then again we can round it round it to two decimal places okay and uh instead of printing it out we are going to display it on our uh what he called a webcam image so what we will do is we will we will copy this part and we will paste it here and let's remove this part not required now we are going to change what exactly do we want to print we want to print that the quiz is completed that is the first thing we want to print and we will print it at 250 and 300 and the offset let's make it 50 and the border let's make it five so that will give us that it is completed and then we are going to write uh yeah we need the f string so we will keep that and we will remove everything else so here we are going to write the score and we can also write your score and then this and then we will write the percentage because the score is in percentage and then the location we will write as 700 and 300 350 again we will keep this the same okay i believe that should be good so let's run that there you go so how many corners does a triangle have let's say three again character and then string so your score was 66.67 because i gave one answer wrong now let's try it again this time around i will give all answers correct so we have three and then we have string and then we have string to go back a little bit there you go so your score is 100 yes so that is basically the idea and again you can add a lot of different things here you can make it more appealing by changing the graphics changing the performance maybe you can add a back button you can add a reset button and lots of things you can do with this now is there anything else that is remaining so let me check uh do we need to do anything else i think that is pretty much it we have covered the basics and the rest if you want to add you can keep adding to this code so this is it for today's video i hope you have learned something new if you like the video give it a thumbs up and if you loved it share it with your friends and let me know in the comments what exactly would you like me to build next and that is it for today and i will see you in the next one
Info
Channel: Murtaza's Workshop - Robotics and AI
Views: 18,189
Rating: undefined out of 5
Keywords:
Id: 6400ShqS9BY
Channel Id: undefined
Length: 54min 10sec (3250 seconds)
Published: Thu Sep 09 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.