Control Mouse using Gesture - python

When I run the code below, I get the following error:
Traceback (most recent call last):
File "path\gesture_mouse.py", line 63, in
cv2.circle(img, (cx, cy), (w+h)/4, (0, 0, 255), 2)
TypeError: integer argument expected, got float
[ WARN:0] terminating async callback
I tried assigning the center and the radius separately pre-defined.
import cv2
import numpy as np
from pynput.mouse import Button, Controller
import wx
mouse = Controller()
app = wx.App(False)
(sx, sy) = wx.GetDisplaySize()
(camx, camy) = (320, 240)
lowerBound = np.array([33, 80, 40])
upperBound = np.array([102, 255, 255])
cam = cv2.VideoCapture(0)
kernelOpen = np.ones((5, 5))
kernelClose = np.ones((20, 20))
pinchFlag = 0
while True:
ret, img = cam.read()
img=cv2.resize(img, (340, 220))
# convert BGR to HSV
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# create the Mask
mask = cv2.inRange(imgHSV, lowerBound, upperBound)
# morphology
maskOpen = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernelOpen)
maskClose = cv2.morphologyEx(maskOpen, cv2.MORPH_CLOSE, kernelClose)
maskFinal = maskClose
conts, h = cv2.findContours(maskFinal.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
if len(conts) == 2:
if pinchFlag == 1:
pinchFlag = 0
mouse.release(Button.left)
x1, y1, w1, h1 = cv2.boundingRect(conts[0])
x2, y2, w2, h2 = cv2.boundingRect(conts[1])
cv2.rectangle(img, (x1, y1), (x1+w1, y1+h1), (255, 0, 0), 2)
cv2.rectangle(img, (x2, y2), (x2+w2, y2+h2), (255, 0, 0), 2)
cx1 = x1+w1/2
cy1 = y1+h1/2
cx2 = x2+w2/2
cy2 = y2+h2/2
cx = (cx1+cx2)/2
cy = (cy1+cy2)/2
cv2.line(img, (cx1, cy1), (cx2, cy2), (255, 0, 0), 2)
cv2.circle(img, (cx, cy), 2, (0, 0, 255), 2)
mouseLoc = (sx-(cx*sx/camx), cy*sy/camy)
mouse.position = mouseLoc
while mouse.position != mouseLoc:
pass
elif len(conts) == 1:
x, y, w, h = cv2.boundingRect(conts[0])
if pinchFlag == 0:
pinchFlag = 1
mouse.press(Button.left)
cv2.rectangle(img, (x, y), (x+w, y+h), (255, 0, 0), 2)
cx = x+w/2
cy = y+h/2
cv2.circle(img, (cx, cy), (w+h)/4, (0, 0, 255), 2)
mouseLoc = (sx-(cx*sx/camx), cy*sy/camy)
mouse.position = mouseLoc
while mouse.position != mouseLoc:
pass
cv2.imshow("cam", img)
cv2.waitKey(5)
I was expecting that when two green color objects appear in the frame they will be scribed in a blue box, and a blue line from the center of the two box will appear where a red dot will be present signifying the location of the cursor(mouse).

Like the error says, the function needs int's as input, but you input floats. This is because the values are the result of division calculations.
print(type(10)) #<class 'int'>
print(type(5)) #<class 'int'>
print(type(10/5)) #<class 'float'>
print(10/5) #2.0
The solution is the convert the calculated values to integers:
cv2.circle(img, (int(cx), int(cy), int((w+h)/4), (0, 0, 255), 2)

Related

how can i perform double click using opencv

I want a code for double clicking with only these packages:
import cv2
import pyautogui
from HandTracker import HandDetector
import math
This is the code for handtracker:
import cv2
import mediapipe as mp
import time
import math
import numpy as np
class HandDetector():
def __init__(self, imageMode=False, maxHands=2, modelComplexity=1 , detectionConfidence=0.5, trackingConfidence=0.5 ):
self.imageMode = imageMode
self.maxHands = maxHands
self.modelComplexity = modelComplexity
self.detectionConfidence = detectionConfidence
self.trackingConfidence = trackingConfidence
self.mpHands = mp.solutions.hands
self.hands = self.mpHands.Hands(self.imageMode, self.maxHands, self.modelComplexity, self.detectionConfidence, self.trackingConfidence)
self.mpDraw = mp.solutions.drawing_utils
self.tipIds = [4, 8, 12, 16, 20]
def findHandLandmarks(self, cap):
# X is the raw distance, Y is the value in cm.
x = [300, 245, 200, 170, 145, 130, 112, 103, 93, 87, 80, 75, 70, 67, 62, 59, 57]
y = [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]
coff = np.polyfit(x, y, 2)
isImageRead, image = cap.read()
image = self.findHands(image)
landmarksList, boundingbox = self.findPosition(image)
try:
_, x1, y1 = landmarksList[5]
_, x2, y2 = landmarksList[17]
distance = int(math.sqrt((y2 - y1)**2 + (x2 - x1)**2))
A, B, C = coff
distanceCM = A * distance**2 + B * distance + C
if distanceCM < 40:
text = 'Move your hand away'
cv2.putText(image, text, (10, 70), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 255), 3)
if distanceCM > 90:
text = 'Bring your hand closer'
cv2.putText(image, text, (10, 70), cv2.FONT_HERSHEY_PLAIN, 2, (255, 0, 255), 3)
if 90 >= distanceCM >= 40:
text = f'{int(distanceCM)} cm'
cv2.putText(image, text, (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
except IndexError:
pass
return image
def findHands(self, image, draw=True):
imgRGB = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
self.results = self.hands.process(imgRGB)
if self.results.multi_hand_landmarks:
for handLandmarks in self.results.multi_hand_landmarks:
if draw:
self.mpDraw.draw_landmarks(image, handLandmarks, self.mpHands.HAND_CONNECTIONS)
return image
def findPosition(self, image, handNo=0, draw=True):
xList = []
yList = []
bbox = []
self.landmarksList = []
if self.results.multi_hand_landmarks:
myHand = self.results.multi_hand_landmarks[handNo]
for id, lm in enumerate(myHand.landmark):
h, w, c = image.shape
cx, cy = int(lm.x * w), int(lm.y * h)
xList.append(cx)
yList.append(cy)
self.landmarksList.append([id, cx, cy])
if draw:
cv2.circle(image, (cx, cy), 5, (255, 0, 255), cv2.FILLED)
xmin, xmax = min(xList), max(xList)
ymin, ymax = min(yList), max(yList)
bbox = xmin, ymin, xmax, ymax
if draw:
cv2.rectangle(image, (xmin - 20, ymin - 20), (xmax + 20, ymax + 20), (0, 255, 0), 2)
return self.landmarksList, bbox
def fingersMotion(self):
# Fingers[] represents which fingers are up where 1 = up and 0 = down
fingers = []
# Thumb
if self.landmarksList[self.tipIds[0]][1] > self.landmarksList[self.tipIds[0] - 1][1]:
fingers.append(1)
else:
fingers.append(0)
# Fingers
for id in range(1, 5):
if self.landmarksList[self.tipIds[id]][2] < self.landmarksList[self.tipIds[id] - 2][2]:
fingers.append(1)
else:
fingers.append(0)
return fingers
def findDistance(self, p1, p2, image, draw=True, r=15, t=3):
x1, y1 = self.landmarksList[p1][1:]
x2, y2 = self.landmarksList[p2][1:]
cx, cy = (x1 + x2) // 2, (y1 + y2) // 2
if draw:
cv2.line(image, (x1, y1), (x2, y2), (255, 0, 255), t)
cv2.circle(image, (x1, y1), r, (255, 0, 255), cv2.FILLED)
cv2.circle(image, (x2, y2), r, (255, 0, 255), cv2.FILLED)
cv2.circle(image, (cx, cy), r, (0, 0, 255), cv2.FILLED)
length = math.hypot(x2 - x1, y2 - y1)
return length, image, [x1, y1, x2, y2, cx, cy]
def main():
previousTime = 0
currentTime = 0
cap = cv2.VideoCapture(0)
detector = HandDetector()
while True:
image = detector.findHandLandmarks(cap)
# Frame rate
currentTime = time.time()
framesPerSecond = 1 / (currentTime - previousTime)
previousTime = currentTime
cv2.putText(image, str(int(framesPerSecond)), (10, 70), cv2.FONT_HERSHEY_PLAIN, 3, (255, 0, 255), 3)
# Display
cv2.imshow("Image", image)
if cv2.waitKey(1) == ord('q'):
break
if __name__ == "__main__":
main()

Opencv Why does the contour remain if the object has disappeared?

I found a pre-written object detection program on the internet. I would like to use this to make a plastic bottle cap sensor on an assembly line that will tell me the size. Only when you move the cap out of the conveyor belt the coordinates taken from the contour stay there. Any ideas?
import cv2
from object_detector import *
import numpy as np
import time
# Load Object Detector
detector = HomogeneousBgDetector()
# Load Cap
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 800)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 600)
while True:
_, img = cap.read()
img = img[0:600, 60:700 ]
contours = []
contours = detector.detect_objects(img)
# Draw objects boundaries
for cnt in contours:
# Get rect
rect = cv2.minAreaRect(cnt)
(x, y), (w, h), angle = rect
# Get Width and Height of the Objects by applying the Ratio pixel to cm
object_width = w
object_height = h
# Display rectangle
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.circle(img, (int(x), int(y)), 5, (0, 0, 255), -1)
cv2.polylines(img, [box], True, (255, 0, 0), 2)
cv2.putText(img, "Width {} px".format(round(object_width, 1)), (int(x - 100), int(y - 20)), cv2.FONT_HERSHEY_PLAIN, 2, (100, 200, 0), 2)
cv2.putText(img, "Height {} px".format(round(object_height, 1)), (int(x - 100), int(y + 15)), cv2.FONT_HERSHEY_PLAIN, 2, (100, 200, 0), 2)
cv2.imshow("Image", img)
key = cv2.waitKey(1)
if key == 27:
break
cap.release()
cv2.destroyAllWindows()
object_detector.py
import cv2
class HomogeneousBgDetector():
def __init__(self):
pass
def detect_objects(self, frame):
def difference_of_Gaussians(img, k1, s1, k2, s2):
b1 = cv2.GaussianBlur(img,(k1, k1), s1)
b2 = cv2.GaussianBlur(img,(k2, k2), s2)
return b1 - b2
# Convert Image to grayscale
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
DoG_img = difference_of_Gaussians(gray, 7, 7, 17, 13)
# Create a Mask with adaptive threshold
#mask = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 19, 5)
mask = cv2.threshold(DoG_img ,130,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]
# Find contours
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cv2.imshow("mask", mask)
objects_contours = []
for cnt in contours:
area = cv2.contourArea(cnt)
if area > 2000:
objects_contours.append(cnt)
return objects_contours
I tried to create the contour variable empty before, but failed:
....
_, img = cap.read()
img = img[0:600, 60:700 ]
contours = []# here
contours = detector.detect_objects(img)
# Draw objects boundaries
for cnt in contours:
.....
the picture:
Eran and Christoph are right. If no contour is found, the last position remains in the global x and y variables. Perhaps you want to increase the indent of the four lines that draw circle, lines and text so that it belongs to the for-loop above?
....
img = img[0:600, 60:700 ]
contours = detector.detect_objects(img)
# Draw objects boundaries
for cnt in contours:
....
# Display rectangle
box = cv2.boxPoints(rect)
box = np.int0(box)
# keep indent here
cv2.circle(img, (int(x), int(y)), 5, (0, 0, 255), -1)
cv2.polylines(img, [box], True, (255, 0, 0), 2)
cv2.putText(img, "Width {} px".format(round(object_width, 1)), (int(x - 100), int(y - 20)), cv2.FONT_HERSHEY_PLAIN, 2, (100, 200, 0), 2)
cv2.putText(img, "Height {} px".format(round(object_height, 1)), (int(x - 100), int(y + 15)), cv2.FONT_HERSHEY_PLAIN, 2, (100, 200, 0), 2)
....

Error in list index python hand gesture recogniser opencv

I am making a hand gesture recognizer, using OPENCV in PYTHON. I refereed to a YouTube tutorial, and it worked fine there, but i have encountered an error. I am a new coder.
here is my code:
import cv2
import math
import numpy as np
capture = cv2.VideoCapture(0)
while capture.isOpened():
# while True:
ret, img = capture.read()
cv2.rectangle(img, (300, 300), (100, 100), (255, 255, 255), 2)
crop_img = img[100:300, 100:300]
grayscale = cv2.cvtColor(crop_img, cv2.COLOR_BGR2GRAY)
value = (35, 35)
blurry = cv2.GaussianBlur(grayscale, value, 0)
_, thresh1 = cv2.threshold(blurry, 127, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
cv2.imshow('Threshold', thresh1)
contours, hierarchy = cv2.findContours(thresh1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
cont = max(contours, key=lambda item: cv2.contourArea(item))
x, y, w, h = cv2.boundingRect(cont)
cv2.rectangle(crop_img, (x, y), (w, h), (0, 0, 255), 2)
hull = cv2.convexHull(cont)
drawing = np.zeros(crop_img.shape, np.uint8)
cv2.drawContours(drawing, [cont], 0, (0, 255, 0), 0)
cv2.drawContours(drawing, [hull], 0, (0, 0, 255), 0)
hull = cv2.convexHull(cont, returnPoints=False)
defects = cv2.convexityDefects(cont, hull)
count_defects = 0
cv2.drawContours(thresh1, contours, -1, (0, 255, 0), 3)
start = ()
end = ()
far = ()
for i in range(defects.shape[0]):
s, e, d, f = defects[i, 0]
start = tuple(cont[s][0])
end = tuple(cont[e][0])
far = tuple(cont[f][0])
a = math.sqrt((end[0] - start[0])**2 + (end[1] - start[1])**2)
b = math.sqrt((far[0] - start[0])**2 + (far[1] - start[1])**2)
c = math.sqrt((end[0] - far[0])**2 + (end[1] - far[1])**2)
angle = math.acos((b**2 + c**2 - a**2)/(2*b*c)) * 57
if angle <= 120:
count_defects += 1
cv2.circle(crop_img, far, 1, (0, 0, 255), -1)
cv2.line(crop_img, start, end, (0, 255, 0), 2)
if count_defects == 1:
cv2.putText(img, '1 Finger', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
elif count_defects == 2:
cv2.putText(img, '2 Fingers', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
elif count_defects == 3:
cv2.putText(img, '3 Fingers', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
elif count_defects == 4:
cv2.putText(img, '4 Fingers', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
elif count_defects == 5:
cv2.putText(img, '5 Fingers', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
else:
cv2.putText(img, 'Unknown gesture', (50, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, 2)
cv2.imshow('Gesture', img)
all_img = np.hstack((drawing, crop_img))
cv2.imshow('Contours', all_img)
k = cv2.waitKey(10)
if k == 27:
break
this shows an error while executing at line 50:
line 50, in <module>
far = tuple(cont[f][0])
IndexError: index 1635 is out of bounds for axis 0 with size 596
I am making a hand gesture recogniser, and it works properly on my friend's python. Please help, thanks
I never use it but in some examples I see different order s, e, f, d instead of s, e, d, f
s, e, f, d = defects[i, 0]
and now your code works for me.

OpenCV Memory and CPU Usage

I'm making a USV (Unmanned Surface Vehicle) for my bachelor project. The track it needs to keep is made by having coloured buoys on the left/right side of the track and for obstacles.
So I need to track the depth of these objects and give all that information on to my navigation program.
And I have made a Python code using ROS and OpenCV to track these buoys with a ZED2 camera. But I'm having CPU and memory issues. Where the ubuntu desktop starts to lag.
Using a Nvidia Jetson Xavier NX and I’m using 85% of the CPU and 5,5+/7.59Gb Memory.
Anyone interested in looking over my code and see if I'm doing something stupid. That would explain my issues.
from __future__ import print_function
import roslib
import sys
import rospy
import cv2
from main.msg import VarRed, VarGreen, VarYellow, RedHSV, GreenHSV, YellowHSV, MidPoint
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import numpy as np
import imutils
import time
from collections import deque
import math
class image_converter:
def __init__(self):
self.image_subd = rospy.Subscriber("/zed2/zed_node/depth/depth_registered",Image,self.callbackDepth)
self.image_sub = rospy.Subscriber("/zed2/zed_node/rgb_raw/image_raw_color",Image,self.callbackVideo)
self.image_pub = rospy.Publisher("/Tracking/RG_image", Image, queue_size = 1)
self.RedHSV_sub = rospy.Subscriber("/Tracking/Red_HSV", RedHSV, self.redHSV)
self.GreenHSV_sub = rospy.Subscriber("/Tracking/Green_HSV", GreenHSV, self.greenHSV)
self.YellowHSV_sub = rospy.Subscriber("/Tracking/Yellow_HSV", YellowHSV, self.yellowHSV)
self.MidPoint_pub = rospy.Publisher("/Tracking/MidPoint", MidPoint, queue_size = 1)
self.red_bridge = CvBridge()
self.red_publisher = rospy.Publisher("/Tracking/red", VarRed, queue_size = 1)
self.green_bridge = CvBridge()
self.green_publisher = rospy.Publisher("/Tracking/green", VarGreen, queue_size = 1)
self.yellow_bridge = CvBridge()
self.yellow_publisher = rospy.Publisher("/Tracking/yellow", VarYellow, queue_size = 1)
self.RedLower = (0, 101, 68) # Declaring the red-specter
self.RedUpper = (15, 255, 255)
self.GreenLower = (75, 145, 48) # Declaring the green-specter
self.GreenUpper = (96, 255, 75)
self.YellowLower = (28, 56, 91) # Declaring the yellow-specter
self.YellowUpper = (51, 152, 150)
self.red_pts = deque(maxlen=14)
self.currentDepthImg=0
self.red_counter = 0
self.red_x = 0
self.red_y = 0
self.red_radius = 30
self.green_pts = deque(maxlen=14)
self.green_currentDepthImg=0
self.green_counter = 0
self.green_x = 0
self.green_y = 0
self.green_radius = 30
self.yellow_pts = deque(maxlen=14)
self.yellow_currentDepthImg=0
self.yellow_counter = 0
self.yellow_x = 0
self.yellow_y = 0
self.yellow_radius = 30
def redHSV(self,msg):
self.RedLower = (msg.r_h_low-10, msg.r_s_low-10, msg.r_v_low-10)
self.RedUpper = (msg.r_h_high+10, msg.r_s_high+10, msg.r_v_high+10)
def greenHSV(self,msg):
self.GreenLower = (msg.g_h_low-10, msg.g_s_low-10, msg.g_v_low-10)
self.GreenUpper = (msg.g_h_high+10, msg.g_s_high+10, msg.g_v_high+10)
def yellowHSV(self,msg):
self.YellowLower = (msg.y_h_low-10, msg.y_s_low-10, msg.y_v_low-10)
self.YellowUpper = (msg.y_h_high+10, msg.y_s_high+10, msg.y_v_high+10)
def callbackDepth(self,msg_depth):
try:
cv_image_depth = self.red_bridge.imgmsg_to_cv2(msg_depth, "32FC1") # CV_Bridge Depth
except CvBridgeError as e:
print(e)
return
self.currentDepthImg=cv_image_depth
try:
a=1
except CvBridgeError as e:
print(e)
return
def callbackVideo(self,data):
try:
cv_image = self.red_bridge.imgmsg_to_cv2(data, "bgr8") # CV_Bridge Video
except CvBridgeError as e:
print(e)
return
(rows,cols,channels) = cv_image.shape
frame = cv_image
blurred = cv2.GaussianBlur(frame, (21, 21), 0) # resize the frame, blur it, and convert it to the HSV (11,11), 0
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV) # color space.
red_mask = cv2.inRange(hsv, self.RedLower, self.RedUpper) # Construct a mask for the color "red", then perform
red_mask = cv2.erode(red_mask, None, iterations=2) # a series of dilations and erosions to remove any small
red_mask = cv2.dilate(red_mask, None, iterations=2) # blobs thats left in the mask.
green_mask = cv2.inRange(hsv, self.GreenLower, self.GreenUpper) # construct a mask for the color "green", then perform
green_mask = cv2.erode(green_mask, None, iterations=2) # a series of dilations and erosions to remove any small
green_mask = cv2.dilate(green_mask, None, iterations=2) # blobs thats left in the mask.
yellow_mask = cv2.inRange(hsv, self.YellowLower, self.YellowUpper) # construct a mask for the color "yellow", then perform
yellow_mask = cv2.erode(yellow_mask, None, iterations=2) # a series of dilations and erosions to remove any small
yellow_mask = cv2.dilate(yellow_mask, None, iterations=2) # blobs thats left in the mask.
red_cnts = cv2.findContours(red_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # find contours in the mask and initialize the current
red_cnts = imutils.grab_contours(red_cnts)
red_center = None
self.red_radius = 0
green_cnts = cv2.findContours(green_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # find contours in the mask and initialize the current
green_cnts = imutils.grab_contours(green_cnts)
green_center = None
self.green_radius = 0
yellow_cnts = cv2.findContours(yellow_mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # find contours in the mask and initialize the current
yellow_cnts = imutils.grab_contours(yellow_cnts)
yellow_center = None
self.yellow_radius = 0
cv_imaged=self.currentDepthImg
#-----------------------------------------RED_START------------------------------------------------------
if len(red_cnts) > 0: # only proceed if at least one contour was found
red_c = max(red_cnts, key=cv2.contourArea) # find the largest contour in the red_mask, then use
((self.red_x, self.red_y), self.red_radius) = cv2.minEnclosingCircle(red_c) # it to compute the minimum enclosing circle and
red_M = cv2.moments(red_c) # centroid
red_center = (int(red_M["m10"] / red_M["m00"]), int(red_M["m01"] / red_M["m00"]))
if self.red_radius > 5: # only proceed if the radius meets a minimum size
cv2.circle(frame, (int(self.red_x), int(self.red_y)), int(self.red_radius), (0, 255, 255), 2) # draw the circle and centroid on the red_frame,
cv2.circle(frame, red_center, 5, (0, 255, 255), -1) # then update the list of tracked points
msg = VarRed()
msg.r_visible = True
#if self.red_y == self.red_y and self.red_x == self.red_x:
r_length = cv_imaged[int(self.red_y),int(self.red_x)] # length to object
msg.r_x = self.red_x
msg.r_y = self.red_y
msg.r_rad = self.red_radius
ToRad = 2*np.pi/360 # = 0.01745329252
ToDeg = 360/(2*np.pi) # = 57.29577951308
# Printing pixel values
cv2.rectangle(frame, (0, 0), (200, 190), (0,0,0), -1)
cv2.putText(frame, str("L: %.3f" %r_length), ((int(self.red_x)),int(self.red_y)), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,255), 2)
cv2.putText(frame, str("RX: %.1f" %msg.r_x +" px"), (10,30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("RY: %.1f" %msg.r_y + " px"), (10,60), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
# For X-direction
red_l_cm = (r_length*100) # Converting to Centimeters
start_x_r = 960/(math.tan((55*ToRad))) # finding start x-length in px
ang_x_r = (math.atan((self.red_x-960)/start_x_r))*ToDeg # finding horizontal angle
red_x_cm = (red_l_cm*math.sin((ang_x_r)*ToRad))
cv2.putText(frame, str("RXC: %.1f" %red_x_cm + " cm"), (10,90), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("X Ang: %.1f" %ang_x_r), (10,150), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
# For Y-direction
start_y_r = 540/(math.tan((35*ToRad))) # finding start y-length in px
ang_y_r = ((math.atan((self.red_y-540)/start_y_r))*ToDeg)*-1 # finding vertical angle
red_y_cm = (red_l_cm/math.tan((ang_y_r*ToRad)+(math.pi/2)))*-1 # finding the y-length
cv2.putText(frame, str("RYC: %.1f" %red_y_cm + " cm"), (10,120), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("Y Ang: %.1f" %ang_y_r), (10,180), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
red_z = (math.cos(abs(ang_x_r)*ToRad))*red_l_cm
self.red_pts.appendleft(red_center)
msg.r_length = red_l_cm
msg.r_xc = red_x_cm
msg.r_yc = red_y_cm
msg.r_angle = ang_x_r # update the points queue
msg.r_z = red_z
self.red_publisher.publish(msg)
for i in range(1, len(self.red_pts)): # loop over the set of points
if self.red_pts[i - 1] is None or self.red_pts[i] is None: # if either of the tracked points
continue # are None, ignore them.
thickness = int(np.sqrt(64 / float(i + 1)) * 2.5) # otherwise, compute the thickness of the line and
cv2.line(frame, self.red_pts[i - 1], self.red_pts[i], (0, 255, 255), thickness) # draw the connecting lines
if self.red_radius < 5:
msg = VarRed()
msg.r_visible = False
self.red_publisher.publish(msg)
#-----------------------------------------RED_END------------------------------------------------------
#-----------------------------------------GREEN_START------------------------------------------------------
if len(green_cnts) > 0: # same as in red, but for green
green_c = max(green_cnts, key=cv2.contourArea)
((self.green_x, self.green_y), self.green_radius) = cv2.minEnclosingCircle(green_c)
green_M = cv2.moments(green_c)
green_center = (int(green_M["m10"] / green_M["m00"]), int(green_M["m01"] / green_M["m00"]))
if self.green_radius > 5:
cv2.circle(frame, (int(self.green_x), int(self.green_y)), int(self.green_radius), (0, 255, 255), 2)
cv2.circle(frame, green_center, 5, (0, 255, 255), -1)
ToRad = 2*np.pi/360 # = 0.01745329252
ToDeg = 360/(2*np.pi) # = 57.29577951308
msg1 = VarGreen()
msg1.g_visible = True
g_length = cv_imaged[int(self.green_y),int(self.green_x)]
msg1.g_x = self.green_x
msg1.g_y = self.green_y
msg1.g_rad = self.green_radius
# Printing pixel values
cv2.rectangle(frame, (1740, 0), (1920, 200), (0,0,0), -1)
cv2.putText(frame, str("L: %.3f" %g_length), ((int(self.green_x)),int(self.green_y)), cv2.FONT_HERSHEY_COMPLEX, 1, (0,255,255), 2)
cv2.putText(frame, str("GX: %.1f" %msg1.g_x +"px"), (1740,30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("GY: %.1f" %msg1.g_y + "px"), (1740,60), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
# For X-direction
green_l_cm = (g_length*100)
start_x_g = 960/(math.tan((55*2*np.pi/360)))
ang_x_g = (math.atan((self.green_x-960)/start_x_g))*57.295779513
green_x_cm = (green_l_cm*math.sin((ang_x_g)*ToRad))
# For Y-direction
start_y_g = 540/(math.tan((35*2*np.pi/360)))
ang_y_g = ((math.atan((self.green_y-540)/start_y_g))*57.295779513)*-1
green_y_cm = green_l_cm/math.tan(ang_y_g*ToRad+(math.pi/2))*-1
cv2.putText(frame, str("GXC: %.1f" %green_x_cm + "cm"), (1740,90), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("X Ang: %.1f" %ang_x_g), (1740,150), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("GYC: %.1f" %green_y_cm + "cm"), (1740,120), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.putText(frame, str("Y Ang: %.1f" %ang_y_g), (1740,180), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
green_z = (math.cos(abs(ang_x_g)*ToRad))*green_l_cm
self.green_pts.appendleft(green_center)
msg1.g_length = green_l_cm
msg1.g_xc = green_x_cm
msg1.g_yc = green_y_cm
msg1.g_angle = ang_x_g
msg1.g_z = green_z
self.green_publisher.publish(msg1)
for i in range(1, len(self.green_pts)):
if self.green_pts[i - 1] is None or self.green_pts[i] is None:
continue
thickness = int(np.sqrt(64 / float(i + 1)) * 2.5)
cv2.line(frame, self.green_pts[i - 1], self.green_pts[i], (0, 255, 255), thickness)
if self.green_radius < 5:
msg1 = VarGreen()
msg1.g_visible = False
self.green_publisher.publish(msg1)
#-----------------------------------------GREEN_END------------------------------------------------------
#-----------------------------------------YELLOW_START------------------------------------------------------
if len(yellow_cnts) > 0: # only proceed if at least one contour was found
yellow_c = max(yellow_cnts, key=cv2.contourArea) # find the largest contour in the yellow_mask, then use
((self.yellow_x, self.yellow_y), self.yellow_radius) = cv2.minEnclosingCircle(yellow_c) # it to compute the minimum enclosing circle and
yellow_M = cv2.moments(yellow_c) # centroid
yellow_center = (int(yellow_M["m10"] / yellow_M["m00"]), int(yellow_M["m01"] / yellow_M["m00"]))
if self.yellow_radius > 5: # only proceed if the radius meets a minimum size
cv2.circle(frame, (int(self.yellow_x), int(self.yellow_y)), int(self.yellow_radius), (0, 0, 200), 2) # draw the circle and centroid on the yellow_frame,
cv2.circle(frame, yellow_center, 5, (0, 0, 200), -1) # then update the list of tracked points
ToRad = 2*np.pi/360 # = 0.01745329252
ToDeg = 360/(2*np.pi) # = 57.29577951308
msg2 = VarYellow()
msg2.y_visible = True
y_length = cv_imaged[int(self.yellow_y),int(self.yellow_x)] # length to object
msg2.y_x = self.yellow_x
msg2.y_y = self.yellow_y
msg2.y_rad = self.yellow_radius
cv2.putText(frame, str("L: %.3f" %y_length), ((int(self.yellow_x)),int(self.yellow_y)), cv2.FONT_HERSHEY_COMPLEX, 1, (0,0,200), 2)
# For X-direction
yellow_l_cm = y_length*100 # Converting to Centimeters
start_x_y = 960/(math.tan((55*2*np.pi/360))) # finding start x-length in px
ang_x_y = (math.atan((self.yellow_x-960)/start_x_y))*57.295779513 # finding horizontal angle
#yellow_x = yellow_l_cm/math.tan((ang_x_y/57.295779513)) # finding the x-length
yellow_x_cm = (yellow_l_cm*math.sin((ang_x_y)*ToRad))
# For Y-direction
start_y_y = 540/(math.tan((35*2*np.pi/360))) # finding start y-length in px
ang_y_y = ((math.atan((self.yellow_y-540)/start_y_y))*57.295779513)*-1 # finding vertical angle
#yellow_y = yellow_l_cm/math.tan((ang_y_y/57.295779513)) # finding the y-length
yellow_y_cm = yellow_l_cm/math.tan(ang_y_y*ToRad+(math.pi/2))*-1
yellow_z = (math.cos(abs(ang_x_y)*ToRad))*yellow_l_cm
self.yellow_pts.appendleft(yellow_center)
msg2.y_length = yellow_l_cm
msg2.y_xc = yellow_x_cm
msg2.y_yc = yellow_y_cm
msg2.y_angle = ang_x_y # update the points queue
msg2.y_z = yellow_z
self.yellow_publisher.publish(msg2)
for i in range(1, len(self.yellow_pts)): # loop over the set of points
if self.yellow_pts[i - 1] is None or self.yellow_pts[i] is None: # if either of the tracked points
continue # are None, ignore them.
thickness = int(np.sqrt(64 / float(i + 1)) * 2.5) # otherwise, compute the thickness of the line and
cv2.line(frame, self.yellow_pts[i - 1], self.yellow_pts[i], (0, 0, 255), thickness) # draw the connecting lines
if self.yellow_radius < 5:
msg2 = VarYellow()
msg2.y_visible = False
self.yellow_publisher.publish(msg2)
#-----------------------------------------YELLOW_END------------------------------------------------------
try:
if (self.green_radius > 5) & (self.red_radius > 5): # if you can see both colors, proceed
ToRad = 2*np.pi/360 # = 0.01745329252
ToDeg = 360/(2*np.pi) # = 57.29577951308
red_z = (math.cos(abs(ang_x_r)*ToRad))*red_l_cm
green_z = (math.cos(abs(ang_x_g)*ToRad))*green_l_cm
Delta_z = abs(red_z-green_z)
Tot_x = abs(green_x_cm) + abs(red_x_cm)
if Delta_z == Delta_z and Tot_x == Tot_x:
red_green_angle = (math.atan(Delta_z/Tot_x))*ToDeg
normal_angle = red_green_angle
if green_l_cm >= red_l_cm:
normal_angle = red_green_angle*-1
if green_l_cm < red_l_cm:
normal_angle = red_green_angle
MidPoint_data = MidPoint()
MidPoint_data.angle = normal_angle
self.MidPoint_pub.publish(MidPoint_data)
length_between_x = math.sqrt((Tot_x*Tot_x)+(Delta_z*Delta_z))
Delta_y = abs(red_y_cm-green_y_cm)
length_between = math.sqrt((length_between_x*length_between_x)+(Delta_y*Delta_y))
#dx = green_x_cm - red_x_cm # Finding the space between the colors in x-direction
#dy = green_y_cm - red_y_cm # Finding the space between the colors in y-direction
# Calculating the direct length between the colors in cm
#cv2.rectangle(frame, (500, 0), (680, 160), (0,0,0), -1)
#cv2.putText(frame, str("Dist: %.1f" %length_between + " cm"), (500,30), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
#Middle_x = dx
#Middle_y = dy
MP_X = (msg1.g_x + msg.r_x)/2
MP_Y = (msg1.g_y + msg.r_y)/2
#Middle_Point_Angle = (math.atan((MP_X-960)/start_x_g))*57.295779513
#Middle_Point_Angle = ang_x_g - ang_x_r
#Middle_Point_Length =(red_x_cm-abs(Middle_x))/(math.sin((math.pi/2)-(Middle_Point_Angle*((2*math.pi)/720))))
#Middle_Point_Length =((red_x_cm-abs(Middle_x))/(math.cos(Middle_Point_Angle*((2*math.pi)/720))))
#cv2.putText(frame, str("MX: %.1f" %Middle_x + " cm"), (500,60), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
#cv2.putText(frame, str("MY: %.1f" %Middle_y + " cm"), (500,90), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
if MP_X == MP_X and MP_Y == MP_Y:
cv2.circle(frame, (int(MP_X), int(MP_Y)), 8, (0, 0, 255), -1)
#cv2.putText(frame, str("M_L: %.1f" %Middle_Point_Length + " cm"), (500,120), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
#cv2.putText(frame, str("M_ang: %.1f" %Middle_Point_Angle), (500,150), cv2.FONT_HERSHEY_COMPLEX, 0.8, (255,255,255), 1)
cv2.line(frame, (int(self.red_x),int(self.red_y)), (int(self.green_x),int(self.green_y)), (0, 0, 0), 2)
#MidPoint_data = MidPoint()
#MidPoint_data.z = Middle_Point_Length
#self.MidPoint_pub.publish(MidPoint_data)
cv2.line(frame, (960, 1280), (960, 0), (0, 255, 0), 1)
cv2.line(frame, (0, 540), (1920, 540), (0, 255, 0), 1)
self.image_pub.publish(self.red_bridge.cv2_to_imgmsg(frame, "bgr8"))
except CvBridgeError as e:
print(e)
return
def main(args):
ic = image_converter()
rospy.init_node('Color_Tracker', anonymous=True)
try:
rospy.spin()
except KeyboardInterrupt:
print("Shutting down")
cv2.destroyAllWindows()
if __name__ == '__main__':
main(sys.argv)

"no module named imutils" when it says imutils is installed?

I want to run this code on my Raspberry Pi 3. I have used pip install imutils on the Pi but, when I run the code via the CLI, it returns "No module named imutils". I do not wish to use virtual environments. I have cv2 running correctly on the Pi and that works no problem, is there a fix for this imutils problem?
Updating, upgrading, removing imutils but it is needed.
import numpy as np
import cv2
import Person
import time
import imutils
import datetime
cap = cv2.VideoCapture('testVideo.mp4')
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=True) # Create the background substractor
kernelOp = np.ones((3, 3), np.uint8)
kernelOp1 = np.ones((7, 7), np.uint8)
kernelOp2 = np.ones((5, 5), np.uint8)
kernelCl = np.ones((11, 11), np.uint8)
kernelCl1 = np.ones((20, 20), np.uint8)
kernelCl2 = np.ones((25, 25), np.uint8)
# Variables
font = cv2.FONT_HERSHEY_SIMPLEX
persons = []
max_p_age = 5
pid = 1
areaTH = 5000
w_margin = 50
h_margin = 50
wmax = 500
import pdb;
pdb.set_trace() # debuginimo pradzia
# Atvaizdavimo kintamieji
cnt_up = 0
cnt_down = 0
line_down_color = (255, 0, 0)
line_up_color = (0, 0, 255)
pts_L1 = np.array([[0, 320], [480, 320]])
pts_L2 = np.array([[0, 400], [480, 400]])
counter = 0
while (cap.isOpened()):
ret, frame = cap.read() # read a frame
frame = imutils.resize(frame, width=min(640, frame.shape[1]))
fgmask = fgbg.apply(frame) # Use the substractor
try:
ret, imBin = cv2.threshold(fgmask, 200, 255, cv2.THRESH_BINARY)
mask0 = cv2.morphologyEx(imBin, cv2.MORPH_OPEN, kernelOp2)
mask = cv2.morphologyEx(mask0, cv2.MORPH_CLOSE, kernelCl2)
except:
# if there are no more frames to show...
print('EOF')
break
maskOriginal = mask
_, contours0, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
########if contour is too big cut in half
mask2_flag = 0
for cnt in contours0:
area = cv2.contourArea(cnt)
if area > areaTH:
M = cv2.moments(cnt)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
x, y, w, h = cv2.boundingRect(cnt)
if w > wmax:
mask2 = cv2.line(mask, ((x + w / 2), 0), ((x + w / 2), 640), (0, 0, 0), 10)
mask2_flag = 1
if mask2_flag == 0:
mask2 = mask
cv2.imshow('Mask line', mask2)
cv2.imshow('mask to open', mask0)
cv2.imshow('Mask initialize', maskOriginal)
cv2.imshow('initial subtraction', imBin)
_, contours0, hierarchy = cv2.findContours(mask2, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
for cnt in contours0:
cv2.drawContours(frame, cnt, -1, (0, 255, 0), 3, 8)
area = cv2.contourArea(cnt)
for i in persons:
i.updateDingimas(i.getDingimas() + 1)
if i.getDingimas() > 25:
persons.remove(i)
if area > areaTH:
M = cv2.moments(cnt)
cx = int(M['m10'] / M['m00'])
cy = int(M['m01'] / M['m00'])
x, y, w, h = cv2.boundingRect(cnt)
print('x{} y{} w{} h{}'.format(x, y, w, h))
new = True
for i in persons:
if abs(x - i.getX()) <= w_margin and abs(y - i.getY()) <= h_margin:
new = False
i.updateCoords(cx, cy)
i.updateDingimas(0)
break
if new == True:
p = Person.MyPerson(pid, cx, cy, max_p_age)
persons.append(p)
pid += 1
cv2.circle(frame, (cx, cy), 5, (0, 0, 255), -1)
img = cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.drawContours(frame, cnt, -1, (0, 255, 0), 3)
cv2.imshow('img', img)
#########################
# Trajectory rendering
#########################
for i in persons:
if len(i.getTracks()) >= 2:
pts = np.array(i.getTracks(), np.int32)
pts = pts.reshape((-1, 1, 2))
frame = cv2.polylines(frame, [pts], False, i.getRGB())
if i.getDir() == None:
i.kurEina(pts_L2[0, 1], pts_L1[0, 1])
if i.getDir() == 'up':
cnt_up += 1
print('Timestamp: {:%H:%M:%S} UP {}'.format(datetime.datetime.now(), cnt_up))
elif i.getDir() == 'down':
cnt_down += 1
print('Timestamp: {:%H:%M:%S} DOWN {}'.format(datetime.datetime.now(), cnt_down))
cv2.putText(frame, str(i.getId()), (i.getX(), i.getY()), font, 0.7, i.getRGB(), 1, cv2.LINE_AA)
#########################
# Rendering
#########################
str_in = 'In: ' + str(cnt_up)
str_out = 'Out: ' + str(cnt_down)
frame = cv2.polylines(frame, [pts_L1], False, line_down_color, thickness=4)
frame = cv2.polylines(frame, [pts_L2], False, line_up_color, thickness=4)
cv2.putText(frame, str_in, (10, 50), font, 1, (0, 0, 255), 2, cv2.LINE_AA)
cv2.putText(frame, str_out, (10, 100), font, 1, (255, 0, 0), 2, cv2.LINE_AA)
cv2.imshow('Frame', frame)
# Abort and exit with 'Q' or ESC
k = cv2.waitKey(30) & 0xff
if k == 27:
break
cap.release() # release video file
cv2.destroyAllWindows() # close all openCV windows
I want to run this code without "No module named imutils" error.
If you intend to use the module with Python 3, you need to install it with pip3 so that it is installed in the correct location.

Categories

Resources