-
-
Save botforge/c88b842cafaa077a91048d51c2db0bdf to your computer and use it in GitHub Desktop.
| """ | |
| USES OPENCV 4.10, PROBABLY WILL WORK FOR OPENCV 2.70 and up | |
| REMEMBER TO CALCULATE THE HSV BOUNDS FOR color1 & color2, use the trackbar: | |
| https://gist.github.com/botforge/c6559abd3c48bceb78c2664dcb53cef6 | |
| to get these values | |
| """ | |
| import cv2 | |
| import numpy as np | |
| import math | |
| def distance(x1, y1, x2, y2): | |
| """ | |
| Calculate distance between two points | |
| """ | |
| dist = math.sqrt(math.fabs(x2-x1)**2 + math.fabs(y2-y1)**2) | |
| return dist | |
| def find_color1(frame): | |
| """ | |
| Filter "frame" for HSV bounds for color1 (inplace, modifies frame) & return coordinates of the object with that color | |
| """ | |
| hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) | |
| hsv_lowerbound = np.array([139, 149, 131]) #replace THIS LINE w/ your hsv lowerb | |
| hsv_upperbound = np.array([179, 255, 219])#replace THIS LINE w/ your hsv upperb | |
| mask = cv2.inRange(hsv_frame, hsv_lowerbound, hsv_upperbound) | |
| res = cv2.bitwise_and(frame, frame, mask=mask) #filter inplace | |
| cnts, hir = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) | |
| if len(cnts) > 0: | |
| maxcontour = max(cnts, key=cv2.contourArea) | |
| #Find center of the contour | |
| M = cv2.moments(maxcontour) | |
| if M['m00'] > 0 and cv2.contourArea(maxcontour) > 1000: | |
| cx = int(M['m10']/M['m00']) | |
| cy = int(M['m01']/M['m00']) | |
| return (cx, cy), True | |
| else: | |
| return (700, 700), False #faraway point | |
| else: | |
| return (700, 700), False #faraway point | |
| def find_color2(frame): | |
| """ | |
| Filter "frame" for HSV bounds for color1 (inplace, modifies frame) & return coordinates of the object with that color | |
| """ | |
| hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) | |
| hsv_lowerbound = np.array([101, 152, 92])#replace THIS LINE w/ your hsv lowerb | |
| hsv_upperbound = np.array([149, 255, 243])#replace THIS LINE w/ your hsv upperb | |
| mask = cv2.inRange(hsv_frame, hsv_lowerbound, hsv_upperbound) | |
| res = cv2.bitwise_and(frame, frame, mask=mask) | |
| cnts, hir = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) | |
| if len(cnts) > 0: | |
| maxcontour = max(cnts, key=cv2.contourArea) | |
| #Find center of the contour | |
| M = cv2.moments(maxcontour) | |
| if M['m00'] > 0 and cv2.contourArea(maxcontour) > 2000: | |
| cx = int(M['m10']/M['m00']) | |
| cy = int(M['m01']/M['m00']) | |
| return (cx, cy), True #True | |
| else: | |
| return (700, 700), True #faraway point | |
| else: | |
| return (700, 700), True #faraway point | |
| cap = cv2.VideoCapture(0) | |
| while(1): | |
| _, orig_frame = cap.read() | |
| #we'll be inplace modifying frames, so save a copy | |
| copy_frame = orig_frame.copy() | |
| (color1_x, color1_y), found_color1 = find_color1(copy_frame) | |
| (color2_x, color2_y), found_color2 = find_color2(copy_frame) | |
| #draw circles around these objects | |
| cv2.circle(copy_frame, (color1_x, color1_y), 20, (255, 0, 0), -1) | |
| cv2.circle(copy_frame, (color2_x, color2_y), 20, (0, 128, 255), -1) | |
| if found_color1 and found_color2: | |
| #trig stuff to get the line | |
| hypotenuse = distance(color1_x, color1_x, color2_x, color2_y) | |
| horizontal = distance(color1_x, color1_y, color2_x, color1_y) | |
| vertical = distance(color2_x, color2_y, color2_x, color1_y) | |
| angle = np.arcsin(vertical/hypotenuse)*180.0/math.pi | |
| #draw all 3 lines | |
| cv2.line(copy_frame, (color1_x, color1_y), (color2_x, color2_y), (0, 0, 255), 2) | |
| cv2.line(copy_frame, (color1_x, color1_y), (color2_x, color1_y), (0, 0, 255), 2) | |
| cv2.line(copy_frame, (color2_x, color2_y), (color2_x, color1_y), (0, 0, 255), 2) | |
| #put angle text (allow for calculations upto 180 degrees) | |
| angle_text = "" | |
| if color2_y < color1_y and color2_x > color1_x: | |
| angle_text = str(int(angle)) | |
| elif color2_y < color1_y and color2_x < color1_x: | |
| angle_text = str(int(180 - angle)) | |
| elif color2_y > color1_y and color2_x < color1_x: | |
| angle_text = str(int(180 + angle)) | |
| elif color2_y > color1_y and color2_x > color1_x: | |
| angle_text = str(int(360 - angle)) | |
| #CHANGE FONT HERE | |
| cv2.putText(copy_frame, angle_text, (color1_x-30, color1_y), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 128, 229), 2) | |
| cv2.imshow('AngleCalc', copy_frame) | |
| cv2.waitKey(5) | |
| cap.release() | |
| cv2.destroyAllWindows() |
Shouldn't line 82 be color1_x, color1_y, color2_x, color2_y? You have color1_x twice.
Yup. Thanks!
Hello .. This is giving error .. can you please help.
C:\Users\XPS\PycharmProjects\FaceMesh1\venv\Scripts\python.exe "C:/Users/XPS/PycharmProjects/FaceMesh1/orientation 2.py"
Error processing line 1 of C:\Users\XPS\PycharmProjects\FaceMesh1\venv\lib\site-packages\vision-1.0.0-py3.10-nspkg.pth:
Traceback (most recent call last):
File "C:\Users\XPS\AppData\Local\Programs\Python\Python310\lib\site.py", line 186, in addpackage
exec(line)
File "", line 1, in
File "", line 568, in module_from_spec
AttributeError: 'NoneType' object has no attribute 'loader'
Remainder of file ignored
Error processing line 1 of C:\Users\XPS\PycharmProjects\FaceMesh1\venv\lib\site-packages\vision-1.0.0-py3.10-nspkg.pth:
Traceback (most recent call last):
File "C:\Users\XPS\AppData\Local\Programs\Python\Python310\lib\site.py", line 186, in addpackage
exec(line)
File "", line 1, in
File "", line 568, in module_from_spec
AttributeError: 'NoneType' object has no attribute 'loader'
Remainder of file ignored
[ WARN:0@3.528] global D:\a\opencv-python\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (539) `anonymous-namespace'::SourceReaderCB::~SourceReaderCB terminating async callback
Traceback (most recent call last):
File "C:\Users\XPS\PycharmProjects\FaceMesh1\orientation 2.py", line 67, in
cap = cv2.VideoCapture(1)
KeyboardInterrupt
Process finished with exit code -1073741510 (0xC000013A: interrupted by Ctrl+C)
Shouldn't line 82 be color1_x, color1_y, color2_x, color2_y? You have color1_x twice.