diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a53d962 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.mp4 \ No newline at end of file diff --git a/Capture_Reference_image/Capture_Reference_Image.py b/Capture_Reference_image/Capture_Reference_Image.py index f034a94..1b37254 100644 --- a/Capture_Reference_image/Capture_Reference_Image.py +++ b/Capture_Reference_image/Capture_Reference_Image.py @@ -1,63 +1,63 @@ - -import cv2 -import time -import os -# chose your camera number: -cam_number =2 -camera = cv2.VideoCapture(cam_number) -starting_time =time.time() -Frame_Counter= 0 -Cap_frame =0 -Dir_name = "capture_images" -number_image_captured =20 -capture_image=False -while True: - # checking the Directory Exist or not . - IsDirExist = os.path.exists(Dir_name) - print(IsDirExist) - # if there is no Directory named "capture_image", simply create it. using os - if not IsDirExist: - os.mkdir(Dir_name) - - Frame_Counter+=1 - # reading the frames from camera - ret, frame = camera.read() - # reading saving frame seperatly - ret, saving_frame = camera.read() - # finding with and height of image - height, width, dim = saving_frame.shape - # print(width, height, dim) - - # writing the width and height of on the image saving image - cv2.putText(saving_frame, f"Height: {height}", (30, 50), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0,255,0),1) - cv2.putText(saving_frame, f"Width: {width}", (30, 70), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0,255,0),1) - # capture frame if capture_image is ture and number_image_captured are less then 10 - # if we press 'c' on keyboard then capture_image become 'True' - if capture_image==True and Cap_frame <= number_image_captured: - Cap_frame+=1 - cv2.putText(frame, 'Capturing', (50, 70), cv2.FONT_HERSHEY_COMPLEX, 2, (0,244, 255),1) - cv2.imwrite(f"{Dir_name}/frame-{Cap_frame}.png", saving_frame) - else: - cv2.putText(frame, 'Not Capturing', (50, 70), cv2.FONT_HERSHEY_COMPLEX, 2, (255,0, 255),1) - Cap_frame =0 - capture_image =False - cv2.imshow("frame", frame) - cv2.imshow("saving Image", saving_frame) - total_time = time.time() - frame_time=total_time -starting_time - # calculating how much frame pass in each second - - fps = Frame_Counter/frame_time - # print(fps) - # print(capture_image) - # when we press 'q' it quites the program - if cv2.waitKey(1) == ord('q'): - break - # if we press 'c' on the keyboard then it starts capturing the images. - if cv2.waitKey(1)==ord('c'): - capture_image= True - -# finally closing the camera -camera.release() -# closing all opend windows + +import cv2 +import time +import os +# chose your camera number: +cam_number =2 +camera = cv2.VideoCapture(cam_number) +starting_time =time.time() +Frame_Counter= 0 +Cap_frame =0 +Dir_name = "capture_images" +number_image_captured =20 +capture_image=False +while True: + # checking the Directory Exist or not . + IsDirExist = os.path.exists(Dir_name) + print(IsDirExist) + # if there is no Directory named "capture_image", simply create it. using os + if not IsDirExist: + os.mkdir(Dir_name) + + Frame_Counter+=1 + # reading the frames from camera + ret, frame = camera.read() + # reading saving frame seperatly + ret, saving_frame = camera.read() + # finding with and height of image + height, width, dim = saving_frame.shape + # print(width, height, dim) + + # writing the width and height of on the image saving image + cv2.putText(saving_frame, f"Height: {height}", (30, 50), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0,255,0),1) + cv2.putText(saving_frame, f"Width: {width}", (30, 70), cv2.FONT_HERSHEY_COMPLEX, 0.4, (0,255,0),1) + # capture frame if capture_image is ture and number_image_captured are less then 10 + # if we press 'c' on keyboard then capture_image become 'True' + if capture_image==True and Cap_frame <= number_image_captured: + Cap_frame+=1 + cv2.putText(frame, 'Capturing', (50, 70), cv2.FONT_HERSHEY_COMPLEX, 2, (0,244, 255),1) + cv2.imwrite(f"{Dir_name}/frame-{Cap_frame}.png", saving_frame) + else: + cv2.putText(frame, 'Not Capturing', (50, 70), cv2.FONT_HERSHEY_COMPLEX, 2, (255,0, 255),1) + Cap_frame =0 + capture_image =False + cv2.imshow("frame", frame) + cv2.imshow("saving Image", saving_frame) + total_time = time.time() + frame_time=total_time -starting_time + # calculating how much frame pass in each second + + fps = Frame_Counter/frame_time + # print(fps) + # print(capture_image) + # when we press 'q' it quites the program + if cv2.waitKey(1) == ord('q'): + break + # if we press 'c' on the keyboard then it starts capturing the images. + if cv2.waitKey(1)==ord('c'): + capture_image= True + +# finally closing the camera +camera.release() +# closing all opend windows cv2.destroyAllWindows() \ No newline at end of file diff --git a/Capture_Reference_image/Distance_Measurement.py b/Capture_Reference_image/Distance_Measurement.py index 88010a6..2e83075 100644 --- a/Capture_Reference_image/Distance_Measurement.py +++ b/Capture_Reference_image/Distance_Measurement.py @@ -1,54 +1,54 @@ -import cv2 as cv - - -# data -Know_distance =30 # in centimeters -#mine is 14.3 something, measure your face width, are google it -Know_width_face =14.3 #centimeters -# chose your camera -cam_number =1 -face_detector = cv.CascadeClassifier('data/haarcascade_frontalface_default.xml') -camera = cv.VideoCapture(cam_number) -def FocalLengthFinder(Measured_distance, real_width_of_face, width_of_face_in_image): - # finding focal length - focal_length = (width_of_face_in_image* Measured_distance)/real_width_of_face - return focal_length - -def Distance_Measurement(face_real_width, Focal_Length, face_with_in_image): - distance= (face_real_width * Focal_Length)/face_with_in_image - return distance -def Face_Detection(image): - f_width =0 - Gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) - faces = face_detector.detectMultiScale(Gray_image, 1.3, 5) - for (x, y, h, w) in faces: - cv.rectangle(image, (x,y), (x+w, y+h), (255,255,255), 1) - f_width =w - print(f_width) - return f_width, image -reference_image =cv.imread("rf.png") -face_w , image_read= Face_Detection(reference_image) -cv.imshow("ref", image_read) -calculate_focal_length =FocalLengthFinder(Know_distance, Know_width_face,face_w) -print(calculate_focal_length) -font = cv.FONT_HERSHEY_SIMPLEX -while True: - ret, frame = camera.read() - height, width, dim = frame.shape - # change the color of image - # print(height, width) - Gray_image = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) - faces = face_detector.detectMultiScale(Gray_image, 1.3, 5) - for (x, y, h, w) in faces: - cv.rectangle(frame, (x,y), (x+w, y+h), (255,255,255), 1) - distance =Distance_Measurement(Know_width_face,calculate_focal_length, w) - print(distance) - - cv.putText(frame, f" Distance = {distance}", (50,50),font, 0.7, (0,255,0), 3) - - cv.imshow('frame', frame) - - if cv.waitKey(1)==ord('q'): - break -camera.release() -cv.destroyAllWindows() +import cv2 as cv + + +# data +Know_distance =30 # in centimeters +#mine is 14.3 something, measure your face width, are google it +Know_width_face =14.3 #centimeters +# chose your camera +cam_number =1 +face_detector = cv.CascadeClassifier('data/haarcascade_frontalface_default.xml') +camera = cv.VideoCapture(cam_number) +def FocalLengthFinder(Measured_distance, real_width_of_face, width_of_face_in_image): + # finding focal length + focal_length = (width_of_face_in_image* Measured_distance)/real_width_of_face + return focal_length + +def Distance_Measurement(face_real_width, Focal_Length, face_with_in_image): + distance= (face_real_width * Focal_Length)/face_with_in_image + return distance +def Face_Detection(image): + f_width =0 + Gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(Gray_image, 1.3, 5) + for (x, y, h, w) in faces: + cv.rectangle(image, (x,y), (x+w, y+h), (255,255,255), 1) + f_width =w + print(f_width) + return f_width, image +reference_image =cv.imread("rf.png") +face_w , image_read= Face_Detection(reference_image) +cv.imshow("ref", image_read) +calculate_focal_length =FocalLengthFinder(Know_distance, Know_width_face,face_w) +print(calculate_focal_length) +font = cv.FONT_HERSHEY_SIMPLEX +while True: + ret, frame = camera.read() + height, width, dim = frame.shape + # change the color of image + # print(height, width) + Gray_image = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(Gray_image, 1.3, 5) + for (x, y, h, w) in faces: + cv.rectangle(frame, (x,y), (x+w, y+h), (255,255,255), 1) + distance =Distance_Measurement(Know_width_face,calculate_focal_length, w) + print(distance) + + cv.putText(frame, f" Distance = {distance}", (50,50),font, 0.7, (0,255,0), 3) + + cv.imshow('frame', frame) + + if cv.waitKey(1)==ord('q'): + break +camera.release() +cv.destroyAllWindows() diff --git a/README.md b/README.md index 308f4cc..7a98897 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,144 @@ -# Distance_measurement_using_single_camera - - -## Clone this Repo: -git clone https://github.com/Asadullah-Dal17/Distance_measurement_using_single_camera - -## install Opencv-python on Windows -pip install opencv-python - -install Opencv-python on Linux or Mac -pip3 install opencv-python - -# Run the code -## windows: -python distance.py -## linux or Mac: -python3 distance.py - -Youtube Video: https://youtu.be/zzJfAw3ASzY - +# Distance measurement using single:one:camera :camera: + +![GitHub Repo stars](https://img.shields.io/github/stars/Asadullah-Dal17/Distance_measurement_using_single_camera?style=social) ![GitHub forks](https://img.shields.io/github/forks/Asadullah-Dal17/Distance_measurement_using_single_camera?style=social) ![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCc8Lx22a5OX4XMxrCykzjbA?style=social) + +If you want to estimate distance of objects with your simple webcam, then this algorithm(*Triangle similarity*) would be helpful for you to find Distance *from object to camera*, I have provide to two examples, one is simple **face detection and distance Estimation**, other is **Yolo4 object detection and distance Estimation** + +Here in this readme file you will get short description, if need more details, then you can watch video tutorial on YouTube as well. + +## Distance & Speed Estimation Demo + +https://user-images.githubusercontent.com/66181793/122644855-bb8ac000-d130-11eb-85c3-c7ff4bd6474c.mp4 + +### Video Tutorials + +[**Distance Estimation Youtube Tutorail**](https://youtu.be/zzJfAw3ASzY) ![YouTube Video Views](https://img.shields.io/youtube/views/zzJfAw3ASzY?style=social) + +[**Distance & Speed Estimation Youtube Tutorial**](https://youtu.be/DIxcLghsQ4Q) ![YouTube Video Views](https://img.shields.io/youtube/views/DIxcLghsQ4Q?style=social) + +[**YoloV4 Object Detection & Distance Estimation**](https://youtu.be/FcRCwTgYXJw) ![YouTube Video Views](https://img.shields.io/youtube/views/FcRCwTgYXJw?style=social) +[*Project GitHub Repository*](https://github.com/Asadullah-Dal17/Yolov4-Detector-and-Distance-Estimator) + +## YoloV4 Distance Estimation + +https://user-images.githubusercontent.com/66181793/124917186-f5066b00-e00c-11eb-93cf-24d84e9c2e7a.mp4 + +## Distance Estimation on Raspberry Pi 🍓 + +https://user-images.githubusercontent.com/66181793/138200943-74d28b4d-bd0e-49fd-8836-4a01b35118eb.mp4 + +✔️ here is source code and details for Instllation of Opencv-python on 🍓 Pi 😃 [Distance Estimation on Raspberry pi 🍓](https://github.com/Asadullah-Dal17/Distance_measurement_using_single_camera/tree/main/Raspberry_pi) + + +:heavy_check_mark: I have included [**Speed Estimation**](https://github.com/Asadullah-Dal17/Distance_measurement_using_single_camera/tree/main/Speed) code is well check that out. + +:heavy_check_mark: You can find the implementation of [**Distance estimation of multiple objects using Yolo V4**](https://github.com/Asadullah-Dal17/Yolov4-Detector-and-Distance-Estimator) Object Detector Opencv-python + +## Clone this Repo: + +git clone https://github.com/Asadullah-Dal17/Distance_measurement_using_single_camera + +## install Opencv-python + +- Windows + + pip install opencv-python + +- _install Opencv-python on Linux or Mac_ + + pip3 install opencv-python + +## Run the code + +- windows: :point_down: + + python distance.py + + ------ OR --------- + + python Updated_distance.py + +- linux or Mac :point_down: + + python3 distance.py + + ------ OR --------- + + python3 Updated_distance.py + +### :bulb:_Focal Length Finder Function Description_ :bulb: + +```python +# focal length finder function +def focal_length(measured_distance, real_width, width_in_rf_image): + + focal_length_value = (width_in_rf_image * measured_distance) / real_width + #return focal length. + return focal_length_value + +``` + +The Focal Length finder Function has three Arguments: + +`measured_distance` is the distance which we have measured while capturing the reference image:straight*ruler:. \*\*\_From object to Camera*\*\* which is `Known_distance = 72.2 #centimeter` + +`real_width` It's measured as the width of the object in the real world, here I measured the width of the face in real-world which was `Known_width =14.3 # centimetre` + +`width_in_rf_image` is the width of the object in the image/frame it will be in **pixels** + +### :bulb:_Distance Finder Function Description_ :bulb: + +```python +# Distance estimation function + +def distance_finder(focal_length, real_face_width, face_width_in_frame): + + distance = (real_face_width * focal_length)/face_width_in_frame + return distance + +``` + +This Function takes three Arguments, + +` Focal_Length` is the focal length, out of the **FocalLength** finder function. + +`real_face_width` measures the width of an object in the real world, here I measured the width of a face in real-world which was `Known_width =14.3 #centimeter` + +`face_width_in_frame` is the width of the face in the frame, the unit will be pixels here. + + + +I have also created Face Following Robot which uses distance Estimation If you are interested you can Watch my Youtube Video +You can create the following Robot with Raspberry That would be easy then, using Arduino Stuff, Raspberry 🍓 Pi will make it a system on Robot 🤖 + +If you found this helpful, please star :star: it. + +You can Watch my Video Tutorial on Computer Vision Topics, just check out my YouTube Channel AiPhile Youtube + + +## 📫 Let's Connect + +
+ +[![YouTube](https://img.shields.io/badge/YouTube-FF0000?style=for-the-badge&logo=youtube&logoColor=white)](https://www.youtube.com/@asadullah-dal) +[![Instagram](https://img.shields.io/badge/Instagram-E4405F?style=for-the-badge&logo=instagram&logoColor=white)](https://www.instagram.com/aiphile17) +[![LinkedIn](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/aiphile) +[![Twitter](https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/ai_phile) +[![Medium](https://img.shields.io/badge/Medium-12100E?style=for-the-badge&logo=medium&logoColor=white)](https://medium.com/@aiphile) +[![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) + +### 💼 Freelance Platforms + +[![Fiverr](https://img.shields.io/badge/Fiverr-1DBF73?style=for-the-badge&logo=fiverr&logoColor=white)](https://www.fiverr.com/asadullahdal482) +[![Kwork](https://img.shields.io/badge/Kwork-Freelance-black?style=for-the-badge&logo=kwork&logoColor=white)](https://kwork.com/user/asadullah92) + +
+ +## 💬 Questions or Need Help? + +If you have any questions or need help with the project, feel free to DM me on [Instagram](https://www.instagram.com/aiphile17)! + + + Insta Badge + + diff --git a/Raspberry_pi/AiPhile.py b/Raspberry_pi/AiPhile.py new file mode 100644 index 0000000..cf14ae3 --- /dev/null +++ b/Raspberry_pi/AiPhile.py @@ -0,0 +1,53 @@ +import cv2 as cv +import numpy as np +# colors +BLACK = (0,0,0) +WHITE = (255,255,255) +BLUE = (255,0,0) +RED = (0,0,255) +CYAN = (255,255,0) +YELLOW =(0,255,255) +MAGENTA = (255,0,255) +GREEN = (0,255,0) +PURPLE = (128,0,128) +ORANGE = (0,165,255) +PINK = [147,20,255] +INDIGO=[75,0,130] +VIOLET=[238,130,238] +GRAY=[127,127,127] + +def textBG(img, text, position, fonts ,scaling=1, color=(0,255,0), thickness=1, padding=3): + img_h, img_w = img.shape[:2] + x, y = position + (w, h ), p= cv.getTextSize(text, fonts, scaling, thickness) + # print(w, h) + cv.rectangle(img, (x-p, y+p), (x+w+p, y-h-p), (255, 0,234), -1) + + cv.putText(img, text, position,fonts, scaling, color, thickness) + +def textBGoutline(img, text, position, fonts=cv.FONT_HERSHEY_SIMPLEX ,scaling=1, text_color=(0,255,0), thickness=1, bg_color=(BLACK)): + img_h, img_w = img.shape[:2] + x, y = position + (w, h ), p= cv.getTextSize(text, fonts, scaling, thickness) + # print(w, h) + cv.rectangle(img, (x-p, y+p), (x+w+p, y-h-p), bg_color, -1) + cv.rectangle(img, (x-p, y+p), (x+w+p, y-h-p), text_color,thickness, cv.LINE_AA) + + cv.putText(img, text, position,fonts, scaling, text_color, thickness, cv.LINE_AA ) +def fillPolyTrans(img, points, color, opacity, line_thickness=2): + """ + @param img: (mat) input image, where shape is drawn. + @param points: list [tuples(int, int) these are the points custom shape,FillPoly + @param color: (tuples (int, int, int) + @param opacity: it is transparency of image. + @return: img(mat) image with rectangle draw. + + """ + list_to_np_array = np.array(points, dtype=np.int32) + overlay = img.copy() # coping the image + cv.fillPoly(overlay,[list_to_np_array], color ) + new_img = cv.addWeighted(overlay, opacity, img, 1 - opacity, 0) + # print(points_list) + img = new_img + cv.polylines(img, [list_to_np_array], True, color,line_thickness, cv.LINE_AA) + return img diff --git a/Raspberry_pi/README.md b/Raspberry_pi/README.md new file mode 100644 index 0000000..4f0f9f2 --- /dev/null +++ b/Raspberry_pi/README.md @@ -0,0 +1,34 @@ +# Run Distance Estimation on Raspberry Pi + +## Installation of Opencv-python + +``` +sudo apt install ffmpeg python3-opencv +``` +⚠️ I highly encourage to Build from source, since this module not optimized for Raspberry Pi. + +### Install dependency packages +``` +sudo apt install libxcb-shm0 libcdio-paranoia-dev libsdl2-2.0-0 libxv1 libtheora0 libva-drm2 libva-x11-2 libvdpau1 libharfbuzz0b libbluray2 libatlas-base-dev libhdf5-103 libgtk-3-0 libdc1394-22 libopenexr23 + +``` + +## ⚠️ Distance Estimation on Pi Camera + +> the distance estimation pi_camera is not tested yet, reason I don't have Pi cam 📷 yet, if you have pi cam try confirm that, I would be greatful, 😄 Thank you so much + +I have also create Face Following Robot which use distance Estimation, if you are interested you can Watch my Youtube Video +You can create Face Following Robot with Raspberry that would be easy then, using Arduino Stuff, Raspberry 🍓 Pi will make it system on Robot 🤖 + +if You found this Helpful, please star :star: it. + +You can Watch my Video Tutorial on Computer Vision Topics, just check out my YouTube Channel AiPhile Youtube + + +If You have any Question or need help in CV Project, Feel free to DM on Instagram Instagram + +## 💚🖤 Join me on Social Media 🖤💚 + +

YouTube AiPhile Youtube + GitHub GitHub + Instagram Instagram

diff --git a/Raspberry_pi/__pycache__/AiPhile.cpython-37.pyc b/Raspberry_pi/__pycache__/AiPhile.cpython-37.pyc new file mode 100644 index 0000000..96b7625 Binary files /dev/null and b/Raspberry_pi/__pycache__/AiPhile.cpython-37.pyc differ diff --git a/Raspberry_pi/__pycache__/AiPhile.cpython-38.pyc b/Raspberry_pi/__pycache__/AiPhile.cpython-38.pyc new file mode 100644 index 0000000..0643272 Binary files /dev/null and b/Raspberry_pi/__pycache__/AiPhile.cpython-38.pyc differ diff --git a/Raspberry_pi/distance.py b/Raspberry_pi/distance.py new file mode 100644 index 0000000..187f046 --- /dev/null +++ b/Raspberry_pi/distance.py @@ -0,0 +1,115 @@ +""" +------------------------------------------- +- Author: Asadullah Dal - +- ============================= - +- Company Name: AiPhile - +- ============================= - +- Purpose : Youtube Channel - +- ============================ - +- Link: https://youtube.com/c/aiphile - +------------------------------------------- +""" + +import cv2 as cv +import time +import AiPhile + +# variables +# distance from camera to object(face) measured +KNOWN_DISTANCE = 76.2 # centimeter +# width of face in the real world or Object Plane +KNOWN_WIDTH = 14.3 # centimeter +# Colors +GREEN = (0, 255, 0) +RED = (0, 0, 255) +WHITE = (255, 255, 255) +fonts = cv.FONT_HERSHEY_COMPLEX +cap = cv.VideoCapture(0) + +# face detector object +face_detector = cv.CascadeClassifier("../haarcascade_frontalface_default.xml") + + +# focal length finder function +def focal_length(measured_distance, real_width, width_in_rf_image): + """ + This Function Calculate the Focal Length(distance between lens to CMOS sensor), it is simple constant we can find by using + MEASURED_DISTACE, REAL_WIDTH(Actual width of object) and WIDTH_OF_OBJECT_IN_IMAGE + :param1 Measure_Distance(int): It is distance measured from object to the Camera while Capturing Reference image + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 14.3 centimeters) + :param3 Width_In_Image(int): It is object width in the frame /image in our case in the reference image(found by Face detector) + :retrun focal_length(Float):""" + focal_length_value = (width_in_rf_image * measured_distance) / real_width + return focal_length_value + + +# distance estimation function +def distance_finder(focal_length, real_face_width, face_width_in_frame): + """ + This Function simply Estimates the distance between object and camera using arguments(focal_length, Actual_object_width, Object_width_in_the_image) + :param1 focal_length(float): return by the focal_length_Finder function + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 object_Width_Frame(int): width of object in the image(frame in our case, using Video feed) + :return Distance(float) : distance Estimated + """ + distance = (real_face_width * focal_length) / face_width_in_frame + return distance + + +# face detector function +def face_data(image): + """ + This function Detect the face + :param Takes image as argument. + :returns face_width in the pixels + """ + + face_width = 0 + gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(gray_image, 1.3, 5) + for (x, y, h, w) in faces: + cv.rectangle(image, (x, y), (x + w, y + h), WHITE, 1) + face_width = w + + return face_width + + +# reading reference image from directory +ref_image = cv.imread("../Ref_image.png") + +ref_image_face_width = face_data(ref_image) +focal_length_found = focal_length(KNOWN_DISTANCE, KNOWN_WIDTH, ref_image_face_width) +print(focal_length_found) +cv.imshow("ref_image", ref_image) +# starting time here +starting_time = time.time() +frame_counter = 0 +while True: + frame_counter += 1 + _, frame = cap.read() + + # calling face_data function + face_width_in_frame = face_data(frame) + # finding the distance by calling function Distance + if face_width_in_frame != 0: + Distance = distance_finder(focal_length_found, KNOWN_WIDTH, face_width_in_frame) + # Drwaing Text on the screen + # cv.putText( + # frame, f"Distance = {round(Distance,2)} CM", (50, 50), fonts, 1, (WHITE), 2) + AiPhile.textBGoutline( + frame, + f"Distance = {round(Distance,2)} CM", + (30, 80), + scaling=0.5, + text_color=AiPhile.YELLOW, + ) + + fps = frame_counter / (time.time() - starting_time) + AiPhile.textBGoutline(frame, f"FPS: {round(fps,2)}", (30, 40), scaling=0.5) + cv.imshow("frame", frame) + if cv.waitKey(1) == ord("q"): + break +cap.release() +cv.destroyAllWindows() diff --git a/Raspberry_pi/pi_camera_Distnace.py b/Raspberry_pi/pi_camera_Distnace.py new file mode 100644 index 0000000..a6dc1fa --- /dev/null +++ b/Raspberry_pi/pi_camera_Distnace.py @@ -0,0 +1,115 @@ +from picamera.array import PiRGBArray +from picamera import PiCamera +import time +import cv2 as cv +import AiPhile + +# variables +# distance from camera to object(face) measured +KNOWN_DISTANCE = 76.2 # centimeter +# width of face in the real world or Object Plane +KNOWN_WIDTH = 14.3 # centimeter + +width, Height = 640, 480 + +# initialize the camera and grab a reference to the raw camera capture +camera = PiCamera() +camera.resolution = (width, Height) +camera.framerate = 10 +rawCapture = PiRGBArray(camera, size=(width, Height)) +# allow the camera to warmup + +# function / Modules +# face detector object +face_detector = cv.CascadeClassifier("../haarcascade_frontalface_default.xml") + + +# focal length finder function +def focal_length(measured_distance, real_width, width_in_rf_image): + """ + This Function Calculate the Focal Length(distance between lens to CMOS sensor), it is simple constant we can find by using + MEASURED_DISTACE, REAL_WIDTH(Actual width of object) and WIDTH_OF_OBJECT_IN_IMAGE + :param1 Measure_Distance(int): It is distance measured from object to the Camera while Capturing Reference image + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 14.3 centimeters) + :param3 Width_In_Image(int): It is object width in the frame /image in our case in the reference image(found by Face detector) + :retrun focal_length(Float):""" + focal_length_value = (width_in_rf_image * measured_distance) / real_width + return focal_length_value + + +# distance estimation function +def distance_finder(focal_length, real_face_width, face_width_in_frame): + """ + This Function simply Estimates the distance between object and camera using arguments(focal_length, Actual_object_width, Object_width_in_the_image) + :param1 focal_length(float): return by the focal_length_Finder function + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 object_Width_Frame(int): width of object in the image(frame in our case, using Video feed) + :return Distance(float) : distance Estimated + """ + distance = (real_face_width * focal_length) / face_width_in_frame + return distance + + +# face detector function +def face_data(image): + """ + This function Detect the face + :param Takes image as argument. + :returns face_width in the pixels + """ + + face_width = 0 + gray_image = cv.cvtColor(image, cv.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(gray_image, 1.3, 5) + for (x, y, h, w) in faces: + cv.rectangle(image, (x, y), (x + w, y + h), WHITE, 1) + face_width = w + + return face_width + + +# reading reference image from directory +ref_image = cv.imread("../Ref_image.png") + +ref_image_face_width = face_data(ref_image) +focal_length_found = focal_length(KNOWN_DISTANCE, KNOWN_WIDTH, ref_image_face_width) +print(focal_length_found) +cv.imshow("ref_image", ref_image) + +time.sleep(0.1) +# starting time here +starting_time = time.time() +frame_counter = 0 +# capture frames from the camera +for image_array in camera.capture_continuous( + rawCapture, format="bgr", use_video_port=True +): + # grab the raw NumPy array representing the image, then initialize the timestamp + # and occupied/unoccupied text + frame = image_array.array + + frame_counter += 1 + # calling face_data function + face_width_in_frame = face_data(frame) + # finding the distance by calling function Distance + if face_width_in_frame != 0: + Distance = distance_finder(focal_length_found, KNOWN_WIDTH, face_width_in_frame) + # Drwaing Text on the screen + # cv.putText( + # frame, f"Distance = {round(Distance,2)} CM", (50, 50), fonts, 1, (WHITE), 2) + AiPhile.textBGoutline( + frame, + f"Distance = {round(Distance,2)} CM", + (30, 80), + scaling=0.5, + text_color=AiPhile.YELLOW, + ) + + fps = frame_counter / (time.time() - starting_time) + AiPhile.textBGoutline(frame, f"FPS: {round(fps,2)}", (30, 40), scaling=0.5) + cv.imshow("frame", frame) + if cv.waitKey(1) == ord("q"): + break +cv.destroyAllWindows() diff --git a/Speed/.gitignore b/Speed/.gitignore new file mode 100644 index 0000000..a53d962 --- /dev/null +++ b/Speed/.gitignore @@ -0,0 +1 @@ +*.mp4 \ No newline at end of file diff --git a/Speed/README.md b/Speed/README.md new file mode 100644 index 0000000..f2045c9 --- /dev/null +++ b/Speed/README.md @@ -0,0 +1,19 @@ +# Finding Speed using Distance Estimation. + +![GitHub Repo stars](https://img.shields.io/github/stars/Asadullah-Dal17/Distance_measurement_using_single_camera?style=social) ![GitHub forks](https://img.shields.io/github/forks/Asadullah-Dal17/Distance_measurement_using_single_camera?style=social) ![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UCc8Lx22a5OX4XMxrCykzjbA?style=social) + +## Distance & Speed Estimation Demo + +https://user-images.githubusercontent.com/66181793/122644855-bb8ac000-d130-11eb-85c3-c7ff4bd6474c.mp4 + +#### [Youtube Tutorial](https://youtu.be/DIxcLghsQ4Q) ![YouTube Video Views](https://img.shields.io/youtube/views/DIxcLghsQ4Q?style=social) + +## TODO + +- [x] Find Speed +- [x] Give it more frame to show, so it looks legible or convert the units +- [x] Youtube Tutorial: [here](https://youtu.be/DIxcLghsQ4Q) (Youtube) + +#### if you want make contribution please go a head. + +if any one has test this know better ways to do this please let me, or make pull request, it will be appreciated thank you. diff --git a/Speed/speed.py b/Speed/speed.py new file mode 100644 index 0000000..7f75b38 --- /dev/null +++ b/Speed/speed.py @@ -0,0 +1,188 @@ + +''' +------------------------------------------- +- Author: Asadullah Dal - +- ============================= - +- Company Name: AiPhile - +- ============================= - +- Purpose : Youtube Channel - +- ============================ - +- Link: https://youtube.com/c/aiphile - +------------------------------------------- +''' + +import cv2 +import time +# variables +initialTime = 0 +initialDistance = 0 +changeInTime = 0 +changeInDistance = 0 + +listDistance = [] +listSpeed = [] + +# distance from camera to object(face) measured +Known_distance = 76.2 # centimeter +# width of face in the real world or Object Plane +Known_width = 14.3 # centimeter +# Colors +GREEN = (0, 255, 0) +RED = (0, 0, 255) +WHITE = (255, 255, 255) +fonts = cv2.FONT_HERSHEY_COMPLEX +cap = cv2.VideoCapture(0) + +# cap.set(3, 640) +# cap.set(4, 480) + +# Define the codec and create VideoWriter object +fourcc = cv2.VideoWriter_fourcc(*'XVID') +Recorder = cv2.VideoWriter('distanceAndSpeed2.mp4', fourcc, 15.0, (640, 480)) +# face detector object +face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") +# focal length finder function + + +def FocalLength(measured_distance, real_width, width_in_rf_image): + ''' +This Function Calculate the Focal Length(distance between lens to CMOS sensor), it is simple constant we can find by using +MEASURED_DISTACE, REAL_WIDTH(Actual width of object) and WIDTH_OF_OBJECT_IN_IMAGE +:param1 Measure_Distance(int): It is distance measured from object to the Camera while Capturing Reference image + +:param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 14.3 centimeters) +:param3 Width_In_Image(int): It is object width in the frame /image in our case in the reference image(found by Face detector) +:retrun Focal_Length(Float): +''' + focal_length = (width_in_rf_image * measured_distance) / real_width + return focal_length +# distance estimation function + + +def Distance_finder(Focal_Length, real_face_width, face_width_in_frame): + ''' +This Function simply Estimates the distance between object and camera using arguments(Focal_Length, Actual_object_width, Object_width_in_the_image) +:param1 Focal_length(float): return by the Focal_Length_Finder function + +:param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) +:param3 object_Width_Frame(int): width of object in the image(frame in our case, using Video feed) +:return Distance(float) : distance Estimated + +''' + distance = (real_face_width * Focal_Length)/face_width_in_frame + return distance + + +def face_data(image): + ''' + This function Detect the face + :param Takes image as argument. + :returns face_width in the pixels + ''' + + face_width = 0 + gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(gray_image, 1.3, 5) + for (x, y, h, w) in faces: + cv2.rectangle(image, (x, y), (x+w, y+h), WHITE, 1) + face_width = w + + return face_width + + +def speedFinder(coveredDistance, timeTaken): + + speed = coveredDistance / timeTaken + + return speed + + +def averageFinder(completeList, averageOfItems): + + # finding the length of list. + lengthOfList = len(completeList) + + # calculating the number items to find the average of + selectedItems = lengthOfList - averageOfItems + # 10 -6 =4 + + # getting the list most recent items of list to find average of . + selectedItemsList = completeList[selectedItems:] + + # finding the average . + average = sum(selectedItemsList) / len(selectedItemsList) + + return average + + +# reading reference image from directory +ref_image = cv2.imread("Ref_image.png") + +ref_image_face_width = face_data(ref_image) +Focal_length_found = FocalLength( + Known_distance, Known_width, ref_image_face_width) +print(Focal_length_found) +# cv2.imshow("ref_image", ref_image) + +while True: + _, frame = cap.read() + + # calling face_data function + face_width_in_frame = face_data(frame) + # finding the distance by calling function Distance + if face_width_in_frame != 0: + Distance = Distance_finder( + Focal_length_found, Known_width, face_width_in_frame) + listDistance.append(Distance) + averageDistance = averageFinder(listDistance, 2) + + # converting centimeters into meters + distanceInMeters = averageDistance/100 + + if initialDistance != 0: + # finding the change in distance + changeInDistance = initialDistance - distanceInMeters + + # if changeInDistance < 0: + # changeInDistance * -1 + # finding change in time + changeInTime = time.time() - initialTime + + # finding the sped + speed = speedFinder( + coveredDistance=changeInDistance, timeTaken=changeInTime) + listSpeed.append(speed) + averageSpeed = averageFinder(listSpeed, 10) + if averageSpeed < 0: + averageSpeed = averageSpeed * -1 + # filling the progressive line dependent on the speed. + speedFill = int(45+(averageSpeed) * 130) + if speedFill > 235: + speedFill = 235 + cv2.line(frame, (45, 70), (235, 70), (0, 255, 0), 35) + # speed dependent line + cv2.line(frame, (45, 70), (speedFill, 70), (255, 255, 0), 32) + cv2.line(frame, (45, 70), (235, 70), (0, 0, 0), 22) + # print() + cv2.putText( + frame, f"Speed: {round(averageSpeed, 2)} m/s", (50, 75), fonts, 0.6, (0, 255, 220), 2) + + # print(speed) + + # inital distance and time + initialDistance = distanceInMeters + initialTime = time.time() + + # Drwaing Text on the screen + cv2.line(frame, (45, 25), (255, 25), (255, 0, 255), 30) + cv2.line(frame, (45, 25), (255, 25), (0, 0, 0), 22) + cv2.putText( + frame, f"Distance = {round(distanceInMeters,2)} m", (50, 30), fonts, 0.6, WHITE, 2) + # recording the video + Recorder.write(frame) + cv2.imshow("frame", frame) + if cv2.waitKey(1) == ord("q"): + break +cap.release() +Recorder.release() +cv2.destroyAllWindows() diff --git a/Speed/updated_speed.py b/Speed/updated_speed.py new file mode 100644 index 0000000..3b1e219 --- /dev/null +++ b/Speed/updated_speed.py @@ -0,0 +1,219 @@ +import cv2 +import time + +# variables +# distance from camera to object(face) measured +Known_distance = 30 # Inches +# mine is 14.3 something, measure your face width, are google it +Known_width = 5.7 # Inches + +# Colors >>> BGR Format(BLUE, GREEN, RED) +GREEN = (0, 255, 0) +RED = (0, 0, 255) +BLACK = (0, 0, 0) +YELLOW = (0, 255, 255) +WHITE = (255, 255, 255) +CYAN = (255, 255, 0) +MAGENTA = (255, 0, 242) +GOLDEN = (32, 218, 165) +LIGHT_BLUE = (255, 9, 2) +PURPLE = (128, 0, 128) +CHOCOLATE = (30, 105, 210) +PINK = (147, 20, 255) +ORANGE = (0, 69, 255) + +fonts = cv2.FONT_HERSHEY_COMPLEX +fonts2 = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX +fonts3 = cv2.FONT_HERSHEY_COMPLEX_SMALL +fonts4 = cv2.FONT_HERSHEY_TRIPLEX +# Camera Object +capID = 0 +cap = cv2.VideoCapture(capID) # Number According to your Camera +Distance_level = 0 +travedDistance = 0 +changeDistance = 0 +velocity = 0 + +# Define the codec and create VideoWriter object +fourcc = cv2.VideoWriter_fourcc(*'XVID') +out = cv2.VideoWriter('output21.mp4', fourcc, 30.0, (640, 480)) + +# face detector object +face_detector = cv2.CascadeClassifier("../haarcascade_frontalface_default.xml") +# focal length finder function + + +def FocalLength(measured_distance, real_width, width_in_rf_image): + # Function Discrption (Doc String) + ''' + This Function Calculate the Focal Length(distance between lens to CMOS sensor), it is simple constant we can find by using + MEASURED_DISTACE, REAL_WIDTH(Actual width of object) and WIDTH_OF_OBJECT_IN_IMAGE + :param1 Measure_Distance(int): It is distance measured from object to the Camera while Capturing Reference image + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 Width_In_Image(int): It is object width in the frame /image in our case in the reference image(found by Face detector) + :retrun Focal_Length(Float): + ''' + focal_length = (width_in_rf_image * measured_distance) / real_width + return focal_length +# distance estimation function + + +def Distance_finder(Focal_Length, real_face_width, face_width_in_frame): + ''' + This Function simply Estimates the distance between object and camera using arguments(Focal_Length, Actual_object_width, Object_width_in_the_image) + :param1 Focal_length(float): return by the Focal_Length_Finder function + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 object_Width_Frame(int): width of object in the image(frame in our case, using Video feed) + :return Distance(float) : distance Estimated + + ''' + distance = (real_face_width * Focal_Length)/face_width_in_frame + return distance + + +def speedFinder(distance, takenTime): + speed = distance/takenTime + return speed + + +# face detection Fauction + +def face_data(image, CallOut, Distance_level): + ''' + + This function Detect face and Draw Rectangle and display the distance over Screen + + :param1 Image(Mat): simply the frame + :param2 Call_Out(bool): If want show Distance and Rectangle on the Screen or not + :param3 Distance_Level(int): which change the line according the Distance changes(Intractivate) + :return1 face_width(int): it is width of face in the frame which allow us to calculate the distance and find focal length + :return2 face(list): length of face and (face paramters) + :return3 face_center_x: face centroid_x coordinate(x) + :return4 face_center_y: face centroid_y coordinate(y) + + ''' + + face_width = 0 + face_x, face_y = 0, 0 + face_center_x = 0 + face_center_y = 0 + gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(gray_image, 1.3, 5) + for (x, y, h, w) in faces: + line_thickness = 2 + # print(len(faces)) + LLV = int(h*0.12) + # print(LLV) + + # cv2.rectangle(image, (x, y), (x+w, y+h), BLACK, 1) + cv2.line(image, (x, y+LLV), (x+w, y+LLV), (GREEN), line_thickness) + cv2.line(image, (x, y+h), (x+w, y+h), (GREEN), line_thickness) + cv2.line(image, (x, y+LLV), (x, y+LLV+LLV), (GREEN), line_thickness) + cv2.line(image, (x+w, y+LLV), (x+w, y+LLV+LLV), + (GREEN), line_thickness) + cv2.line(image, (x, y+h), (x, y+h-LLV), (GREEN), line_thickness) + cv2.line(image, (x+w, y+h), (x+w, y+h-LLV), (GREEN), line_thickness) + + face_width = w + face_center = [] + # Drwaing circle at the center of the face + face_center_x = int(w/2)+x + face_center_y = int(h/2)+y + if Distance_level < 10: + Distance_level = 10 + + # cv2.circle(image, (face_center_x, face_center_y),5, (255,0,255), 3 ) + if CallOut == True: + # cv2.line(image, (x,y), (face_center_x,face_center_y ), (155,155,155),1) + cv2.line(image, (x, y-11), (x+180, y-11), (ORANGE), 28) + cv2.line(image, (x, y-11), (x+180, y-11), (YELLOW), 20) + cv2.line(image, (x, y-11), (x+Distance_level, y-11), (GREEN), 18) + + # cv2.circle(image, (face_center_x, face_center_y),2, (255,0,255), 1 ) + # cv2.circle(image, (x, y),2, (255,0,255), 1 ) + + # face_x = x + # face_y = y + + return face_width, faces, face_center_x, face_center_y + + +def averageFinder(valuesList, numberElements): + sizeOfList = len(valuesList) + lastMostElement = sizeOfList - numberElements + lastPart = valuesList[lastMostElement:] + average = sum(lastPart)/(len(lastPart)) + return average + + +# reading reference image from directory +ref_image = cv2.imread("../Ref_image.png") + +ref_image_face_width, _, _, _ = face_data(ref_image, False, Distance_level) +Focal_length_found = FocalLength( + Known_distance, Known_width, ref_image_face_width) +print(Focal_length_found) + +cv2.imshow("ref_image", ref_image) +speedList = [] +DistanceList = [] +averageSpeed = 0 +intialDisntace = 0 + +while True: + _, frame = cap.read() + # calling face_data function + # Distance_leve =0 + intialTime = time.time() + face_width_in_frame, Faces, FC_X, FC_Y = face_data( + frame, True, Distance_level) + # finding the distance by calling function Distance finder + for (face_x, face_y, face_w, face_h) in Faces: + if face_width_in_frame != 0: + + Distance = Distance_finder( + Focal_length_found, Known_width, face_width_in_frame) + DistanceList.append(Distance) + avergDistnce = averageFinder(DistanceList, 6) + # print(avergDistnce) + roundedDistance = round((avergDistnce*0.0254), 2) + # Drwaing Text on the screen + Distance_level = int(Distance) + if intialDisntace != 0: + + changeDistance = Distance - intialDisntace + distanceInMeters = changeDistance * 0.0254 + + velocity = speedFinder(distanceInMeters, changeInTime) + + speedList.append(velocity) + + averageSpeed = averageFinder(speedList, 6) + # intial Distance + intialDisntace = avergDistnce + + changeInTime = time.time() - intialTime + # print(changeInTime) + + cv2.line(frame, (25, 45), (180, 45), (ORANGE), 26) + cv2.line(frame, (25, 45), (180, 45), (GREEN), 20) + # cv2.line(image, (x, y-11), (x+180, y-11), (YELLOW), 20) + # cv2.line(image, (x, y-11), (x+Distance_level, y-11), (GREEN), 18) + if averageSpeed < 0: + averageSpeed = averageSpeed * -1 + cv2.putText( + frame, f"Speed: {round(averageSpeed,2)} m/s", (30, 50), fonts, 0.5, BLACK, 2) + + cv2.putText(frame, f"Distance {roundedDistance} meter", + (face_x-6, face_y-6), fonts, 0.5, (BLACK), 2) + cv2.imshow("frame", frame) + out.write(frame) + + if cv2.waitKey(1) == ord("q"): + break + +cap.release() +# out.release() +cv2.destroyAllWindows() diff --git a/Updated_distance.py b/Updated_distance.py new file mode 100644 index 0000000..b5b5309 --- /dev/null +++ b/Updated_distance.py @@ -0,0 +1,180 @@ +import cv2 + +# variables +# distance from camera to object(face) measured +Known_distance = 30 # Inches +# mine is 14.3 something, measure your face width, are google it +Known_width = 5.7 # Inches + +# Colors >>> BGR Format(BLUE, GREEN, RED) +GREEN = (0, 255, 0) +RED = (0, 0, 255) +BLACK = (0, 0, 0) +YELLOW = (0, 255, 255) +WHITE = (255, 255, 255) +CYAN = (255, 255, 0) +MAGENTA = (255, 0, 242) +GOLDEN = (32, 218, 165) +LIGHT_BLUE = (255, 9, 2) +PURPLE = (128, 0, 128) +CHOCOLATE = (30, 105, 210) +PINK = (147, 20, 255) +ORANGE = (0, 69, 255) + +fonts = cv2.FONT_HERSHEY_COMPLEX +fonts2 = cv2.FONT_HERSHEY_SCRIPT_SIMPLEX +fonts3 = cv2.FONT_HERSHEY_COMPLEX_SMALL +fonts4 = cv2.FONT_HERSHEY_TRIPLEX +# Camera Object +cap = cv2.VideoCapture(0) # Number According to your Camera +Distance_level = 0 + +# Define the codec and create VideoWriter object +fourcc = cv2.VideoWriter_fourcc(*"XVID") +out = cv2.VideoWriter("output21.mp4", fourcc, 30.0, (640, 480)) + +# face detector object +face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") +# focal length finder function + + +def FocalLength(measured_distance, real_width, width_in_rf_image): + # Function Discrption (Doc String) + """ + This Function Calculate the Focal Length(distance between lens to CMOS sensor), it is simple constant we can find by using + MEASURED_DISTACE, REAL_WIDTH(Actual width of object) and WIDTH_OF_OBJECT_IN_IMAGE + :param1 Measure_Distance(int): It is distance measured from object to the Camera while Capturing Reference image + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 Width_In_Image(int): It is object width in the frame /image in our case in the reference image(found by Face detector) + :retrun Focal_Length(Float): + """ + focal_length = (width_in_rf_image * measured_distance) / real_width + return focal_length + + +# distance estimation function + + +def Distance_finder(Focal_Length, real_face_width, face_width_in_frame): + """ + This Function simply Estimates the distance between object and camera using arguments(Focal_Length, Actual_object_width, Object_width_in_the_image) + :param1 Focal_length(float): return by the Focal_Length_Finder function + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 object_Width_Frame(int): width of object in the image(frame in our case, using Video feed) + :return Distance(float) : distance Estimated + + """ + distance = (real_face_width * Focal_Length) / face_width_in_frame + return distance + + +# face detection Fauction + + +def face_data(image, CallOut, Distance_level): + """ + + This function Detect face and Draw Rectangle and display the distance over Screen + + :param1 Image(Mat): simply the frame + :param2 Call_Out(bool): If want show Distance and Rectangle on the Screen or not + :param3 Distance_Level(int): which change the line according the Distance changes(Intractivate) + :return1 face_width(int): it is width of face in the frame which allow us to calculate the distance and find focal length + :return2 face(list): length of face and (face paramters) + :return3 face_center_x: face centroid_x coordinate(x) + :return4 face_center_y: face centroid_y coordinate(y) + + """ + + face_width = 0 + face_x, face_y = 0, 0 + face_center_x = 0 + face_center_y = 0 + gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(gray_image, 1.3, 5) + for (x, y, w, h) in faces: + line_thickness = 2 + # print(len(faces)) + LLV = int(h * 0.12) + # print(LLV) + + # cv2.rectangle(image, (x, y), (x+w, y+h), BLACK, 1) + cv2.line(image, (x, y + LLV), (x + w, y + LLV), (GREEN), line_thickness) + cv2.line(image, (x, y + h), (x + w, y + h), (GREEN), line_thickness) + cv2.line(image, (x, y + LLV), (x, y + LLV + LLV), (GREEN), line_thickness) + cv2.line( + image, (x + w, y + LLV), (x + w, y + LLV + LLV), (GREEN), line_thickness + ) + cv2.line(image, (x, y + h), (x, y + h - LLV), (GREEN), line_thickness) + cv2.line(image, (x + w, y + h), (x + w, y + h - LLV), (GREEN), line_thickness) + + face_width = w + face_center = [] + # Drwaing circle at the center of the face + face_center_x = int(w / 2) + x + face_center_y = int(h / 2) + y + if Distance_level < 10: + Distance_level = 10 + + # cv2.circle(image, (face_center_x, face_center_y),5, (255,0,255), 3 ) + if CallOut == True: + # cv2.line(image, (x,y), (face_center_x,face_center_y ), (155,155,155),1) + cv2.line(image, (x, y - 11), (x + 180, y - 11), (ORANGE), 28) + cv2.line(image, (x, y - 11), (x + 180, y - 11), (YELLOW), 20) + cv2.line(image, (x, y - 11), (x + Distance_level, y - 11), (GREEN), 18) + + # cv2.circle(image, (face_center_x, face_center_y),2, (255,0,255), 1 ) + # cv2.circle(image, (x, y),2, (255,0,255), 1 ) + + # face_x = x + # face_y = y + + return face_width, faces, face_center_x, face_center_y + + +# reading reference image from directory +ref_image = cv2.imread("Ref_image.png") + +ref_image_face_width, _, _, _ = face_data(ref_image, False, Distance_level) +Focal_length_found = FocalLength(Known_distance, Known_width, ref_image_face_width) +print(Focal_length_found) + +cv2.imshow("ref_image", ref_image) + +while True: + _, frame = cap.read() + # calling face_data function + # Distance_leve =0 + + face_width_in_frame, Faces, FC_X, FC_Y = face_data(frame, True, Distance_level) + # finding the distance by calling function Distance finder + for (face_x, face_y, face_w, face_h) in Faces: + if face_width_in_frame != 0: + + Distance = Distance_finder( + Focal_length_found, Known_width, face_width_in_frame + ) + Distance = round(Distance, 2) + # Drwaing Text on the screen + Distance_level = int(Distance) + + cv2.putText( + frame, + f"Distance {Distance} Inches", + (face_x - 6, face_y - 6), + fonts, + 0.5, + (BLACK), + 2, + ) + cv2.imshow("frame", frame) + out.write(frame) + + if cv2.waitKey(1) == ord("q"): + break + +cap.release() +# out.release() +cv2.destroyAllWindows() diff --git a/distance.py b/distance.py index d7e4247..e68bd64 100644 --- a/distance.py +++ b/distance.py @@ -1,56 +1,101 @@ -import cv2 -# variables -# distance from camera to object(face) measured -Known_distance = 30 #centimeter -# width of face in the real world or Object Plane -Known_width =14.3 -# Colors -GREEN = (0,255,0) -RED = (0,0,255) -WHITE = (255,255,255) -fonts = cv2.FONT_HERSHEY_COMPLEX -cap = cv2.VideoCapture(1) -# face detector object -face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") -# focal length finder function -def FocalLength(measured_distance, real_width, width_in_rf_image): - focal_length = (width_in_rf_image* measured_distance)/ real_width - return focal_length -# distance estimation function -def Distance_finder (Focal_Length, real_face_width, face_width_in_frame): - distance = (real_face_width * Focal_Length)/face_width_in_frame - return distance - -def face_data(image): - face_width = 0 - gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) - faces = face_detector.detectMultiScale(gray_image, 1.3, 5) - for (x, y, h, w) in faces: - cv2.rectangle(image, (x, y), (x+w, y+h), WHITE, 1) - face_width = w - - return face_width - -# reading reference image from directory -ref_image = cv2.imread("Ref_image.png") - -ref_image_face_width = face_data(ref_image) -Focal_length_found = FocalLength(Known_distance, Known_width, ref_image_face_width) -print(Focal_length_found) -cv2.imshow("ref_image", ref_image) - -while True: - _, frame = cap.read() - - # calling face_data function - face_width_in_frame = face_data(frame) - # finding the distance by calling function Distance finder - if face_width_in_frame !=0: - Distance = Distance_finder(Focal_length_found, Known_width,face_width_in_frame) - # Drwaing Text on the screen - cv2.putText(frame, f"Distance = {Distance}", (50,50), fonts,1, (WHITE),2) - cv2.imshow("frame", frame ) - if cv2.waitKey(1)==ord("q"): - break -cap.release() -cv2.destroyAllWindows() +""" +------------------------------------------- +- Author: Asadullah Dal - +- ============================= - +- Company Name: AiPhile - +- ============================= - +- Purpose : Youtube Channel - +- ============================ - +- Link: https://youtube.com/c/aiphile - +------------------------------------------- +""" + +import cv2 + +# variables +# distance from camera to object(face) measured +KNOWN_DISTANCE = 76.2 # centimeter +# width of face in the real world or Object Plane +KNOWN_WIDTH = 14.3 # centimeter +# Colors +GREEN = (0, 255, 0) +RED = (0, 0, 255) +WHITE = (255, 255, 255) +fonts = cv2.FONT_HERSHEY_COMPLEX +cap = cv2.VideoCapture(1) + +# face detector object +face_detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml") + + +# focal length finder function +def focal_length(measured_distance, real_width, width_in_rf_image): + """ + This Function Calculate the Focal Length(distance between lens to CMOS sensor), it is simple constant we can find by using + MEASURED_DISTACE, REAL_WIDTH(Actual width of object) and WIDTH_OF_OBJECT_IN_IMAGE + :param1 Measure_Distance(int): It is distance measured from object to the Camera while Capturing Reference image + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 14.3 centimeters) + :param3 Width_In_Image(int): It is object width in the frame /image in our case in the reference image(found by Face detector) + :retrun focal_length(Float):""" + focal_length_value = (width_in_rf_image * measured_distance) / real_width + return focal_length_value + + +# distance estimation function +def distance_finder(focal_length, real_face_width, face_width_in_frame): + """ + This Function simply Estimates the distance between object and camera using arguments(focal_length, Actual_object_width, Object_width_in_the_image) + :param1 focal_length(float): return by the focal_length_Finder function + + :param2 Real_Width(int): It is Actual width of object, in real world (like My face width is = 5.7 Inches) + :param3 object_Width_Frame(int): width of object in the image(frame in our case, using Video feed) + :return Distance(float) : distance Estimated + """ + distance = (real_face_width * focal_length) / face_width_in_frame + return distance + + +# face detector function +def face_data(image): + """ + This function Detect the face + :param Takes image as argument. + :returns face_width in the pixels + """ + + face_width = 0 + gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) + faces = face_detector.detectMultiScale(gray_image, 1.3, 5) + for (x, y, h, w) in faces: + cv2.rectangle(image, (x, y), (x + w, y + h), WHITE, 1) + face_width = w + + return face_width + + +# reading reference image from directory +ref_image = cv2.imread("Ref_image.png") + +ref_image_face_width = face_data(ref_image) +focal_length_found = focal_length(KNOWN_DISTANCE, KNOWN_WIDTH, ref_image_face_width) +print(focal_length_found) +cv2.imshow("ref_image", ref_image) + +while True: + _, frame = cap.read() + + # calling face_data function + face_width_in_frame = face_data(frame) + # finding the distance by calling function Distance + if face_width_in_frame != 0: + Distance = distance_finder(focal_length_found, KNOWN_WIDTH, face_width_in_frame) + # Drwaing Text on the screen + cv2.putText( + frame, f"Distance = {round(Distance,2)} CM", (50, 50), fonts, 1, (WHITE), 2 + ) + cv2.imshow("frame", frame) + if cv2.waitKey(1) == ord("q"): + break +cap.release() +cv2.destroyAllWindows() diff --git a/icons/facebook-icon.svg b/icons/facebook-icon.svg new file mode 100644 index 0000000..7e6fd47 --- /dev/null +++ b/icons/facebook-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/github-icon.svg b/icons/github-icon.svg new file mode 100644 index 0000000..0adb502 --- /dev/null +++ b/icons/github-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/instagram-icon.svg b/icons/instagram-icon.svg new file mode 100644 index 0000000..04b9097 --- /dev/null +++ b/icons/instagram-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/linkedin-icon.svg b/icons/linkedin-icon.svg new file mode 100644 index 0000000..f461f9e --- /dev/null +++ b/icons/linkedin-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/icons/youtub-icon.svg b/icons/youtub-icon.svg new file mode 100644 index 0000000..959dced --- /dev/null +++ b/icons/youtub-icon.svg @@ -0,0 +1 @@ + \ No newline at end of file