[
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n\n# C extensions\n*.so\n*.mp4\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\npip-wheel-metadata/\nshare/python-wheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.nox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n*.py,cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\ndb.sqlite3-journal\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# IPython\nprofile_default/\nipython_config.py\n\n# pyenv\n.python-version\n\n# pipenv\n#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.\n#   However, in case of collaboration, if having platform-specific dependencies or dependencies\n#   having no cross-platform support, pipenv may install dependencies that don't work, or not\n#   install all needed dependencies.\n#Pipfile.lock\n\n# PEP 582; used by e.g. github.com/David-OConnor/pyflow\n__pypackages__/\n\n# Celery stuff\ncelerybeat-schedule\ncelerybeat.pid\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n.dmypy.json\ndmypy.json\n\n# Pyre type checker\n.pyre/\n"
  },
  {
    "path": "Eye_Tracking_part1/main.py",
    "content": "import cv2 as cv\nimport mediapipe as mp\nimport time\n\nfrom numpy import greater\nimport utils\n\n# variables \nframe_counter =0\n\n# constants \nFONTS =cv.FONT_HERSHEY_COMPLEX\n\n# face bounder indices \nFACE_OVAL=[ 10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288, 397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136, 172, 58, 132, 93, 234, 127, 162, 21, 54, 103,67, 109]\n\n# lips indices for Landmarks\nLIPS=[ 61, 146, 91, 181, 84, 17, 314, 405, 321, 375,291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95,185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78 ]\nLOWER_LIPS =[61, 146, 91, 181, 84, 17, 314, 405, 321, 375, 291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95]\nUPPER_LIPS=[ 185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78] \n# Left eyes indices \nLEFT_EYE =[ 362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385,384, 398 ]\nLEFT_EYEBROW =[ 336, 296, 334, 293, 300, 276, 283, 282, 295, 285 ]\n\n# right eyes indices\nRIGHT_EYE=[ 33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161 , 246 ]  \nRIGHT_EYEBROW=[ 70, 63, 105, 66, 107, 55, 65, 52, 53, 46 ]\n\nmap_face_mesh = mp.solutions.face_mesh\n# camera object \ncamera = cv.VideoCapture(\"VideoFile.mp4\")\n# landmark detection function \ndef landmarksDetection(img, results, draw=False):\n    img_height, img_width= img.shape[:2]\n    # list[(x,y), (x,y)....]\n    mesh_coord = [(int(point.x * img_width), int(point.y * img_height)) for point in results.multi_face_landmarks[0].landmark]\n    if draw :\n        [cv.circle(img, p, 2, utils.GREEN, -1) for p in mesh_coord]\n\n    # returning the list of tuples for each landmarks \n    return mesh_coord\n\nwith map_face_mesh.FaceMesh(min_detection_confidence =0.5, min_tracking_confidence=0.5) as face_mesh:\n\n    # starting time here \n    start_time = time.time()\n    # starting Video loop here.\n    while True:\n        frame_counter +=1 # frame counter\n        ret, frame = camera.read() # getting frame from camera \n        if not ret: \n            break # no more frames break\n        #  resizing frame\n        # frame = cv.resize(frame, None, fx=2.0, fy=2.0, interpolation=cv.INTER_CUBIC)\n        # writing orginal image image thumbnail \n        # cv.imwrite(f'img/img_{frame_counter}.png', frame)\n        # print(frame_counter)\n\n\n        rgb_frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)\n        results  = face_mesh.process(rgb_frame)\n        if results.multi_face_landmarks:\n            mesh_coords = landmarksDetection(frame, results, False)\n            frame =utils.fillPolyTrans(frame, [mesh_coords[p] for p in FACE_OVAL], utils.WHITE, opacity=0.4)\n            frame =utils.fillPolyTrans(frame, [mesh_coords[p] for p in LEFT_EYE], utils.GREEN, opacity=0.4)\n            frame =utils.fillPolyTrans(frame, [mesh_coords[p] for p in RIGHT_EYE], utils.GREEN, opacity=0.4)\n            frame =utils.fillPolyTrans(frame, [mesh_coords[p] for p in LEFT_EYEBROW], utils.ORANGE, opacity=0.4)\n            frame =utils.fillPolyTrans(frame, [mesh_coords[p] for p in RIGHT_EYEBROW], utils.ORANGE, opacity=0.4)\n            frame =utils.fillPolyTrans(frame, [mesh_coords[p] for p in LIPS], utils.BLACK, opacity=0.3 )\n            # Changes for Thumbnail of youtube Video \n            [cv.circle(frame,mesh_coords[p], 1, utils.GREEN , -1, cv.LINE_AA) for p in LIPS]\n            [cv.circle(frame,mesh_coords[p], 1, utils.BLACK ,- 1, cv.LINE_AA) for p in RIGHT_EYE]\n            [cv.circle(frame,mesh_coords[p], 1, utils.BLACK , -1, cv.LINE_AA) for p in LEFT_EYE]\n\n            [cv.circle(frame,mesh_coords[p], 1, utils.BLACK , -1, cv.LINE_AA) for p in RIGHT_EYEBROW]\n            [cv.circle(frame,mesh_coords[p], 1, utils.BLACK , -1, cv.LINE_AA) for p in LEFT_EYEBROW]\n            [cv.circle(frame,mesh_coords[p], 1, utils.RED , -1, cv.LINE_AA) for p in FACE_OVAL]\n\n\n\n\n\n        # calculating  frame per seconds FPS\n        end_time = time.time()-start_time\n        fps = frame_counter/end_time\n\n        frame =utils.textWithBackground(frame,f'FPS: {round(fps,1)}',FONTS, 1.0, (20, 50), bgOpacity=0.9, textThickness=2)\n        # writing image for thumbnail drawing shape\n        # cv.imwrite(f'img/frame_{frame_counter}.png', frame)\n        cv.imshow('frame', frame)\n        key = cv.waitKey(1)\n        if key==ord('q') or key ==ord('Q'):\n            break\n    cv.destroyAllWindows()\n    camera.release()\n"
  },
  {
    "path": "Eye_Tracking_part1/utils.py",
    "content": "'''\n\nAuthor: Asadullah Dal \nYoutube Channel: https://www.youtube.com/c/aiphile\n\n'''\n\nimport cv2 as cv \nimport numpy as np\n\n# colors \n# values =(blue, green, red) opencv accepts BGR values not RGB\nBLACK = (0,0,0)\nWHITE = (255,255,255)\nBLUE = (255,0,0)\nRED = (0,0,255)\nCYAN = (255,255,0)\nYELLOW =(0,255,255)\nMAGENTA = (255,0,255)\nGRAY = (128,128,128)\nGREEN = (0,255,0)\nPURPLE = (128,0,128)\nORANGE = (0,165,255)\nPINK = (147,20,255)\npoints_list =[(200, 300), (150, 150), (400, 200)]\ndef drawColor(img, colors):\n    x, y = 0,10\n    w, h = 20, 30\n    \n    for color in colors:\n        x += w+5 \n        # y += 10 \n        cv.rectangle(img, (x-6, y-5 ), (x+w+5, y+h+5), (10, 50, 10), -1)\n        cv.rectangle(img, (x, y ), (x+w, y+h), color, -1)\n    \n\ndef textWithBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3, bgOpacity=0.5):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    overlay = img.copy() # coping the image\n    cv.rectangle(overlay, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    new_img = cv.addWeighted(overlay, bgOpacity, img, 1 - bgOpacity, 0) # overlaying the rectangle on the image.\n    cv.putText(new_img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n    img = new_img\n\n    return img\n\n\ndef textBlurBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0),kneral=(33,33) , pad_x=3, pad_y=3):\n    \"\"\"    \n    Draw text with background blured,  control the blur value, with kernal(odd, odd)\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param kneral: tuple(3,3) int as odd number:  higher the value, more blurry background would be\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels)  padding of in y direction\n    @return: img mat, with text drawn, with background blured\n    \n    call the function: \n     img =textBlurBackground(img, 'Blured Background Text', cv2.FONT_HERSHEY_COMPLEX, 0.9, (20, 60),2, (0,255, 0), (49,49), 13, 13 )\n    \"\"\"\n    \n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    blur_roi = img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x] # croping Text Background\n    img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x]=cv.blur(blur_roi, kneral)  # merging the blured background to img\n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness )          \n    # cv.imshow('blur roi', blur_roi)\n    # cv.imshow('blured', img)\n\n    return img\n\ndef fillPolyTrans(img, points, color, opacity):\n    \"\"\"\n    @param img: (mat) input image, where shape is drawn.\n    @param points: list [tuples(int, int) these are the points custom shape,FillPoly\n    @param color: (tuples (int, int, int)\n    @param opacity:  it is transparency of image.\n    @return: img(mat) image with rectangle draw.\n\n    \"\"\"\n    list_to_np_array = np.array(points, dtype=np.int32)\n    overlay = img.copy()  # coping the image\n    cv.fillPoly(overlay,[list_to_np_array], color )\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0)\n    # print(points_list)\n    img = new_img\n    cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n    return img\n\ndef rectTrans(img, pt1, pt2, color, thickness, opacity):\n    \"\"\"\n\n    @param img: (mat) input image, where shape is drawn.\n    @param pt1: tuple(int,int) it specifies the starting point(x,y) os rectangle\n    @param pt2: tuple(int,int)  it nothing but width and height of rectangle\n    @param color: (tuples (int, int, int), it tuples of BGR values\n    @param thickness: it thickness of board line rectangle, if (-1) passed then rectangle will be fulled with color.\n    @param opacity:  it is transparency of image.\n    @return:\n    \"\"\"\n    overlay = img.copy()\n    cv.rectangle(overlay, pt1, pt2, color, thickness)\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0) # overlaying the rectangle on the image.\n    img = new_img\n\n    return img\n\ndef main():\n    cap = cv.VideoCapture('Girl.mp4')\n    counter =0\n    while True:\n        success, img = cap.read()\n        # img = np.zeros((1000,1000, 3), dtype=np.uint8)\n        img=rectTrans(img, pt1=(30, 320), pt2=(160, 260), color=(0,255,255),thickness=-1, opacity=0.6)\n        img =fillPolyTrans(img=img, points=points_list, color=(0,255,0), opacity=.5)\n        drawColor(img, [BLACK,WHITE ,BLUE,RED,CYAN,YELLOW,MAGENTA,GRAY ,GREEN,PURPLE,ORANGE,PINK])\n        textBlurBackground(img, 'Blured Background Text', cv.FONT_HERSHEY_COMPLEX, 0.8, (60, 140),2, YELLOW, (71,71), 13, 13)\n        img=textWithBackground(img, 'Colored Background Texts', cv.FONT_HERSHEY_SIMPLEX, 0.8, (60,80), textThickness=2, bgColor=GREEN, textColor=BLACK, bgOpacity=0.7, pad_x=6, pad_y=6)\n        imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n        # cv.imwrite('color_image.png', img)\n        counter +=1\n        cv.imshow('img', img)\n        cv.imwrite(f'image/image_{counter}.png', img)\n        if cv.waitKey(1) ==ord('q'):\n            break\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Eye_Tracking_part2/main.py",
    "content": "\nimport cv2 as cv\nimport mediapipe as mp\nimport time\nimport utils, math\nimport numpy as np\n# variables \nframe_counter =0\nCEF_COUNTER =0\nTOTAL_BLINKS =0\n# constants\nCLOSED_EYES_FRAME =3\nFONTS =cv.FONT_HERSHEY_COMPLEX\n\n# face bounder indices \nFACE_OVAL=[ 10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288, 397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136, 172, 58, 132, 93, 234, 127, 162, 21, 54, 103,67, 109]\n\n# lips indices for Landmarks\nLIPS=[ 61, 146, 91, 181, 84, 17, 314, 405, 321, 375,291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95,185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78 ]\nLOWER_LIPS =[61, 146, 91, 181, 84, 17, 314, 405, 321, 375, 291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95]\nUPPER_LIPS=[ 185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78] \n# Left eyes indices \nLEFT_EYE =[ 362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385,384, 398 ]\nLEFT_EYEBROW =[ 336, 296, 334, 293, 300, 276, 283, 282, 295, 285 ]\n\n# right eyes indices\nRIGHT_EYE=[ 33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161 , 246 ]  \nRIGHT_EYEBROW=[ 70, 63, 105, 66, 107, 55, 65, 52, 53, 46 ]\n\nmap_face_mesh = mp.solutions.face_mesh\n# camera object \ncamera = cv.VideoCapture(1)\n# landmark detection function \ndef landmarksDetection(img, results, draw=False):\n    img_height, img_width= img.shape[:2]\n    # list[(x,y), (x,y)....]\n    mesh_coord = [(int(point.x * img_width), int(point.y * img_height)) for point in results.multi_face_landmarks[0].landmark]\n    if draw :\n        [cv.circle(img, p, 2, (0,255,0), -1) for p in mesh_coord]\n\n    # returning the list of tuples for each landmarks \n    return mesh_coord\n\n# Euclaidean distance \ndef euclaideanDistance(point, point1):\n    x, y = point\n    x1, y1 = point1\n    distance = math.sqrt((x1 - x)**2 + (y1 - y)**2)\n    return distance\n\n# Blinking Ratio\ndef blinkRatio(img, landmarks, right_indices, left_indices):\n    # Right eyes \n    # horizontal line \n    rh_right = landmarks[right_indices[0]]\n    rh_left = landmarks[right_indices[8]]\n    # vertical line \n    rv_top = landmarks[right_indices[12]]\n    rv_bottom = landmarks[right_indices[4]]\n    # draw lines on right eyes \n    # cv.line(img, rh_right, rh_left, utils.GREEN, 2)\n    # cv.line(img, rv_top, rv_bottom, utils.WHITE, 2)\n\n    # LEFT_EYE \n    # horizontal line \n    lh_right = landmarks[left_indices[0]]\n    lh_left = landmarks[left_indices[8]]\n\n    # vertical line \n    lv_top = landmarks[left_indices[12]]\n    lv_bottom = landmarks[left_indices[4]]\n\n    rhDistance = euclaideanDistance(rh_right, rh_left)\n    rvDistance = euclaideanDistance(rv_top, rv_bottom)\n\n    lvDistance = euclaideanDistance(lv_top, lv_bottom)\n    lhDistance = euclaideanDistance(lh_right, lh_left)\n\n    reRatio = rhDistance/rvDistance\n    leRatio = lhDistance/lvDistance\n\n    ratio = (reRatio+leRatio)/2\n    return ratio \n\n\n\nwith map_face_mesh.FaceMesh(min_detection_confidence =0.5, min_tracking_confidence=0.5) as face_mesh:\n\n    # starting time here \n    start_time = time.time()\n    # starting Video loop here.\n    while True:\n        frame_counter +=1 # frame counter\n        ret, frame = camera.read() # getting frame from camera \n        if not ret: \n            break # no more frames break\n        #  resizing frame\n        \n        frame = cv.resize(frame, None, fx=1.5, fy=1.5, interpolation=cv.INTER_CUBIC)\n        frame_height, frame_width= frame.shape[:2]\n        rgb_frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)\n        results  = face_mesh.process(rgb_frame)\n        if results.multi_face_landmarks:\n            mesh_coords = landmarksDetection(frame, results, False)\n            ratio = blinkRatio(frame, mesh_coords, RIGHT_EYE, LEFT_EYE)\n            # cv.putText(frame, f'ratio {ratio}', (100, 100), FONTS, 1.0, utils.GREEN, 2)\n            utils.colorBackgroundText(frame,  f'Ratio : {round(ratio,2)}', FONTS, 0.7, (30,100),2, utils.PINK, utils.YELLOW)\n\n            if ratio >5.5:\n                CEF_COUNTER +=1\n                # cv.putText(frame, 'Blink', (200, 50), FONTS, 1.3, utils.PINK, 2)\n                utils.colorBackgroundText(frame,  f'Blink', FONTS, 1.7, (int(frame_height/2), 100), 2, utils.YELLOW, pad_x=6, pad_y=6, )\n\n            else:\n                if CEF_COUNTER>CLOSED_EYES_FRAME:\n                    TOTAL_BLINKS +=1\n                    CEF_COUNTER =0\n            # cv.putText(frame, f'Total Blinks: {TOTAL_BLINKS}', (100, 150), FONTS, 0.6, utils.GREEN, 2)\n            utils.colorBackgroundText(frame,  f'Total Blinks: {TOTAL_BLINKS}', FONTS, 0.7, (30,150),2)\n            \n            cv.polylines(frame,  [np.array([mesh_coords[p] for p in LEFT_EYE ], dtype=np.int32)], True, utils.GREEN, 1, cv.LINE_AA)\n            cv.polylines(frame,  [np.array([mesh_coords[p] for p in RIGHT_EYE ], dtype=np.int32)], True, utils.GREEN, 1, cv.LINE_AA)\n\n\n\n        # calculating  frame per seconds FPS\n        end_time = time.time()-start_time\n        fps = frame_counter/end_time\n\n        frame =utils.textWithBackground(frame,f'FPS: {round(fps,1)}',FONTS, 1.0, (30, 50), bgOpacity=0.9, textThickness=2)\n        # writing image for thumbnail drawing shape\n        # cv.imwrite(f'img/frame_{frame_counter}.png', frame)\n        cv.imshow('frame', frame)\n        key = cv.waitKey(2)\n        if key==ord('q') or key ==ord('Q'):\n            break\n    cv.destroyAllWindows()\n    camera.release()\n"
  },
  {
    "path": "Eye_Tracking_part2/utils.py",
    "content": "'''\n\nAuthor: Asadullah Dal \nYoutube Channel: https://www.youtube.com/c/aiphile\n\n'''\n\nimport cv2 as cv \nimport numpy as np\n\n# colors \n# values =(blue, green, red) opencv accepts BGR values not RGB\nBLACK = (0,0,0)\nWHITE = (255,255,255)\nBLUE = (255,0,0)\nRED = (0,0,255)\nCYAN = (255,255,0)\nYELLOW =(0,255,255)\nMAGENTA = (255,0,255)\nGRAY = (128,128,128)\nGREEN = (0,255,0)\nPURPLE = (128,0,128)\nORANGE = (0,165,255)\nPINK = (147,20,255)\npoints_list =[(200, 300), (150, 150), (400, 200)]\ndef drawColor(img, colors):\n    x, y = 0,10\n    w, h = 20, 30\n    \n    for color in colors:\n        x += w+5 \n        # y += 10 \n        cv.rectangle(img, (x-6, y-5 ), (x+w+5, y+h+5), (10, 50, 10), -1)\n        cv.rectangle(img, (x, y ), (x+w, y+h), color, -1)\n    \ndef colorBackgroundText(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    cv.rectangle(img, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n\n    return img\n\ndef textWithBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3, bgOpacity=0.5):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    overlay = img.copy() # coping the image\n    cv.rectangle(overlay, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    new_img = cv.addWeighted(overlay, bgOpacity, img, 1 - bgOpacity, 0) # overlaying the rectangle on the image.\n    cv.putText(new_img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n    img = new_img\n\n    return img\n\n\ndef textBlurBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0),kneral=(33,33) , pad_x=3, pad_y=3):\n    \"\"\"    \n    Draw text with background blured,  control the blur value, with kernal(odd, odd)\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param kneral: tuple(3,3) int as odd number:  higher the value, more blurry background would be\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels)  padding of in y direction\n    @return: img mat, with text drawn, with background blured\n    \n    call the function: \n     img =textBlurBackground(img, 'Blured Background Text', cv2.FONT_HERSHEY_COMPLEX, 0.9, (20, 60),2, (0,255, 0), (49,49), 13, 13 )\n    \"\"\"\n    \n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    blur_roi = img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x] # croping Text Background\n    img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x]=cv.blur(blur_roi, kneral)  # merging the blured background to img\n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness )          \n    # cv.imshow('blur roi', blur_roi)\n    # cv.imshow('blured', img)\n\n    return img\n\ndef fillPolyTrans(img, points, color, opacity):\n    \"\"\"\n    @param img: (mat) input image, where shape is drawn.\n    @param points: list [tuples(int, int) these are the points custom shape,FillPoly\n    @param color: (tuples (int, int, int)\n    @param opacity:  it is transparency of image.\n    @return: img(mat) image with rectangle draw.\n\n    \"\"\"\n    list_to_np_array = np.array(points, dtype=np.int32)\n    overlay = img.copy()  # coping the image\n    cv.fillPoly(overlay,[list_to_np_array], color )\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0)\n    # print(points_list)\n    img = new_img\n    cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n    return img\n\n# def pollyLines(img, points, color):\n#     list_to_np_array = np.array(points, dtype=np.int32)\n#     cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n#     return img\n\ndef rectTrans(img, pt1, pt2, color, thickness, opacity):\n    \"\"\"\n\n    @param img: (mat) input image, where shape is drawn.\n    @param pt1: tuple(int,int) it specifies the starting point(x,y) os rectangle\n    @param pt2: tuple(int,int)  it nothing but width and height of rectangle\n    @param color: (tuples (int, int, int), it tuples of BGR values\n    @param thickness: it thickness of board line rectangle, if (-1) passed then rectangle will be fulled with color.\n    @param opacity:  it is transparency of image.\n    @return:\n    \"\"\"\n    overlay = img.copy()\n    cv.rectangle(overlay, pt1, pt2, color, thickness)\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0) # overlaying the rectangle on the image.\n    img = new_img\n\n    return img\n\ndef main():\n    cap = cv.VideoCapture('Girl.mp4')\n    counter =0\n    while True:\n        success, img = cap.read()\n        # img = np.zeros((1000,1000, 3), dtype=np.uint8)\n        img=rectTrans(img, pt1=(30, 320), pt2=(160, 260), color=(0,255,255),thickness=-1, opacity=0.6)\n        img =fillPolyTrans(img=img, points=points_list, color=(0,255,0), opacity=.5)\n        drawColor(img, [BLACK,WHITE ,BLUE,RED,CYAN,YELLOW,MAGENTA,GRAY ,GREEN,PURPLE,ORANGE,PINK])\n        textBlurBackground(img, 'Blured Background Text', cv.FONT_HERSHEY_COMPLEX, 0.8, (60, 140),2, YELLOW, (71,71), 13, 13)\n        img=textWithBackground(img, 'Colored Background Texts', cv.FONT_HERSHEY_SIMPLEX, 0.8, (60,80), textThickness=2, bgColor=GREEN, textColor=BLACK, bgOpacity=0.7, pad_x=6, pad_y=6)\n        imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n        # cv.imwrite('color_image.png', img)\n        counter +=1\n        cv.imshow('img', img)\n        cv.imwrite(f'image/image_{counter}.png', img)\n        if cv.waitKey(1) ==ord('q'):\n            break\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Eye_Tracking_part3/main.py",
    "content": "\nimport cv2 as cv\nimport mediapipe as mp\nimport time\nimport utils, math\nimport numpy as np\n# variables \nframe_counter =0\nCEF_COUNTER =0\nTOTAL_BLINKS =0\n# constants\nCLOSED_EYES_FRAME =3\nFONTS =cv.FONT_HERSHEY_COMPLEX\n\n# face bounder indices \nFACE_OVAL=[ 10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288, 397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136, 172, 58, 132, 93, 234, 127, 162, 21, 54, 103,67, 109]\n\n# lips indices for Landmarks\nLIPS=[ 61, 146, 91, 181, 84, 17, 314, 405, 321, 375,291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95,185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78 ]\nLOWER_LIPS =[61, 146, 91, 181, 84, 17, 314, 405, 321, 375, 291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95]\nUPPER_LIPS=[ 185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78] \n# Left eyes indices \nLEFT_EYE =[ 362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385,384, 398 ]\nLEFT_EYEBROW =[ 336, 296, 334, 293, 300, 276, 283, 282, 295, 285 ]\n\n# right eyes indices\nRIGHT_EYE=[ 33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161 , 246 ]  \nRIGHT_EYEBROW=[ 70, 63, 105, 66, 107, 55, 65, 52, 53, 46 ]\n\nmap_face_mesh = mp.solutions.face_mesh\n# camera object \ncamera = cv.VideoCapture(0)\n# landmark detection function \ndef landmarksDetection(img, results, draw=False):\n    img_height, img_width= img.shape[:2]\n    # list[(x,y), (x,y)....]\n    mesh_coord = [(int(point.x * img_width), int(point.y * img_height)) for point in results.multi_face_landmarks[0].landmark]\n    if draw :\n        [cv.circle(img, p, 2, (0,255,0), -1) for p in mesh_coord]\n\n    # returning the list of tuples for each landmarks \n    return mesh_coord\n\n# Euclaidean distance \ndef euclaideanDistance(point, point1):\n    x, y = point\n    x1, y1 = point1\n    distance = math.sqrt((x1 - x)**2 + (y1 - y)**2)\n    return distance\n\n# Blinking Ratio\ndef blinkRatio(img, landmarks, right_indices, left_indices):\n    # Right eyes \n    # horizontal line \n    rh_right = landmarks[right_indices[0]]\n    rh_left = landmarks[right_indices[8]]\n    # vertical line \n    rv_top = landmarks[right_indices[12]]\n    rv_bottom = landmarks[right_indices[4]]\n    # draw lines on right eyes \n    # cv.line(img, rh_right, rh_left, utils.GREEN, 2)\n    # cv.line(img, rv_top, rv_bottom, utils.WHITE, 2)\n\n    # LEFT_EYE \n    # horizontal line \n    lh_right = landmarks[left_indices[0]]\n    lh_left = landmarks[left_indices[8]]\n\n    # vertical line \n    lv_top = landmarks[left_indices[12]]\n    lv_bottom = landmarks[left_indices[4]]\n\n    rhDistance = euclaideanDistance(rh_right, rh_left)\n    rvDistance = euclaideanDistance(rv_top, rv_bottom)\n\n    lvDistance = euclaideanDistance(lv_top, lv_bottom)\n    lhDistance = euclaideanDistance(lh_right, lh_left)\n\n    reRatio = rhDistance/rvDistance\n    leRatio = lhDistance/lvDistance\n\n    ratio = (reRatio+leRatio)/2\n    return ratio \n\n# Eyes Extrctor function,\ndef eyesExtractor(img, right_eye_coords, left_eye_coords):\n    # converting color image to  scale image \n    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n    \n    # getting the dimension of image \n    dim = gray.shape\n\n    # creating mask from gray scale dim\n    mask = np.zeros(dim, dtype=np.uint8)\n\n    # drawing Eyes Shape on mask with white color \n    cv.fillPoly(mask, [np.array(right_eye_coords, dtype=np.int32)], 255)\n    cv.fillPoly(mask, [np.array(left_eye_coords, dtype=np.int32)], 255)\n\n    # showing the mask \n    # cv.imshow('mask', mask)\n    \n    # draw eyes image on mask, where white shape is \n    eyes = cv.bitwise_and(gray, gray, mask=mask)\n    # change black color to gray other than eys \n    # cv.imshow('eyes draw', eyes)\n    eyes[mask==0]=155\n    \n    # getting minium and maximum x and y  for right and left eyes \n    # For Right Eye \n    r_max_x = (max(right_eye_coords, key=lambda item: item[0]))[0]\n    r_min_x = (min(right_eye_coords, key=lambda item: item[0]))[0]\n    r_max_y = (max(right_eye_coords, key=lambda item : item[1]))[1]\n    r_min_y = (min(right_eye_coords, key=lambda item: item[1]))[1]\n\n    # For LEFT Eye\n    l_max_x = (max(left_eye_coords, key=lambda item: item[0]))[0]\n    l_min_x = (min(left_eye_coords, key=lambda item: item[0]))[0]\n    l_max_y = (max(left_eye_coords, key=lambda item : item[1]))[1]\n    l_min_y = (min(left_eye_coords, key=lambda item: item[1]))[1]\n\n    # croping the eyes from mask \n    cropped_right = eyes[r_min_y: r_max_y, r_min_x: r_max_x]\n    cropped_left = eyes[l_min_y: l_max_y, l_min_x: l_max_x]\n\n    # returning the cropped eyes \n    return cropped_right, cropped_left\n\n# Eyes Postion Estimator \ndef positionEstimator(cropped_eye):\n    # getting height and width of eye \n    h, w =cropped_eye.shape\n    \n    # remove the noise from images\n    gaussain_blur = cv.GaussianBlur(cropped_eye, (9,9),0)\n    median_blur = cv.medianBlur(gaussain_blur, 3)\n\n    # applying thrsholding to convert binary_image\n    ret, threshed_eye = cv.threshold(median_blur, 130, 255, cv.THRESH_BINARY)\n\n    # create fixd part for eye with \n    piece = int(w/3) \n\n    # slicing the eyes into three parts \n    right_piece = threshed_eye[0:h, 0:piece]\n    center_piece = threshed_eye[0:h, piece: piece+piece]\n    left_piece = threshed_eye[0:h, piece +piece:w]\n    \n    # calling pixel counter function\n    eye_position, color = pixelCounter(right_piece, center_piece, left_piece)\n\n    return eye_position, color \n\n# creating pixel counter function \ndef pixelCounter(first_piece, second_piece, third_piece):\n    # counting black pixel in each part \n    right_part = np.sum(first_piece==0)\n    center_part = np.sum(second_piece==0)\n    left_part = np.sum(third_piece==0)\n    # creating list of these values\n    eye_parts = [right_part, center_part, left_part]\n\n    # getting the index of max values in the list \n    max_index = eye_parts.index(max(eye_parts))\n    pos_eye ='' \n    if max_index==0:\n        pos_eye=\"RIGHT\"\n        color=[utils.BLACK, utils.GREEN]\n    elif max_index==1:\n        pos_eye = 'CENTER'\n        color = [utils.YELLOW, utils.PINK]\n    elif max_index ==2:\n        pos_eye = 'LEFT'\n        color = [utils.GRAY, utils.YELLOW]\n    else:\n        pos_eye=\"Closed\"\n        color = [utils.GRAY, utils.YELLOW]\n    return pos_eye, color\n\n\nwith map_face_mesh.FaceMesh(min_detection_confidence =0.5, min_tracking_confidence=0.5) as face_mesh:\n\n    # starting time here \n    start_time = time.time()\n    # starting Video loop here.\n    while True:\n        frame_counter +=1 # frame counter\n        ret, frame = camera.read() # getting frame from camera \n        if not ret: \n            break # no more frames break\n        #  resizing frame\n        \n        frame = cv.resize(frame, None, fx=1.5, fy=1.5, interpolation=cv.INTER_CUBIC)\n        frame_height, frame_width= frame.shape[:2]\n        rgb_frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)\n        results  = face_mesh.process(rgb_frame)\n        if results.multi_face_landmarks:\n            mesh_coords = landmarksDetection(frame, results, False)\n            ratio = blinkRatio(frame, mesh_coords, RIGHT_EYE, LEFT_EYE)\n            # cv.putText(frame, f'ratio {ratio}', (100, 100), FONTS, 1.0, utils.GREEN, 2)\n            utils.colorBackgroundText(frame,  f'Ratio : {round(ratio,2)}', FONTS, 0.7, (30,100),2, utils.PINK, utils.YELLOW)\n\n            if ratio >5.5:\n                CEF_COUNTER +=1\n                # cv.putText(frame, 'Blink', (200, 50), FONTS, 1.3, utils.PINK, 2)\n                utils.colorBackgroundText(frame,  f'Blink', FONTS, 1.7, (int(frame_height/2), 100), 2, utils.YELLOW, pad_x=6, pad_y=6, )\n\n            else:\n                if CEF_COUNTER>CLOSED_EYES_FRAME:\n                    TOTAL_BLINKS +=1\n                    CEF_COUNTER =0\n            # cv.putText(frame, f'Total Blinks: {TOTAL_BLINKS}', (100, 150), FONTS, 0.6, utils.GREEN, 2)\n            utils.colorBackgroundText(frame,  f'Total Blinks: {TOTAL_BLINKS}', FONTS, 0.7, (30,150),2)\n            \n            cv.polylines(frame,  [np.array([mesh_coords[p] for p in LEFT_EYE ], dtype=np.int32)], True, utils.GREEN, 1, cv.LINE_AA)\n            cv.polylines(frame,  [np.array([mesh_coords[p] for p in RIGHT_EYE ], dtype=np.int32)], True, utils.GREEN, 1, cv.LINE_AA)\n\n            # Blink Detector Counter Completed\n            right_coords = [mesh_coords[p] for p in RIGHT_EYE]\n            left_coords = [mesh_coords[p] for p in LEFT_EYE]\n            crop_right, crop_left = eyesExtractor(frame, right_coords, left_coords)\n            # cv.imshow('right', crop_right)\n            # cv.imshow('left', crop_left)\n            eye_position, color = positionEstimator(crop_right)\n            utils.colorBackgroundText(frame, f'R: {eye_position}', FONTS, 1.0, (40, 220), 2, color[0], color[1], 8, 8)\n            eye_position_left, color = positionEstimator(crop_left)\n            utils.colorBackgroundText(frame, f'L: {eye_position_left}', FONTS, 1.0, (40, 320), 2, color[0], color[1], 8, 8)\n            \n            \n\n\n        # calculating  frame per seconds FPS\n        end_time = time.time()-start_time\n        fps = frame_counter/end_time\n\n        frame =utils.textWithBackground(frame,f'FPS: {round(fps,1)}',FONTS, 1.0, (30, 50), bgOpacity=0.9, textThickness=2)\n        # writing image for thumbnail drawing shape\n        # cv.imwrite(f'img/frame_{frame_counter}.png', frame)\n        cv.imshow('frame', frame)\n        key = cv.waitKey(2)\n        if key==ord('q') or key ==ord('Q'):\n            break\n    cv.destroyAllWindows()\n    camera.release()\n"
  },
  {
    "path": "Eye_Tracking_part3/utils.py",
    "content": "'''\n\nAuthor: Asadullah Dal \nYoutube Channel: https://www.youtube.com/c/aiphile\n\n'''\n\nimport cv2 as cv \nimport numpy as np\n\n# colors \n# values =(blue, green, red) opencv accepts BGR values not RGB\nBLACK = (0,0,0)\nWHITE = (255,255,255)\nBLUE = (255,0,0)\nRED = (0,0,255)\nCYAN = (255,255,0)\nYELLOW =(0,255,255)\nMAGENTA = (255,0,255)\nGRAY = (128,128,128)\nGREEN = (0,255,0)\nPURPLE = (128,0,128)\nORANGE = (0,165,255)\nPINK = (147,20,255)\npoints_list =[(200, 300), (150, 150), (400, 200)]\ndef drawColor(img, colors):\n    x, y = 0,10\n    w, h = 20, 30\n    \n    for color in colors:\n        x += w+5 \n        # y += 10 \n        cv.rectangle(img, (x-6, y-5 ), (x+w+5, y+h+5), (10, 50, 10), -1)\n        cv.rectangle(img, (x, y ), (x+w, y+h), color, -1)\n    \ndef colorBackgroundText(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    cv.rectangle(img, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n\n    return img\n\ndef textWithBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3, bgOpacity=0.5):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    overlay = img.copy() # coping the image\n    cv.rectangle(overlay, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    new_img = cv.addWeighted(overlay, bgOpacity, img, 1 - bgOpacity, 0) # overlaying the rectangle on the image.\n    cv.putText(new_img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n    img = new_img\n\n    return img\n\n\ndef textBlurBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0),kneral=(33,33) , pad_x=3, pad_y=3):\n    \"\"\"    \n    Draw text with background blured,  control the blur value, with kernal(odd, odd)\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param kneral: tuple(3,3) int as odd number:  higher the value, more blurry background would be\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels)  padding of in y direction\n    @return: img mat, with text drawn, with background blured\n    \n    call the function: \n     img =textBlurBackground(img, 'Blured Background Text', cv2.FONT_HERSHEY_COMPLEX, 0.9, (20, 60),2, (0,255, 0), (49,49), 13, 13 )\n    \"\"\"\n    \n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    blur_roi = img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x] # croping Text Background\n    img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x]=cv.blur(blur_roi, kneral)  # merging the blured background to img\n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness )          \n    # cv.imshow('blur roi', blur_roi)\n    # cv.imshow('blured', img)\n\n    return img\n\ndef fillPolyTrans(img, points, color, opacity):\n    \"\"\"\n    @param img: (mat) input image, where shape is drawn.\n    @param points: list [tuples(int, int) these are the points custom shape,FillPoly\n    @param color: (tuples (int, int, int)\n    @param opacity:  it is transparency of image.\n    @return: img(mat) image with rectangle draw.\n\n    \"\"\"\n    list_to_np_array = np.array(points, dtype=np.int32)\n    overlay = img.copy()  # coping the image\n    cv.fillPoly(overlay,[list_to_np_array], color )\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0)\n    # print(points_list)\n    img = new_img\n    cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n    return img\n\n# def pollyLines(img, points, color):\n#     list_to_np_array = np.array(points, dtype=np.int32)\n#     cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n#     return img\n\ndef rectTrans(img, pt1, pt2, color, thickness, opacity):\n    \"\"\"\n\n    @param img: (mat) input image, where shape is drawn.\n    @param pt1: tuple(int,int) it specifies the starting point(x,y) os rectangle\n    @param pt2: tuple(int,int)  it nothing but width and height of rectangle\n    @param color: (tuples (int, int, int), it tuples of BGR values\n    @param thickness: it thickness of board line rectangle, if (-1) passed then rectangle will be fulled with color.\n    @param opacity:  it is transparency of image.\n    @return:\n    \"\"\"\n    overlay = img.copy()\n    cv.rectangle(overlay, pt1, pt2, color, thickness)\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0) # overlaying the rectangle on the image.\n    img = new_img\n\n    return img\n\ndef main():\n    cap = cv.VideoCapture('Girl.mp4')\n    counter =0\n    while True:\n        success, img = cap.read()\n        # img = np.zeros((1000,1000, 3), dtype=np.uint8)\n        img=rectTrans(img, pt1=(30, 320), pt2=(160, 260), color=(0,255,255),thickness=-1, opacity=0.6)\n        img =fillPolyTrans(img=img, points=points_list, color=(0,255,0), opacity=.5)\n        drawColor(img, [BLACK,WHITE ,BLUE,RED,CYAN,YELLOW,MAGENTA,GRAY ,GREEN,PURPLE,ORANGE,PINK])\n        textBlurBackground(img, 'Blured Background Text', cv.FONT_HERSHEY_COMPLEX, 0.8, (60, 140),2, YELLOW, (71,71), 13, 13)\n        img=textWithBackground(img, 'Colored Background Texts', cv.FONT_HERSHEY_SIMPLEX, 0.8, (60,80), textThickness=2, bgColor=GREEN, textColor=BLACK, bgOpacity=0.7, pad_x=6, pad_y=6)\n        imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n        # cv.imwrite('color_image.png', img)\n        counter +=1\n        cv.imshow('img', img)\n        cv.imwrite(f'image/image_{counter}.png', img)\n        if cv.waitKey(1) ==ord('q'):\n            break\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "Eye_Tracking_part4/Create Sound/create_sound.py",
    "content": "import pyttsx3\nengine = pyttsx3.init() # object creation\ntext = 'Looking at center!'\n\n\"\"\" RATE\"\"\"\nengine.setProperty('rate', 120)   \nrate = engine.getProperty('rate')   # getting details of current speaking rate\nprint (rate)                        #printing current voice rate\n  # setting up new voice rate\n\n\n\"\"\"VOLUME\"\"\"\nvolume = engine.getProperty('volume')   #getting to know current volume level (min=0 and max=1)\nprint (volume)                          #printing current volume level\nengine.setProperty('volume',1.0)    # setting up volume level  between 0 and 1\n\n\"\"\"VOICE\"\"\"\nvoices = engine.getProperty('voices')       #getting details of current voice\n#engine.setProperty('voice', voices[0].id)  #changing index, changes voices. o for male\nengine.setProperty('voice', voices[1].id)   #changing index, changes voices. 1 for female\n\nengine.say(text)\nengine.runAndWait()\nengine.stop()\n\n\"\"\"Saving Voice to a file\"\"\"\n# On linux make sure that 'espeak' and 'ffmpeg' are installed\nengine.save_to_file(text, 'center.wav')\nengine.runAndWait()"
  },
  {
    "path": "Eye_Tracking_part4/main.py",
    "content": "\nimport cv2 as cv\nimport mediapipe as mp\nimport time\nimport utils, math\nimport numpy as np\nimport pygame \nfrom pygame import mixer \n\n# variables \nframe_counter =0\nCEF_COUNTER =0\nTOTAL_BLINKS =0\nstart_voice= False\ncounter_right=0\ncounter_left =0\ncounter_center =0 \n# constants\nCLOSED_EYES_FRAME =3\nFONTS =cv.FONT_HERSHEY_COMPLEX\n\n# initialize mixer \nmixer.init()\n# loading in the voices/sounds \nvoice_left = mixer.Sound('Voice/left.wav')\nvoice_right = mixer.Sound('Voice/Right.wav')\nvoice_center = mixer.Sound('Voice/center.wav')\n\n# face bounder indices \nFACE_OVAL=[ 10, 338, 297, 332, 284, 251, 389, 356, 454, 323, 361, 288, 397, 365, 379, 378, 400, 377, 152, 148, 176, 149, 150, 136, 172, 58, 132, 93, 234, 127, 162, 21, 54, 103,67, 109]\n\n# lips indices for Landmarks\nLIPS=[ 61, 146, 91, 181, 84, 17, 314, 405, 321, 375,291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95,185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78 ]\nLOWER_LIPS =[61, 146, 91, 181, 84, 17, 314, 405, 321, 375, 291, 308, 324, 318, 402, 317, 14, 87, 178, 88, 95]\nUPPER_LIPS=[ 185, 40, 39, 37,0 ,267 ,269 ,270 ,409, 415, 310, 311, 312, 13, 82, 81, 42, 183, 78] \n# Left eyes indices \nLEFT_EYE =[ 362, 382, 381, 380, 374, 373, 390, 249, 263, 466, 388, 387, 386, 385,384, 398 ]\nLEFT_EYEBROW =[ 336, 296, 334, 293, 300, 276, 283, 282, 295, 285 ]\n\n# right eyes indices\nRIGHT_EYE=[ 33, 7, 163, 144, 145, 153, 154, 155, 133, 173, 157, 158, 159, 160, 161 , 246 ]  \nRIGHT_EYEBROW=[ 70, 63, 105, 66, 107, 55, 65, 52, 53, 46 ]\n\nmap_face_mesh = mp.solutions.face_mesh\n\n# camera object \ncamera = cv.VideoCapture(1)\n_, frame = camera.read()\nimg = cv.resize(frame, None, fx=1.5, fy=1.5, interpolation=cv.INTER_CUBIC)\nimg_hieght, img_width = img.shape[:2]\nprint(img_hieght, img_width)\n\n\n\n# video Recording setup \nfourcc = cv.VideoWriter_fourcc(*'XVID')\nout = cv.VideoWriter('output21.mp4', fourcc, 30.0, (img_width, img_hieght))\n# landmark detection function \n\ndef landmarksDetection(img, results, draw=False):\n    img_height, img_width= img.shape[:2]\n    # list[(x,y), (x,y)....]\n    mesh_coord = [(int(point.x * img_width), int(point.y * img_height)) for point in results.multi_face_landmarks[0].landmark]\n    if draw :\n        [cv.circle(img, p, 2, (0,255,0), -1) for p in mesh_coord]\n\n    # returning the list of tuples for each landmarks \n    return mesh_coord\n\n# Euclaidean distance \ndef euclaideanDistance(point, point1):\n    x, y = point\n    x1, y1 = point1\n    distance = math.sqrt((x1 - x)**2 + (y1 - y)**2)\n    return distance\n\n# Blinking Ratio\ndef blinkRatio(img, landmarks, right_indices, left_indices):\n    # Right eyes \n    # horizontal line \n    rh_right = landmarks[right_indices[0]]\n    rh_left = landmarks[right_indices[8]]\n    # vertical line \n    rv_top = landmarks[right_indices[12]]\n    rv_bottom = landmarks[right_indices[4]]\n    # draw lines on right eyes \n    # cv.line(img, rh_right, rh_left, utils.GREEN, 2)\n    # cv.line(img, rv_top, rv_bottom, utils.WHITE, 2)\n\n    # LEFT_EYE \n    # horizontal line \n    lh_right = landmarks[left_indices[0]]\n    lh_left = landmarks[left_indices[8]]\n\n    # vertical line \n    lv_top = landmarks[left_indices[12]]\n    lv_bottom = landmarks[left_indices[4]]\n\n    rhDistance = euclaideanDistance(rh_right, rh_left)\n    rvDistance = euclaideanDistance(rv_top, rv_bottom)\n\n    lvDistance = euclaideanDistance(lv_top, lv_bottom)\n    lhDistance = euclaideanDistance(lh_right, lh_left)\n\n    reRatio = rhDistance/rvDistance\n    leRatio = lhDistance/lvDistance\n\n    ratio = (reRatio+leRatio)/2\n    return ratio \n\n# Eyes Extrctor function,\ndef eyesExtractor(img, right_eye_coords, left_eye_coords):\n    # converting color image to  scale image \n    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n    \n    # getting the dimension of image \n    dim = gray.shape\n\n    # creating mask from gray scale dim\n    mask = np.zeros(dim, dtype=np.uint8)\n\n    # drawing Eyes Shape on mask with white color \n    cv.fillPoly(mask, [np.array(right_eye_coords, dtype=np.int32)], 255)\n    cv.fillPoly(mask, [np.array(left_eye_coords, dtype=np.int32)], 255)\n\n    # showing the mask \n    # cv.imshow('mask', mask)\n    \n    # draw eyes image on mask, where white shape is \n    eyes = cv.bitwise_and(gray, gray, mask=mask)\n    # change black color to gray other than eys \n    # cv.imshow('eyes draw', eyes)\n    eyes[mask==0]=155\n    \n    # getting minium and maximum x and y  for right and left eyes \n    # For Right Eye \n    r_max_x = (max(right_eye_coords, key=lambda item: item[0]))[0]\n    r_min_x = (min(right_eye_coords, key=lambda item: item[0]))[0]\n    r_max_y = (max(right_eye_coords, key=lambda item : item[1]))[1]\n    r_min_y = (min(right_eye_coords, key=lambda item: item[1]))[1]\n\n    # For LEFT Eye\n    l_max_x = (max(left_eye_coords, key=lambda item: item[0]))[0]\n    l_min_x = (min(left_eye_coords, key=lambda item: item[0]))[0]\n    l_max_y = (max(left_eye_coords, key=lambda item : item[1]))[1]\n    l_min_y = (min(left_eye_coords, key=lambda item: item[1]))[1]\n\n    # croping the eyes from mask \n    cropped_right = eyes[r_min_y: r_max_y, r_min_x: r_max_x]\n    cropped_left = eyes[l_min_y: l_max_y, l_min_x: l_max_x]\n\n    # returning the cropped eyes \n    return cropped_right, cropped_left\n\n# Eyes Postion Estimator \ndef positionEstimator(cropped_eye):\n    # getting height and width of eye \n    h, w =cropped_eye.shape\n    \n    # remove the noise from images\n    gaussain_blur = cv.GaussianBlur(cropped_eye, (9,9),0)\n    median_blur = cv.medianBlur(gaussain_blur, 3)\n\n    # applying thrsholding to convert binary_image\n    ret, threshed_eye = cv.threshold(median_blur, 130, 255, cv.THRESH_BINARY)\n\n    # create fixd part for eye with \n    piece = int(w/3) \n\n    # slicing the eyes into three parts \n    right_piece = threshed_eye[0:h, 0:piece]\n    center_piece = threshed_eye[0:h, piece: piece+piece]\n    left_piece = threshed_eye[0:h, piece +piece:w]\n    \n    # calling pixel counter function\n    eye_position, color = pixelCounter(right_piece, center_piece, left_piece)\n\n    return eye_position, color \n\n# creating pixel counter function \ndef pixelCounter(first_piece, second_piece, third_piece):\n    # counting black pixel in each part \n    right_part = np.sum(first_piece==0)\n    center_part = np.sum(second_piece==0)\n    left_part = np.sum(third_piece==0)\n    # creating list of these values\n    eye_parts = [right_part, center_part, left_part]\n\n    # getting the index of max values in the list \n    max_index = eye_parts.index(max(eye_parts))\n    pos_eye ='' \n    if max_index==0:\n        pos_eye=\"RIGHT\"\n        color=[utils.BLACK, utils.GREEN]\n    elif max_index==1:\n        pos_eye = 'CENTER'\n        color = [utils.YELLOW, utils.PINK]\n    elif max_index ==2:\n        pos_eye = 'LEFT'\n        color = [utils.GRAY, utils.YELLOW]\n    else:\n        pos_eye=\"Closed\"\n        color = [utils.GRAY, utils.YELLOW]\n    return pos_eye, color\n\n\nwith map_face_mesh.FaceMesh(min_detection_confidence =0.5, min_tracking_confidence=0.5) as face_mesh:\n\n    # starting time here \n    start_time = time.time()\n    # starting Video loop here.\n    while True:\n        frame_counter +=1 # frame counter\n        ret, frame = camera.read() # getting frame from camera \n        if not ret: \n            break # no more frames break\n        #  resizing frame\n        \n        frame = cv.resize(frame, None, fx=1.5, fy=1.5, interpolation=cv.INTER_CUBIC)\n        frame_height, frame_width= frame.shape[:2]\n        rgb_frame = cv.cvtColor(frame, cv.COLOR_RGB2BGR)\n        results  = face_mesh.process(rgb_frame)\n        if results.multi_face_landmarks:\n            mesh_coords = landmarksDetection(frame, results, False)\n            ratio = blinkRatio(frame, mesh_coords, RIGHT_EYE, LEFT_EYE)\n            # cv.putText(frame, f'ratio {ratio}', (100, 100), FONTS, 1.0, utils.GREEN, 2)\n            utils.colorBackgroundText(frame,  f'Ratio : {round(ratio,2)}', FONTS, 0.7, (30,100),2, utils.PINK, utils.YELLOW)\n\n            if ratio >5.5:\n                CEF_COUNTER +=1\n                # cv.putText(frame, 'Blink', (200, 50), FONTS, 1.3, utils.PINK, 2)\n                utils.colorBackgroundText(frame,  f'Blink', FONTS, 1.7, (int(frame_height/2), 100), 2, utils.YELLOW, pad_x=6, pad_y=6, )\n\n            else:\n                if CEF_COUNTER>CLOSED_EYES_FRAME:\n                    TOTAL_BLINKS +=1\n                    CEF_COUNTER =0\n            # cv.putText(frame, f'Total Blinks: {TOTAL_BLINKS}', (100, 150), FONTS, 0.6, utils.GREEN, 2)\n            utils.colorBackgroundText(frame,  f'Total Blinks: {TOTAL_BLINKS}', FONTS, 0.7, (30,150),2)\n            \n            cv.polylines(frame,  [np.array([mesh_coords[p] for p in LEFT_EYE ], dtype=np.int32)], True, utils.GREEN, 1, cv.LINE_AA)\n            cv.polylines(frame,  [np.array([mesh_coords[p] for p in RIGHT_EYE ], dtype=np.int32)], True, utils.GREEN, 1, cv.LINE_AA)\n\n            # Blink Detector Counter Completed\n            right_coords = [mesh_coords[p] for p in RIGHT_EYE]\n            left_coords = [mesh_coords[p] for p in LEFT_EYE]\n            crop_right, crop_left = eyesExtractor(frame, right_coords, left_coords)\n            # cv.imshow('right', crop_right)\n            # cv.imshow('left', crop_left)\n            eye_position_right, color = positionEstimator(crop_right)\n            utils.colorBackgroundText(frame, f'R: {eye_position_right}', FONTS, 1.0, (40, 220), 2, color[0], color[1], 8, 8)\n            eye_position_left, color = positionEstimator(crop_left)\n            utils.colorBackgroundText(frame, f'L: {eye_position_left}', FONTS, 1.0, (40, 320), 2, color[0], color[1], 8, 8)\n            \n            # Starting Voice Indicator \n            if eye_position_right==\"RIGHT\" and pygame.mixer.get_busy()==0 and counter_right<2:\n                # starting counter \n                counter_right+=1\n                # resetting counters \n                counter_center=0\n                counter_left=0\n                # playing voice \n                voice_right.play()\n\n\n            if eye_position_right==\"CENTER\" and pygame.mixer.get_busy()==0 and counter_center <2:\n                # starting Counter \n                counter_center +=1\n                # resetting counters \n                counter_right=0\n                counter_left=0\n                # playing voice \n                voice_center.play()\n            \n            if eye_position_right==\"LEFT\" and pygame.mixer.get_busy()==0 and counter_left<2: \n                counter_left +=1\n                # resetting counters \n                counter_center=0\n                counter_right=0\n                # playing Voice \n                voice_left.play()\n\n\n\n        # calculating  frame per seconds FPS\n        end_time = time.time()-start_time\n        fps = frame_counter/end_time\n        \n\n        frame =utils.textWithBackground(frame,f'FPS: {round(fps,1)}',FONTS, 1.0, (30, 50), bgOpacity=0.9, textThickness=2)\n        # writing image for thumbnail drawing shape\n        # cv.imwrite(f'img/frame_{frame_counter}.png', frame)\n        # wirting the video for demo purpose \n        out.write(frame)\n        cv.imshow('frame', frame)\n        key = cv.waitKey(2)\n        if key==ord('q') or key ==ord('Q'):\n            break\n    cv.destroyAllWindows()\n    camera.release()\n"
  },
  {
    "path": "Eye_Tracking_part4/utils.py",
    "content": "'''\n\nAuthor: Asadullah Dal \nYoutube Channel: https://www.youtube.com/c/aiphile\n\n'''\n\nimport cv2 as cv \nimport numpy as np\n\n# colors \n# values =(blue, green, red) opencv accepts BGR values not RGB\nBLACK = (0,0,0)\nWHITE = (255,255,255)\nBLUE = (255,0,0)\nRED = (0,0,255)\nCYAN = (255,255,0)\nYELLOW =(0,255,255)\nMAGENTA = (255,0,255)\nGRAY = (128,128,128)\nGREEN = (0,255,0)\nPURPLE = (128,0,128)\nORANGE = (0,165,255)\nPINK = (147,20,255)\npoints_list =[(200, 300), (150, 150), (400, 200)]\ndef drawColor(img, colors):\n    x, y = 0,10\n    w, h = 20, 30\n    \n    for color in colors:\n        x += w+5 \n        # y += 10 \n        cv.rectangle(img, (x-6, y-5 ), (x+w+5, y+h+5), (10, 50, 10), -1)\n        cv.rectangle(img, (x, y ), (x+w, y+h), color, -1)\n    \ndef colorBackgroundText(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    cv.rectangle(img, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n\n    return img\n\ndef textWithBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0), bgColor=(0,0,0), pad_x=3, pad_y=3, bgOpacity=0.5):\n    \"\"\"\n    Draws text with background, with  control transparency\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param bgColor: tuple(BGR), values -->0 to 255 each\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels) 1 to 1.0 (), controls transparency of  text background \n    @return: img(mat) with draw with background\n    \"\"\"\n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    overlay = img.copy() # coping the image\n    cv.rectangle(overlay, (x-pad_x, y+ pad_y), (x+t_w+pad_x, y-t_h-pad_y), bgColor,-1) # draw rectangle \n    new_img = cv.addWeighted(overlay, bgOpacity, img, 1 - bgOpacity, 0) # overlaying the rectangle on the image.\n    cv.putText(new_img,text, textPos,font, fontScale, textColor,textThickness ) # draw in text\n    img = new_img\n\n    return img\n\n\ndef textBlurBackground(img, text, font, fontScale, textPos, textThickness=1,textColor=(0,255,0),kneral=(33,33) , pad_x=3, pad_y=3):\n    \"\"\"    \n    Draw text with background blured,  control the blur value, with kernal(odd, odd)\n    @param img:(mat) which you want to draw text\n    @param text: (string) text you want draw\n    @param font: fonts face, like FONT_HERSHEY_COMPLEX, FONT_HERSHEY_PLAIN etc.\n    @param fontScale: (double) the size of text, how big it should be.\n    @param textPos: tuple(x,y) position where you want to draw text\n    @param textThickness:(int) fonts weight, how bold it should be.\n    @param textColor: tuple(BGR), values -->0 to 255 each\n    @param kneral: tuple(3,3) int as odd number:  higher the value, more blurry background would be\n    @param pad_x: int(pixels)  padding of in x direction\n    @param pad_y: int(pixels)  padding of in y direction\n    @return: img mat, with text drawn, with background blured\n    \n    call the function: \n     img =textBlurBackground(img, 'Blured Background Text', cv2.FONT_HERSHEY_COMPLEX, 0.9, (20, 60),2, (0,255, 0), (49,49), 13, 13 )\n    \"\"\"\n    \n    (t_w, t_h), _= cv.getTextSize(text, font, fontScale, textThickness) # getting the text size\n    x, y = textPos\n    blur_roi = img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x] # croping Text Background\n    img[y-pad_y-t_h: y+pad_y, x-pad_x:x+t_w+pad_x]=cv.blur(blur_roi, kneral)  # merging the blured background to img\n    cv.putText(img,text, textPos,font, fontScale, textColor,textThickness )          \n    # cv.imshow('blur roi', blur_roi)\n    # cv.imshow('blured', img)\n\n    return img\n\ndef fillPolyTrans(img, points, color, opacity):\n    \"\"\"\n    @param img: (mat) input image, where shape is drawn.\n    @param points: list [tuples(int, int) these are the points custom shape,FillPoly\n    @param color: (tuples (int, int, int)\n    @param opacity:  it is transparency of image.\n    @return: img(mat) image with rectangle draw.\n\n    \"\"\"\n    list_to_np_array = np.array(points, dtype=np.int32)\n    overlay = img.copy()  # coping the image\n    cv.fillPoly(overlay,[list_to_np_array], color )\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0)\n    # print(points_list)\n    img = new_img\n    cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n    return img\n\n# def pollyLines(img, points, color):\n#     list_to_np_array = np.array(points, dtype=np.int32)\n#     cv.polylines(img, [list_to_np_array], True, color,1, cv.LINE_AA)\n#     return img\n\ndef rectTrans(img, pt1, pt2, color, thickness, opacity):\n    \"\"\"\n\n    @param img: (mat) input image, where shape is drawn.\n    @param pt1: tuple(int,int) it specifies the starting point(x,y) os rectangle\n    @param pt2: tuple(int,int)  it nothing but width and height of rectangle\n    @param color: (tuples (int, int, int), it tuples of BGR values\n    @param thickness: it thickness of board line rectangle, if (-1) passed then rectangle will be fulled with color.\n    @param opacity:  it is transparency of image.\n    @return:\n    \"\"\"\n    overlay = img.copy()\n    cv.rectangle(overlay, pt1, pt2, color, thickness)\n    new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0) # overlaying the rectangle on the image.\n    img = new_img\n\n    return img\n\ndef main():\n    cap = cv.VideoCapture('Girl.mp4')\n    counter =0\n    while True:\n        success, img = cap.read()\n        # img = np.zeros((1000,1000, 3), dtype=np.uint8)\n        img=rectTrans(img, pt1=(30, 320), pt2=(160, 260), color=(0,255,255),thickness=-1, opacity=0.6)\n        img =fillPolyTrans(img=img, points=points_list, color=(0,255,0), opacity=.5)\n        drawColor(img, [BLACK,WHITE ,BLUE,RED,CYAN,YELLOW,MAGENTA,GRAY ,GREEN,PURPLE,ORANGE,PINK])\n        textBlurBackground(img, 'Blured Background Text', cv.FONT_HERSHEY_COMPLEX, 0.8, (60, 140),2, YELLOW, (71,71), 13, 13)\n        img=textWithBackground(img, 'Colored Background Texts', cv.FONT_HERSHEY_SIMPLEX, 0.8, (60,80), textThickness=2, bgColor=GREEN, textColor=BLACK, bgOpacity=0.7, pad_x=6, pad_y=6)\n        imgGray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)\n        # cv.imwrite('color_image.png', img)\n        counter +=1\n        cv.imshow('img', img)\n        cv.imwrite(f'image/image_{counter}.png', img)\n        if cv.waitKey(1) ==ord('q'):\n            break\n\nif __name__ == \"__main__\":\n    main()\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2021 Asadullah Dal\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Eyes-Position-Estimator-Mediapipe\n![GitHub Repo stars](https://img.shields.io/github/stars/Asadullah-Dal17/Eyes-Position-Estimator-Mediapipe?style=social) ![GitHub forks](https://img.shields.io/github/forks/Asadullah-Dal17/Eyes-Position-Estimator-Mediapipe?style=social) ![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCc8Lx22a5OX4XMxrCykzjbA?style=social)\n> *This is Eyes :eye: :eye: Tracking Project, here we will use computer vision techniques to extracting the eyes,  mediapipe python modules will provide the landmarks*, \n\n## Eyes Position Estimation Demo without Voice\n\nhttps://user-images.githubusercontent.com/66181793/134312531-d8f6b068-13d9-4590-a1d2-232ea4cf5681.mp4\n\n## Iris Tracking Mediapipe Opencv python   [Video Tutorial 📹](https://youtu.be/DNKAvDeqH_Y)\nhttps://user-images.githubusercontent.com/66181793/150673670-7b12506f-67d6-4540-96f7-ea6233c01bd6.mp4\n\n## TODO \n\n##### Eyes Tracking Part 1  [Video Tutorial](https://youtu.be/-jFobb6ARc4)\n\n- [x] Detecting face landmarks with Mediapipe 👨‍💻  \n- [x] Detecting Eyes Landmarks 👁️‍🗨️ 👁️‍🗨️  \n- [x] Draw Eyes,Eyebrows, lips and Face Oval with transparent shapes.\n\n##### Eyes Tracking Part 2 [Video Tutorial](https://youtu.be/XIJD43rbI-4) \n- [x] Detecting the blinks\n- [x] Counting Blinks\n\n##### Eyes Tracking Part 3 [Video Tutorial](https://youtu.be/Y-mCtkv41rk) \n\n- [x] Extracting Eyes from the frame using Masking techniques\n\n- [x] Thresholding Eyes to get black ⚫ and white ⚪ pixels separated \n\n- [x] Dividing Each Eye into three 3️⃣ pieces, right_piece, center_piece, left_piece\n\n- [x] Counting the Black Pixel in each piece, and estimating position.\n\n##### Eyes Tracking Part 4 [Video Tutorial](https://youtu.be/oAgu20kuRQw) \n\n- [x] Voice position indicator using pygame.\n \n\n#### [**Blog Post:** ](https://aiphile.blogspot.com/2021/08/eyes-tracking-mediapipe-part1.html)\n\n\n\n\n\n### Face Mesh Points  \n<details>\n<summary>Face Mesh Points</summary>\n<br>\n\n<img src='/mesh_image.png'>\n \n </br>\n</details>\n\n### Face Mesh Map Points  \n\n<details>\n<summary>Face Mesh Map Points</summary>\n<br>\n \n![Face Mesh Map image](mesh_map.jpg)\n \n \n </br>\n</details>\n\nIf you found this helpful, please star :star: it.\n\nYou can Watch my Video Tutorial on Computer Vision Topics, just check out my YouTube Channel <a href=\"https://www.youtube.com/c/aiphile\">  <img alt=\"AiPhile Youtube\" src=\"https://user-images.githubusercontent.com/66181793/131223988-882d53a0-4882-468f-9bd7-46b46466baae.png\"  width=\"20\"> </a>\n\n\n## 📫 Let's Connect\n\n<div align=\\\"center\\\">\n\n[![YouTube](https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/@asadullah-dal)\n[![Instagram](https://img.shields.io/badge/Instagram-E4405F?style=for-the-badge&logo=instagram&logoColor=white)](https://www.instagram.com/aiphile17)\n[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/aiphile)\n[![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/ai_phile)\n[![Medium](https://img.shields.io/badge/Medium-12100E?style=for-the-badge&logo=medium&logoColor=white)](https://medium.com/@aiphile)\n[![Portfolio](https://img.shields.io/badge/Portfolio-00C7B7?style=for-the-badge&logo=About.me&logoColor=white)](https://asadullah-dal17.github.io/asadullahdal.github.io)\n\n### 💼 Freelance Platforms\n\n[![Fiverr](https://img.shields.io/badge/Fiverr-1DBF73?style=for-the-badge&logo=fiverr&logoColor=white)](https://www.fiverr.com/asadullahdal482)\n[![Kwork](https://img.shields.io/badge/Kwork-Freelance-black?style=for-the-badge&logo=kwork&logoColor=white)](https://kwork.com/user/asadullah92)\n\n</div>\n\n## 💬 Questions or Need Help?\n\nIf you have any questions or need help with the project, feel free to DM me on [Instagram](https://www.instagram.com/aiphile17)!\n\n<a href=\"https://www.instagram.com/aiphile17\">\n    <img src=\"https://img.shields.io/badge/Instagram-purple?style=for-the-badge&logo=Instagram&logoColor=white\" height=20  alt=\"Insta Badge\"/>\n  </a>\n"
  }
]