├── Codes ├── ColorSpaceVideo.py └── RobotCode.py ├── Images&Videos ├── Circuit Diagram.png ├── Code Snippets │ ├── DriveFunction.png │ ├── GPIO-Config.png │ ├── Main.png │ ├── driving-functions.png │ └── libraries.png ├── FrontView.jpeg ├── Open-cv.png ├── Parts.jpeg ├── Python3.jpg ├── Rpi.jpg └── SideView.jpeg ├── LICENSE └── README.md /Codes/ColorSpaceVideo.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | 4 | def nothing(pos): 5 | pass 6 | 7 | device = cv2.VideoCapture(1) 8 | 9 | cv2.namedWindow('ColorSpace') 10 | 11 | cv2.createTrackbar('lh','ColorSpace',0,179,nothing) 12 | cv2.createTrackbar('ls','ColorSpace',0,255,nothing) 13 | cv2.createTrackbar('lv','ColorSpace',0,255,nothing) 14 | 15 | cv2.createTrackbar('hh','ColorSpace',0,179,nothing) 16 | cv2.createTrackbar('hs','ColorSpace',0,255,nothing) 17 | cv2.createTrackbar('hv','ColorSpace',0,255,nothing) 18 | 19 | while(True): 20 | 21 | ret, frame = device.read() 22 | frame = cv2.flip(frame,1) 23 | 24 | newFrame = cv2.cvtColor(frame,cv2.COLOR_BGR2HSV) 25 | 26 | lh = cv2.getTrackbarPos('lh','ColorSpace') 27 | ls = cv2.getTrackbarPos('ls','ColorSpace') 28 | lv = cv2.getTrackbarPos('lv','ColorSpace') 29 | 30 | hh = cv2.getTrackbarPos('hh','ColorSpace') 31 | hs = cv2.getTrackbarPos('hs','ColorSpace') 32 | hv = cv2.getTrackbarPos('hv','ColorSpace') 33 | 34 | lower_blue = np.array([lh,ls,lv]) 35 | high_blue = np.array([hh,hs,hv]) 36 | 37 | mask = cv2.inRange(newFrame,lower_blue,high_blue) 38 | result = cv2.bitwise_and(frame,frame,mask=mask) 39 | 40 | cv2.imshow('ColorSpace',frame) 41 | cv2.imshow('Result',result) 42 | 43 | if cv2.waitKey(1) & 0xFF == ord('q'): 44 | break 45 | 46 | device.release() 47 | cv2.destroyAllWindows() -------------------------------------------------------------------------------- /Codes/RobotCode.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import numpy as np 3 | import RPi.GPIO as GPIO 4 | import imutils 5 | from imutils.video import WebcamVideoStream 6 | from _thread import * 7 | import time 8 | 9 | 10 | GPIO.setmode(GPIO.BCM) 11 | GPIO.setwarnings(False) 12 | L_Forward=19 13 | L_Backward=13 14 | R_Forward=5 15 | R_Backward=6 16 | 17 | GPIO.setup(L_Forward, GPIO.OUT) 18 | GPIO.setup(L_Backward, GPIO.OUT) 19 | GPIO.setup(R_Forward, GPIO.OUT) 20 | GPIO.setup(R_Backward, GPIO.OUT) 21 | 22 | 23 | def stopMotor(): 24 | GPIO.output(L_Backward,False) 25 | GPIO.output(R_Backward,False) 26 | GPIO.output(L_Forward,False) 27 | GPIO.output(R_Forward,False) 28 | 29 | 30 | def right(): 31 | GPIO.output(L_Forward,True) 32 | GPIO.output(L_Backward,False) 33 | GPIO.output(R_Forward,False) 34 | GPIO.output(R_Backward,True) 35 | 36 | 37 | def left(): 38 | GPIO.output(L_Forward,False) 39 | GPIO.output(L_Backward,True) 40 | GPIO.output(R_Forward,True) 41 | GPIO.output(R_Backward,False) 42 | 43 | 44 | def forward(): 45 | GPIO.output(L_Forward,True) 46 | GPIO.output(R_Forward,True) 47 | 48 | 49 | def backward(): 50 | GPIO.output(L_Backward,True) 51 | GPIO.output(R_Backward,True) 52 | 53 | 54 | def drive(): 55 | global cx,fw,w,h,minArea,maxArea,flag,lock 56 | while not threadStop: 57 | if flag==1 and lock: 58 | if cx > 3*fw/4: 59 | #print("Right") 60 | right() 61 | time.sleep(0.015) 62 | elif cx < fw/4: 63 | #print("Left") 64 | left() 65 | time.sleep(0.015) 66 | elif w*h > maxArea: 67 | #print("Back") 68 | backward() 69 | time.sleep(0.025) 70 | elif w*h < minArea: 71 | #print("Forward") 72 | forward() 73 | time.sleep(0.025) 74 | 75 | stopMotor() 76 | time.sleep(0.0125) 77 | 78 | else: 79 | #print("Stop") 80 | stopMotor() 81 | GPIO.cleanup() 82 | 83 | 84 | 85 | if __name__ == "__main__": 86 | 87 | global cx,w,h,flag,minArea,maxArea,lock,fw,threadStop 88 | threadStop = False #To terminate the thread which drives the robot whenever the user quits 89 | 90 | lock = False #To lock the object 91 | 92 | flag = 0 #Its 1 whenever the object is detected 93 | 94 | #Range of the colors to detect an Object in this range 95 | lower_thresh = np.array([22, 56, 58]) 96 | high_thresh = np.array([61, 223, 255]) 97 | 98 | #To stream the video from the webcam 99 | device = WebcamVideoStream(src=0).start() 100 | 101 | first = True 102 | start_new_thread(drive,()) #Thread to drive the robot 103 | 104 | while True: 105 | frame = device.read() #It reads frames from the video 106 | #_, frame = device.read() 107 | #frame = cv2.flip(frame,1) 108 | 109 | #Pre-processing of the frame to detect the object 110 | blurred = cv2.GaussianBlur(frame, (11, 11), 0) 111 | hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV) 112 | 113 | mask = cv2.inRange(hsv, lower_thresh, high_thresh) 114 | mask = cv2.erode(mask, None, iterations=2) 115 | mask = cv2.dilate(mask, None, iterations=2) 116 | 117 | cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 118 | cnts = imutils.grab_contours(cnts) 119 | 120 | fh,fw,_ = frame.shape 121 | #cv2.rectangle(frame,(int(fw/5),0),(int(4*fw/5),fh),(0,0,255),3) 122 | cv2.rectangle(frame,(int(fw/4),0),(int(3*fw/4),fh),(0,255,255),3) 123 | 124 | #It draws rectangle around the object and finds its centre co-ordinates 125 | if len(cnts)>0: 126 | flag = 1 127 | c = max(cnts, key=cv2.contourArea) 128 | x,y,w,h = cv2.boundingRect(c) 129 | cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2) 130 | M = cv2.moments(c) 131 | cx = int(M['m10']/M['m00']) 132 | cy = int(M['m01']/M['m00']) 133 | #cv2.circle(frame,(cx,cy),3,(0,255,255),-1) 134 | 135 | if first: 136 | #print("Area = ",w*h) 137 | #exit(0) 138 | maxArea = 3*w*h/2 139 | minArea = w*h/2 140 | 141 | else: 142 | flag = 0 143 | 144 | 145 | 146 | cv2.imshow("Frame",frame) 147 | #cv2.imshow("Mask", mask) 148 | 149 | k = cv2.waitKey(1) & 0xFF 150 | 151 | if k == ord('q'): 152 | threadStop = True 153 | break 154 | elif k == ord('l') and flag==1: 155 | print("Locked") 156 | print("Fw = ",fw) 157 | print("Fh = ",fh) 158 | first = False 159 | lock = True 160 | 161 | #device.release() 162 | device.stop() 163 | cv2.destroyAllWindows() 164 | -------------------------------------------------------------------------------- /Images&Videos/Circuit Diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Circuit Diagram.png -------------------------------------------------------------------------------- /Images&Videos/Code Snippets/DriveFunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Code Snippets/DriveFunction.png -------------------------------------------------------------------------------- /Images&Videos/Code Snippets/GPIO-Config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Code Snippets/GPIO-Config.png -------------------------------------------------------------------------------- /Images&Videos/Code Snippets/Main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Code Snippets/Main.png -------------------------------------------------------------------------------- /Images&Videos/Code Snippets/driving-functions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Code Snippets/driving-functions.png -------------------------------------------------------------------------------- /Images&Videos/Code Snippets/libraries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Code Snippets/libraries.png -------------------------------------------------------------------------------- /Images&Videos/FrontView.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/FrontView.jpeg -------------------------------------------------------------------------------- /Images&Videos/Open-cv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Open-cv.png -------------------------------------------------------------------------------- /Images&Videos/Parts.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Parts.jpeg -------------------------------------------------------------------------------- /Images&Videos/Python3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Python3.jpg -------------------------------------------------------------------------------- /Images&Videos/Rpi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/Rpi.jpg -------------------------------------------------------------------------------- /Images&Videos/SideView.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/memr5/Object-Following-Robot/84924f3878705e1d18a89706af470bf01cda23fd/Images&Videos/SideView.jpeg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Meet Ranoliya 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Object-Following-Robot 2 | 3 | It uses **Raspberry pi** + **Motor driver** + **Web Camera** + **OpenCV** to follow an object 4 | It uses **openCV** to detect the object and according to the movement of that object the program drives the robot 5 | **Raspberry-pi** is used to do processing 6 | 7 | ## Tools and Technologies used 8 | 9 | ![raspberry-pi](https://img.shields.io/badge/RPi-raspberry%20pi%203-red)| ![opencv](https://img.shields.io/badge/CV-Open--CV-green)|![python](https://img.shields.io/badge/Py-Python3-blue) 10 | :-------------------------:|:-------------------------:|:-------------------------: 11 | 12 | ## Circuit Diagram 13 | 14 | ![Circuit-Diagram](https://github.com/memr5/Object-Following-Robot/blob/master/Images%26Videos/Circuit%20Diagram.png) 15 | 16 | ## Images 17 | 18 | Front view | Side view 19 | :-------------------------:|:-------------------------: 20 | ![Front](https://github.com/memr5/Object-Following-Robot/blob/master/Images%26Videos/FrontView.jpeg) | ![Side](https://github.com/memr5/Object-Following-Robot/blob/master/Images%26Videos/SideView.jpeg) 21 | 22 | ## Contributers 23 | 24 | * [Meet Ranoliya](https://github.com/memr5) 25 | * [Vatsal Parsaniya](https://github.com/Vatsalparsaniya) 26 | * [Darshit Vachhani](https://github.com/darshitvachhani) 27 | --------------------------------------------------------------------------------