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.
Related
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)
....
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.
I'm trying to save the output imgCanny as an image/screenshot. How do I incorporate this so a screenshot of that window can be captured when a certain key is pressed. I am taking the live feed from the webcam and processing it. I would then like to be able to press a key on the keyboard to capture and save a screenshot of the imgCanny Window.
cap = cv2.VideoCapture(1)
cv2.waitKey(0)
cap.set(3, frameWidth)
cap.set(4, frameHeight)
def empty(a):
pass
cv2.namedWindow("Parameters")
cv2.resizeWindow("Parameters", 640, 240)
cv2.createTrackbar("Threshold1", "Parameters", 150, 500, empty)
cv2.createTrackbar("Threshold2", "Parameters", 255, 500, empty)
def getContours(img, imgContour):
contours, hierarchy = cv2.findContours(img, cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE) #retreival method. External, only extreme
outer contours
#change APPROX to simple for less points
#remove small bits of noise
for cnt in contours:
area = cv2.contourArea(cnt)
# Used to flatted the array containing
# the co-ordinates of the vertices.
approx = cv2.approxPolyDP(cnt, 0.009 * cv2.arcLength(cnt, True),
True)
n = approx.ravel()
i = 0
for j in n:
if (i % 2 == 0):
x = n[i]
y = n[i + 1]
# String containing the co-ordinates.
string = str(int(x / 3.5)) + " " + str(int(y / 3.5))
print(string)
if (i == 0):
# text on topmost co-ordinate.
cv2.putText(imgContour, "", (x, y),
font, 0.5, (255, 0, 0))
else:
# text on remaining co-ordinates.
cv2.putText(imgContour, string, (x, y),
font, 0.5, (0, 255, 0))
i = i + 1
if area > 3000:
cv2.drawContours(imgContour, cnt, -1, (255, 0, 255), 1)
peri = cv2.arcLength(cnt, True) #true means contour is closed
while True:
success, img = cap.read()
imgContour = img.copy()
imgBlur = cv2.GaussianBlur(img, (31, 31), 1)
imgGray = cv2.cvtColor(imgBlur, cv2.COLOR_BGR2GRAY)
threshold1 = cv2.getTrackbarPos("Threshold1", "Parameters")
threshold2 = cv2.getTrackbarPos("Threshold2", "Parameters")
imgCanny = cv2.Canny(imgGray, threshold1, threshold2)
kernel = np.ones((5, 5))
imgDil = cv2.dilate(imgCanny, kernel, iterations=1)
getContours(imgDil, imgContour)
#cv2.imshow("Results", img )
#cv2.imshow("Mask", imgGray)
cv2.imshow("Canny", imgCanny)
cv2.imshow("Dilated", imgContour)
cv2.imshow("Test", imgDil)
key = cv2.waitKey(100)
if key == 27: #kills with Esc
break
cap.release()
cv2.destroyAllWindows()
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)
I am building handwriting recognition project but I am getting this error of cvtColor while trying to change the image from BGR2HSV.
cap = cv2.VideoCapture(0)
Lower_blue = np.array([110, 50, 50])
Upper_blue = np.array([130, 255, 255])
pred_class = 0
pts = deque(maxlen = 512)
blackboard = np.zeros((480, 640, 3), dtype = np.uint8)
digit = np.zeros((200, 200, 3), dtype = np.uint8)
while(cap.isOpened()):
ret, img = cap.read()
img = cv2.flip(img, 1)
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(imgHSV, Lower_blue, Upper_blue)
blur = cv2.medianBlur(mask, 15)
blur = cv2.GaussianBlur(blur, (5, 5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[1]
center = None
if len(cnts) >= 1:
contour = max(cnts, key = cv2.contourArea)
if cv2.contourArea(contour) > 250:
((x, y), radius) = cv2.minEnclosingCircle(contour)
cv2.circle(img, (int(x), int(y)), int(radius), (0, 255, 255), 2)
cv2.circle(img, center, 5, (0, 255, 255), -1)
M = cv2.moments(contour)
center = (int(M['m10'] / M['m00']), int(M['m01'] / M['m00']))
pts.appendleft(center)
for i in range (1, len(pts)):
if pts[i - 1] is None or pts[i] is None:
continue
cv2.line(blackboard, pts[i - 1], pts[i], (255, 255, 255), 10)
cv2.line(img, pts[i - 1], pts[i], (0, 0,255), 5)
elif len(cnts) == 0:
if len(pts) != []:
blackboard_gray = cv2.cvtColor(blackboard, cv2.COLOR_BGR2GRAY)
blur1 = cv2.medianBlur(blackboard_gray, 15)
blur1 = cv2.GaussianBlur(blur1, (5, 5), 0)
thresh1 = cv2.threshold(blur1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
blackboard_cnts = cv2.findContours(thresh1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[1]
if len(blackboard_cnts) >= 1:
cnt = max(blackboard_cnts, key = cv2.contourArea)
print(cv2.contourArea(cnt))
if cv2.contourArea(cnt) > 2000:
x, y, w, h = cv2.boundingRect(cnt)
digit = blackboard_gray[y:y + h, x:x + w]
#new Image = process_letter(digit)
pred_probab, pred_class = keras_predict(model1, digit)
print(pred_class, pred_probab)
pts = deque(maxlen = 512)
blackboard = np.zeros((480, 640, 3), dtype = uint8)
cv2.putText(img, "Conv Network : " + str(letter_count [pred_class]), (10, 470),
cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.imshow("Frame", img)
cv2.imshow("Contours", thresh)
k = cv2.waitkey(10)
if k == 27:
break
How do I fix this issue of OpenCV error? Please help!
I am getting following error:
error: OpenCV(3.4.1) C:\Miniconda3\conda-bld\opencv-suite_1533128839831\work\modules\imgproc\src\color.cpp:11214: error: (-215) (scn == 3 || scn == 4) && (depth == 0 || depth == 5) in function cv::cvtColor
I think following error: error: (-215) (scn == 3 || scn == 4) && (depth == 0 || depth == 5) in function cv::cvtColor is because of camera unable to capture frame correctly. Check this by printing ret value. It camera is able to capture frame correctly, it will return True, else False. Above error is happening because None is passed to cv2.cvtColor function. You can use below code as a safety check:
if ret is True:
# your code goes here
else:
break
Moreover, please consider below points:
It's cv2.waitKey(10), not cv2.waitkey(10)[Capital 'K']
cv2.findContours function return 3 values(i.e. image, contours and hierarchy) in OpenCV 3.x but just 2 values(i.e. contours, hierarchy) in openCV 4.x
len(pts) != [] doesn't make sense. Here, you are trying to compare a number to an empty list. Change it to len(pts) != 0.
What's letter_count inside cv2.putText function. Kindly recheck it.
In place of re-initializing deque(pts = deque(maxlen = 512)) in case of len(cnts)==0 and len(pts) != 0, you can use the old pts by simply clearing it using pts.clear(). Just a thought!
Also, add below code at the end:
cap.release()
cv2.destroyAllWindows()
Try below modified code(Tested using openCV v4.0.0):
import cv2
import numpy as np
from collections import deque
cap = cv2.VideoCapture(0)
Lower_blue = np.array([110, 50, 50])
Upper_blue = np.array([130, 255, 255])
pred_class = 0
pts = deque(maxlen = 512)
blackboard = np.zeros((480, 640, 3), dtype = np.uint8)
digit = np.zeros((200, 200, 3), dtype = np.uint8)
while(cap.isOpened()):
ret, img = cap.read()
img = cv2.flip(img, 1)
imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(imgHSV, Lower_blue, Upper_blue)
blur = cv2.medianBlur(mask, 15)
blur = cv2.GaussianBlur(blur, (5, 5), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
cnts = cv2.findContours(thresh.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[0]
center = None
if len(cnts) >= 1:
contour = max(cnts, key = cv2.contourArea)
if cv2.contourArea(contour) > 250:
((x, y), radius) = cv2.minEnclosingCircle(contour)
cv2.circle(img, (int(x), int(y)), int(radius), (0, 255, 255), 2)
cv2.circle(img, center, 5, (0, 255, 255), -1)
M = cv2.moments(contour)
center = (int(M['m10'] / M['m00']), int(M['m01'] / M['m00']))
pts.appendleft(center)
# print(pts)
for i in range (1, len(pts)):
if pts[i - 1] is None or pts[i] is None:
print("Continue")
continue
cv2.line(blackboard, pts[i - 1], pts[i], (255, 255, 255), 10)
cv2.line(img, pts[i - 1], pts[i], (0, 0,255), 5)
cv2.imshow("Frame", img)
cv2.imshow("Contours", thresh)
# press q to stop
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
if len(pts) != 0:
blackboard_gray = cv2.cvtColor(blackboard, cv2.COLOR_BGR2GRAY)
blur1 = cv2.medianBlur(blackboard_gray, 15)
blur1 = cv2.GaussianBlur(blur1, (5, 5), 0)
thresh1 = cv2.threshold(blur1, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
print('Hello')
blackboard_cnts = cv2.findContours(thresh1.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)[0]
if len(blackboard_cnts) >= 1:
cnt = max(blackboard_cnts, key = cv2.contourArea)
print(cv2.contourArea(cnt))
if cv2.contourArea(cnt) > 2000:
x, y, w, h = cv2.boundingRect(cnt)
digit = blackboard_gray[y:y + h, x:x + w]
#new Image = process_letter(digit)
#pred_probab, pred_class = keras_predict(model1, digit)
print(digit.shape)
#pts = deque(maxlen = 512)
pts.clear()
blackboard = np.zeros((480, 640, 3), dtype = np.uint8)
#cv2.putText(img, "Conv Network : " + str(letter_count[pred_class]), (10, 470), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.putText(img, "Conv Network :", (10, 470), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2)
cv2.imshow("Frame", img)
cv2.imshow("Contours", thresh)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()