Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions canvas.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
class canvas():

def __init__(self, width, height):
self.width = width
self.height = height
self.width = int(width)
self.height = int(height)
self.new_canvas = np.zeros((self.height, self.width, 3), np.uint8)

def set_color(self, B, G, R):
Expand All @@ -19,10 +19,18 @@ def show_canvas(self):
cv2.imshow('newCanvas', self.new_canvas)

def save_drawing(self):
""""""
"""This function allows users to save their drawing with a name of
their choice.
"""
file_name = input('Please name your drawing: ')
cv2.imwrite(file_name+'.jpg', self.new_canvas)

def clear(self):
"""This function clears the screen.
"""
cv2.rectangle(self.new_canvas, (0, 0), (self.width, self.height), (0, 0, 0))


if __name__ == "__main__":
canvas1 = canvas(1280, 960)
canvas1.set_color(0, 0, 0)
Expand Down
72 changes: 48 additions & 24 deletions fingerTrack.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,45 @@ def __init__(self):
self.red_maskL = [np.array([0, 150, 100]), np.array([178, 150, 100])]
self.red_maskH = [np.array([1, 255, 255]), np.array([180, 255, 255])]
self.refreshDelay = 0
self.colors = []
self.dist = []

def map(self, x, oldL, oldH, newL, newH):
"""This function maps a value from one range to a differnet range

x: the value in the old range
oldL: the lower limit of the old range of values
oldH: the upper limit of the old range of values
newL: the lower limit of the new range of values
newH: the upper limit of the new range of values
"""
return int(((x - oldL)/(oldH-oldL))*(newH-newL)+newL)

def brush_color(self, hue):
"""This function takes in a uint8 value for hue and generate
a BGR color range """
color = np.uint8([[[hue, 255, 255]]])
return cv2.cvtColor(color, cv2.COLOR_HSV2BGR)

def BGR2HSV(self, frame):
"""This functions takes in a frame and converts it from BGR to BGR2HSV
"""This functions takes in a frame and converts it from BGR
to HSV values
"""
return cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

def red_mask(self, frame):
"""This function generates a red mask based on the frame being passed in
"""This function generates a red mask based on the frame being
passed in
"""
mask1 = cv2.inRange(frame, self.red_maskL[0], self.red_maskH[0])
mask2 = cv2.inRange(frame, self.red_maskL[1], self.red_maskH[1])
return (mask1 | mask2)

def find_center(self, mask, target):
"""This function takes in a cv2 mask, find the center of the
contours in the mask, and draw a green dot at the center location
on the target frame
"""
im2, contours, hierarchy = cv2.findContours(mask, 1, 2)
try:
if self.frame_num > self.refreshDelay or self.frame_num == 0:
Expand All @@ -44,37 +69,36 @@ def find_center(self, mask, target):
except IndexError:
""""""

def draw(self, target):
def refine_path(self):
"""This function takes evalutes every two consecutive points,
find the distance between them, and add the new point to a
list of clear path if they are not off by roughly 15 pixels.
It also takes a distance and convert it to a color to be used
when plotting the line.
"""
if len(self.path) == 1:
clearpath.append(path[0])
self.clearpath.append(self.path[0])
elif len(self.path) > 2:
pair = self.path[-2]
# print(pair, pair[0], cx, pair[1], cy)
diffx = abs(self.cx-pair[0])
diffy = abs(self.cy-pair[1])
distance = math.sqrt(diffx**2+diffy**2)
if distance<10:
dist2hue = self.map(distance, 0.0, 10.0, 0.0, 255.0)
paintColor = self.brush_color(dist2hue)
self.colors.append((int(paintColor[0][0][0]), int(paintColor[0][0][1]), int(paintColor[0][0][2])))
self.clearpath.append(pair)

def draw(self, canvas, disappr=True):
"""This function draws the lines on the canvas of the screen.
The default is that only the 20 newest points will be drawn on screen.
"""
for i in range(len(self.clearpath)):
if len(self.clearpath) < 1:
break
elif i<(len(self.clearpath)-1)<21:
cv2.line(res, self.clearpath[i], self.clearpath[i+1], (255,0,0), 3)
elif 20 < i < (len(self.clearpath)-1):
cv2.rectangle(res, (0,0), (600, 400), (0,0,0))
elif i<(len(self.clearpath)-1)<21 and not disappr:
cv2.line(canvas.new_canvas, self.clearpath[i], self.clearpath[i+1], self.colors[i], 3)
elif 20 < i < (len(self.clearpath)-1) and disappr:
canvas.clear()
for j in range(20):
cv2.line(res, self.clearpath[-(j+1)], self.clearpath[-(j+2)], (255,0,0), 3)
# for i in range(len(self.path)):
# # TODO: Add if statements to make sure that any outliers
# # would be removed from the list or ignored when drawing
# # the linewidth
# diffx = math.abs(self.cx-self.path[-1][0])
# print(diffx)
# diffy = math.abs(cy-path[-1][1])
# print(diffy)
# if len(self.path) == 1:
# break
# # elif math.sqrt(diffx**2+diffy**2) > 30:
# # break
# if i < (len(self.clearpath)-1):
# cv2.line(target, self.clearpath[i], self.path[i+1], (255, 0, 0), 3)
cv2.line(canvas.new_canvas, self.clearpath[-(j+1)], self.clearpath[-(j+2)], self.colors[-(j+2)], 3)
34 changes: 34 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,43 @@
from fingerTrack import *
from canvas import *
import cv2


def main():
"""
"""
track = finger_track()
cap = cv2.VideoCapture(0)
newCanvas = canvas(cap.get(3), cap.get(4))
disappr = True


while True:
ret, frame = cap.read()
frame = cv2.flip(frame,1)
cv2.imshow('original', frame)
hsv = track.BGR2HSV(frame)
redMask = track.red_mask(hsv)
mask = cv2.bilateralFilter(redMask, 10, 40, 40)
mask = cv2.blur(mask, (5, 5))
res = cv2.bitwise_and(frame, frame, mask=redMask)
mask = cv2.blur(mask, (20, 20))
track.find_center(mask, frame)
track.refine_path()
track.draw(newCanvas, disappr=disappr)
newCanvas.show_canvas()

if cv2.waitKey(1) & 0xFF == ord('s'):
newCanvas.save_drawing()
break
elif cv2.waitKey(1) & 0xFF == ord('q'):
break
elif cv2.waitKey(1) & 0xFF == ord('d'):
disappr = ~disappr
elif cv2.waitKey(1) & 0xFF == ord('c'):
newCanvas.clear()

cv2.destroyAllWindows()

if __name__ == "__main__":
main()
33 changes: 30 additions & 3 deletions paint.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,34 @@
cy = 0
path = []
clearpath = []
dist = []
colors = []


def map(x, oldL, oldH, newL, newH):
"""This function maps a value from one range to a differnet range

x: the value in the old range
oldL: the lower limit of the old range of values
oldH: the upper limit of the old range of values
newL: the lower limit of the new range of values
newH: the upper limit of the new range of values
"""
return int(((x - oldL)/(oldH-oldL))*(newH-newL)+newL)

def brush_color(hue):
"""This function takes in a uint8 value for hue and generate
a BGR color range """
color = np.uint8([[[hue, 255, 255]]])
return cv2.cvtColor(color, cv2.COLOR_HSV2BGR)

while(True):
#capture frame by frame
ret, frame = cap.read()
frame = cv2.flip(frame,1)
hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
#find specific color
lower_white = np.array([[0, 0, 230]])
lower_white = np.array([0, 0, 230])
upper_white = np.array([180, 25, 255])
lower_color = np.array([0,80,50])
upper_color = np.array([20,100,100])
Expand Down Expand Up @@ -69,18 +89,25 @@
diffy = abs(cy-pair[1])
distance = math.sqrt(diffx**2+diffy**2)
if distance<10:
dist2hue = map(distance, 0.0, 10.0, 0.0, 255.0)
paintColor = brush_color(dist2hue)
print(paintColor[0][0][0])
colors.append((int(paintColor[0][0][0]), int(paintColor[0][0][1]), int(paintColor[0][0][2])))
print(colors)
clearpath.append(pair)

for i in range(len(clearpath)):
if len(clearpath) < 1:
break
elif i<(len(clearpath)-1)<21:
cv2.line(res, clearpath[i], clearpath[i+1], (255,0,0), 3)
cv2.line(res, clearpath[i], clearpath[i+1], colors[i], 3)
elif 20 < i < (len(clearpath)-1):
cv2.rectangle(res, (0,0), (600, 400), (0,0,0))
for j in range(20):
cv2.line(res, clearpath[-(j+1)], clearpath[-(j+2)], (255,0,0), 3)
cv2.line(res, clearpath[-(j+1)], clearpath[-(j+2)], colors[-(j+2)], 3)


# print(dist)
frame_num += 1
# cnts = cv2.findContours(res, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
#display the resulting frame
Expand Down