Opencv redraw image when values are changed - python

I have just started using OpenCV, I have been using harris corner detection function. I have written a script to look for black edges in a picture.
I have been struggling with implementing a slider to dynamically adjust the threshold of the image.
At the moment the slider only sets the value before the image is loaded. It does not get updated when changing the value by using the slider.
How would I go about getting the slider to continuously update the image when you move the slider?
Thanks in advance
from threading import Thread
import time
import numpy as np
import cv2
from matplotlib import pyplot as plt
import tkinter
import sys
slideVal =1
def showVal(value):
global slideVal
value = int(value)
print (type(value))
slideVal = value
def harrisCorn():
time.sleep(3)
print(slideVal)
print ("the current slider value is: ",slideVal)
img = cv2.imread('rawGun.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
#Changeing the value's in this function with : slideVal
dst = cv2.cornerHarris(gray,slideVal,3,0.04)
#result is dilated for marking the corners, not important
dst = cv2.dilate(dst,None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()]=[0,0,255]
imgSize = cv2.resize(img,(1000,1000))
cv2.imshow('dst', imgSize)
if cv2.waitKey(0) & 0xff:
cv2.destroyAllWindows()
def slider():
root = tkinter.Tk()
s = tkinter.Scale(orient='horizontal', from_=1, to=225, command=showVal)
s.pack()
root.mainloop()
if __name__ == '__main__':
Thread(target = slider).start()
time.sleep(3)
Thread(target = harrisCorn).start()

Actually you can use horrisCorn() as the command function of the slider so that whenever the slider is changed, the image is updated. Below changed code block is based on your code:
import numpy as np
import cv2
import tkinter
def harrisCorn(slideVal):
slideVal = int(slideVal)
print("the current slider value is: ", slideVal)
img = cv2.imread('rawGun.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = np.float32(gray)
#Changeing the value's in this function with : slideVal
dst = cv2.cornerHarris(gray, slideVal, 3, 0.04)
#result is dilated for marking the corners, not important
dst = cv2.dilate(dst, None)
# Threshold for an optimal value, it may vary depending on the image.
img[dst>0.01*dst.max()] = [0, 0, 255]
imgSize = cv2.resize(img, (1000, 1000))
cv2.imshow('dst', imgSize)
def slider():
root = tkinter.Tk()
tkinter.Scale(orient='horizontal', from_=1, to=225, command=harrisCorn).pack()
harrisCorn(1)
root.mainloop()
if __name__ == '__main__':
slider()

Related

How to change the camera input from column to row wise in streamlit

I have an app which get the input as web image and convert into cartoonic image but it displays the camera input and output in column wise instead of that i need side by side(row wise)
Don't know whether we can reduce the width of the camera.input??
Any idea would be appreciated!
import cv2
import streamlit as st
import numpy as np
from PIL import Image
import base64
from torch import square
def cartoonization (img):
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.medianBlur(gray, 7)
edges = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 7, 7)
blurred = cv2.bilateralFilter(img, d=7, sigmaColor=200,sigmaSpace=200)
cartoon = cv2.bitwise_and(blurred, blurred, mask=edges)
return cartoon
###############################################################################
file_image = st.camera_input(label = "Take a pic of you to be sketched out")
if file_image:
input_img = Image.open(file_image)
final_sketch = cartoonization(np.array(input_img))
st.write("**Output Pencil Sketch**")
one = st.columns(1)
st.image(final_sketch, use_column_width=True)
#with one:
# st.write("**Input Photo**")
#st.image(input_img, use_column_width=True)
#with one:
# st.write("**Output Pencil Sketch**")
# st.image(final_sketch, use_column_width=True)
else:
st.write("You haven't uploaded any image file")

Filter color in Ros, using Python and Gazebo

recently I was commissioned to use a robot already made in gazebo, using Ros which has a camera and I have been able to see that image through .py code. Now they ask me to filter colors (green, red and blue), I already have the high and low values, and I can do it with an image, but I don't know how to mix both programs, so that what is filtered by color, I only know what transmit the robot's camera and not an image.
All of this while using Open CV
Attached both codes
////////////////////////////////////////////////////////////////////////////////////////
Code to see the gazeebo virtual camera
////////////////////////////////////////////////////////////////////////////////////////
#!/usr/bin/env python
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2
bridge_object = CvBridge() # create the cv_bridge object
image_received = 0 #Flag to indicate that we have already received an image
cv_image = 0 #This is just to create the global variable cv_image
def show_image():
image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback)
r = rospy.Rate(10) #10Hz
while not rospy.is_shutdown():
if image_received:
cv2.waitKey(1)
r.sleep()
cv2.destroyAllWindows()
def camera_callback(data):
global bridge_object
global cv_image
global image_received
image_received=1
try:
print("received ROS image, I will convert it to opencv")
# We select bgr8 because its the OpenCV encoding by default
cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8")
#Add your code to save the image here:
#Save the image "img" in the current path
cv2.imwrite('robot_image.jpg', cv_image)
#Display the image in a window
cv2.imshow('Image from robot camera', cv_image)
except CvBridgeError as e:
print(e)
if __name__ == '__main__':
rospy.init_node('load_image', anonymous=True)
show_image()
////////////////////////////////////////////////////////////////////////////////////////
code to see an image segmented in RGB by windows
////////////////////////////////////////////////////////////////////////////////////////
#!/usr/bin/env python
import rospy
from sensor_msgs.msg import Image
#Import the numpy library which will help with some matrix operations
import numpy as np
from cv_bridge import CvBridge, CvBridgeError
import cv2
bridge_object = CvBridge() # create the cv_bridge object
image_received = 0 #Flag to indicate that we have already received an image
cv_image = 0 #This is just to create the global variable cv_image
def show_image():
image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback)
r = rospy.Rate(10) #10Hz
image = cv2.imread('/home/user/catkin_ws/src/opencv_for_robotics_images/Unit_2/Course_images/Filtering.png')
while not rospy.is_shutdown():
#I resized the image so it can be easier to work with
image = cv2.resize(image,(300,300))
#Once we read the image we need to change the color space to HSV
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
#Hsv limits are defined
#here is where you define the range of the color you're looking for
#each value of the vector corresponds to the H,S & V values respectively
min_green = np.array([50,220,220])
max_green = np.array([60,255,255])
min_red = np.array([170,220,220])
max_red = np.array([180,255,255])
min_blue = np.array([110,220,220])
max_blue = np.array([120,255,255])
#This is the actual color detection
#Here we will create a mask that contains only the colors defined in your limits
#This mask has only one dimension, so its black and white }
mask_g = cv2.inRange(hsv, min_green, max_green)
mask_r = cv2.inRange(hsv, min_red, max_red)
mask_b = cv2.inRange(hsv, min_blue, max_blue)
#We use the mask with the original image to get the colored post-processed image
res_b = cv2.bitwise_and(image, image, mask= mask_b)
res_g = cv2.bitwise_and(image,image, mask= mask_g)
res_r = cv2.bitwise_and(image,image, mask= mask_r)
cv2.imshow('Green',res_g)
cv2.imshow('Red',res_b)
cv2.imshow('Blue',res_r)
cv2.imshow('Original',image)
cv2.waitKey(1)
r.sleep()
cv2.destroyAllWindows()
def camera_callback(data):
global bridge_object
global cv_image
global image_received
image_received=1
try:
print("received ROS image, I will convert it to opencv")
# We select bgr8 because its the OpenCV encoding by default
cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8")
except CvBridgeError as e:
print(e)
if __name__ == '__main__':
rospy.init_node('opencv_example1', anonymous=True)
show_image()
First of all there a lot structural problems in that code. You should consider using Classes and follow the ROS philosophy by implementing separates nodes that communicates with each other. Please take a look also to the rospy tutorials.
To "mix" both programs you can either create a function that processes the color in your first program that receives the image
def process_image(image):
image = cv2.resize(image,(300,300))
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
min_green = np.array([50,220,220])
max_green = np.array([60,255,255])
min_red = np.array([170,220,220])
max_red = np.array([180,255,255])
min_blue = np.array([110,220,220])
max_blue = np.array([120,255,255])
mask_g = cv2.inRange(hsv, min_green, max_green)
mask_r = cv2.inRange(hsv, min_red, max_red)
mask_b = cv2.inRange(hsv, min_blue, max_blue)
res_b = cv2.bitwise_and(image, image, mask= mask_b)
res_g = cv2.bitwise_and(image,image, mask= mask_g)
res_r = cv2.bitwise_and(image,image, mask= mask_r)
cv2.imshow('Green',res_g)
cv2.imshow('Red',res_b)
cv2.imshow('Blue',res_r)
cv2.imshow('Original',image)
cv2.waitKey(1)
And calling it once every time you receive an image (inside the callback). Usually it's preferable to divide all this processing in multiple threads, but, as a start point you could use something like this:
#!/usr/bin/env python
import rospy
from sensor_msgs.msg import Image
from cv_bridge import CvBridge, CvBridgeError
import cv2
bridge_object = CvBridge() # create the cv_bridge object
image_received = 0 #Flag to indicate that we have already received an image
cv_image = 0 #This is just to create the global variable cv_image
def show_image():
image_sub = rospy.Subscriber("/two_wheels_robot/camera1/image_raw",Image,camera_callback)
r = rospy.Rate(10) #10Hz
while not rospy.is_shutdown():
if image_received:
cv2.waitKey(1)
r.sleep()
cv2.destroyAllWindows()
def process_image(image):
image = cv2.resize(image,(300,300))
hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
min_green = np.array([50,220,220])
max_green = np.array([60,255,255])
min_red = np.array([170,220,220])
max_red = np.array([180,255,255])
min_blue = np.array([110,220,220])
max_blue = np.array([120,255,255])
mask_g = cv2.inRange(hsv, min_green, max_green)
mask_r = cv2.inRange(hsv, min_red, max_red)
mask_b = cv2.inRange(hsv, min_blue, max_blue)
res_b = cv2.bitwise_and(image, image, mask= mask_b)
res_g = cv2.bitwise_and(image,image, mask= mask_g)
res_r = cv2.bitwise_and(image,image, mask= mask_r)
cv2.imshow('Green',res_g)
cv2.imshow('Red',res_b)
cv2.imshow('Blue',res_r)
cv2.imshow('Original',image)
cv2.waitKey(1)
def camera_callback(data):
global bridge_object
global cv_image
global image_received
image_received=1
try:
print("received ROS image, I will convert it to opencv")
# We select bgr8 because its the OpenCV encoding by default
cv_image = bridge_object.imgmsg_to_cv2(data, desired_encoding="bgr8")
#Add your code to save the image here:
#Save the image "img" in the current path
cv2.imwrite('robot_image.jpg', cv_image)
## Calling the processing function
process_image(cv_image)
cv2.imshow('Image from robot camera', cv_image)
except CvBridgeError as e:
print(e)
if __name__ == '__main__':
rospy.init_node('load_image', anonymous=True)
show_image()
You should also avoid declaring globals variables inside a function.

PIL.ImageTk.PhotoImage stored in RAM appears as black square on Tkinter

Ok so I'm trying to reproduce a raycaster with Python. All things done, now I've got a 512x512 matrix coded as 8-bit colors, that I try rendering through Tkinter.
Problem is, after doing a bit of conversion with Pillow, the image appears roughly half-sized, but most importantly as a black square. I'm sure it's some kind of misuse of a function, but i can't find which. Here's the code :
from PIL import Image, ImageTk
import tkinter as Tk
import matplotlib.pyplot as plt, numpy as np
fen = Tk.Tk()
img = plt.imread('BG0.png')
canvas = Tk.Canvas(fen, width = 512, height = 512)
canvas.pack()
def Up(event):
global img
i = np.finfo(img.dtype)
img = img.astype(np.float64)/i.max
img = 255 * img
img = img.astype(np.uint8)
img = ImageTk.PhotoImage(Image.fromarray(img))
canvas.create_image(0, 0, image = img, anchor = Tk.NW)
fen.bind_all('<Up>', Up)
fen.mainloop()
And here's that famous image we're looking to show (but actually, any 512x512 image could do the trick i'd say), just put it in the same folder as this program:
BG0.png
You just have to press the up arrow key on your keybord to have it render in the tkinter window.
It's a PIL and Tkinter bug.
The image that ImageTk returns must to be stored in a variable, or a list.
You can try to pop one image from the list and it will disappear.
Here is what you can do.
from PIL import Image, ImageTk
import tkinter as Tk
import matplotlib.pyplot as plt, numpy as np
fen = Tk.Tk()
img = plt.imread('BG0.png')
canvas = Tk.Canvas(fen, width = 512, height = 512)
canvas.pack()
# THIS IS NEEDED
images_tk_list = []
def Up(event):
global img
i = np.finfo(img.dtype)
img = img.astype(np.float64)/i.max
img = 255 * img
img = img.astype(np.uint8)
img = ImageTk.PhotoImage(Image.fromarray(img))
# THIS IS NEEDED
images_tk_list.append( img )
canvas.create_image(0, 0, image = img, anchor = Tk.NW)
fen.bind_all('<Up>', Up)
fen.mainloop()

How to use OpenCV video capture with custom video input?

I am trying to use the LK Optical Flow from this tutorial, to get some motion estimation into a robot simulation made with ROS+Gazebo.
I could manage to make properly the bridge between ROS and OpenCV via cv_bridge, as per the code below, and could implement some sample features which work "frame-by-frame" without major issues.
However, the optical flow tutorial reference seems to accept only video inputs, such as webcam and/or saved video files, and this is where I got stuck.
How could I apply the LK Optical flow in a "frame-by-frame" approach, or configure my cv_bridge to act as a "custom" camera device?
This is my cv_brige so far:
#!/usr/bin/env python
import roslib
import rospy
import sys
import cv2
import numpy as np
from sensor_msgs.msg import Image, CameraInfo
from cv_bridge import CvBridge, CvBridgeError
class OpticalFlow(object):
def __init__(self):
#Setting up the bridge and the subscriber
self.bridge = CvBridge()
self.image_sub = rospy.Subscriber("/realsense/color/image_raw", Image,self.image_callback)
# Parameters for Good Features Detection
self.feature_params = dict( maxCorners = 100,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7 )
# Parameters for Lucas-Kanade optical flow
self.lk_params = dict( winSize = (150,150),
maxLevel = 2,
criteria = (cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03))
# Create some random colors for the tracking points
self.color = np.random.randint(0,255,(100,3))
def image_callback(self,ros_image):
# Using cv_bridge() to convert the ROS image to OpenCV format
try:
cv_image = self.bridge.imgmsg_to_cv2(ros_image, "bgr8")#bgr8
hsv_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2HSV)
gray = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY)
except CvBridgeError as e:
print(e)
cv2.imshow("Robot Image", cv_image) # The actual (non-processed image from the simulation/robot)
#cv2.imshow('Image HSV', hsv_image)
#cv2.imshow('Image Gray', gray)
frame = np.array(cv_image, dtype=np.uint8)
# Calling the Optical Flow Function
display = self.optical_flow(frame,self.feature_params,self.lk_params,self.color)
def optical_flow(self,frame,feature_params,lk_params,color):
old_frame = frame
old_gray = cv2.cvtColor(old_frame, cv2.COLOR_BGR2GRAY)
p0 = cv2.goodFeaturesToTrack(old_gray, mask = None, **feature_params)
mask = np.zeros_like(old_frame)
while(1):
newframe = frame
frame_gray = cv2.cvtColor(newframe, cv2.COLOR_BGR2GRAY)
# Calculating the optical flow
p1, st, err = cv2.calcOpticalFlowPyrLK(old_gray, frame_gray, p0, None, **lk_params)
# Select good points
good_new = p1[st==1]
good_old = p0[st==1]
# Draw the tracks
for i,(new,old) in enumerate(zip(good_new, good_old)):
a,b = new.ravel()
c,d = old.ravel()
mask = cv2.line(mask, (a,b),(c,d), color[i].tolist(), 2)
frame = cv2.circle(frame,(a,b),5,color[i].tolist(),-1)
img = cv2.add(frame,mask)
cv2.imshow('LK_Flow',img)
k = cv2.waitKey(30) & 0xff
if k == 27:
break
# Now update the previous frame and previous points
old_gray = frame_gray.copy()
p0 = good_new.reshape(-1,1,2)
def main():
optical_flow_object = OpticalFlow()
rospy.init_node('KLT_Node', anonymous=True)
rospy.loginfo("\nWaiting for image topics...\n...")
try:
rospy.spin()
except KeyboardInterrupt:
rospy.loginfo("\nShutting Down...\n...")
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
I also would like to know, if possible, where I can find more information about how to manipulate those parameters (from the tutorial):
# params for ShiTomasi corner detection
feature_params = dict( maxCorners = 100,
qualityLevel = 0.3,
minDistance = 7,
blockSize = 7 )
# Parameters for lucas kanade optical flow
lk_params = dict( winSize = (15,15),
maxLevel = 2,
criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
I would recommend using cv2.calcOpticalFlowPyrLK(old_frame, cur_frame, ...) or cv2.calcOpticalFlowFarneback(old_frame, cur_frame, ...) (dense optical flow). There is a bunch of information about these methods on the cv2 website. From personal experience, these methods work great!
Let me know if you have any questions or problems!

How can I use tensorflow lite to detect specific object without retraining

I'm trying to use tensorflow lite in raspberry pi to detect specific category (motorcycle only) using the pre-trained model. Since the motorcycle category is already existing in the pre-trained model, I assume that I don't need any to retrain it. Is there anyway to remove other objects in the model? I am using the code from Edje Electronics provided by this link: https://github.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi
'''
# Import packages
import os
import argparse
import cv2
import numpy as np
import sys
import time
from threading import Thread
import importlib.util
from utils import label_map_util
from utils import visualization_utils as vis_util
# Define VideoStream class to handle streaming of video from webcam in separate processing thread
class VideoStream:
"""Camera object that controls video streaming from the Picamera"""
def __init__(self,resolution=(640,480),framerate=30):
# Initialize the PiCamera and the camera image stream
self.stream = cv2.VideoCapture(0)
ret = self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
ret = self.stream.set(3,resolution[0])
ret = self.stream.set(4,resolution[1])
# Read first frame from the stream
(self.grabbed, self.frame) = self.stream.read()
# Variable to control when the camera is stopped
self.stopped = False
def start(self):
# Start the thread that reads frames from the video stream
Thread(target=self.update,args=()).start()
return self
def update(self):
# Keep looping indefinitely until the thread is stopped
while True:
# If the camera is stopped, stop the thread
if self.stopped:
# Close camera resources
self.stream.release()
return
# Otherwise, grab the next frame from the stream
(self.grabbed, self.frame) = self.stream.read()
def read(self):
# Return the most recent frame
return self.frame
def stop(self):
# Indicate that the camera and thread should be stopped
self.stopped = True
# Define and parse input arguments
parser = argparse.ArgumentParser()
parser.add_argument('--modeldir', help='Folder the .tflite file is located in',
required=True)
parser.add_argument('--graph', help='Name of the .tflite file, if different than detect.tflite',
default='detect.tflite')
parser.add_argument('--labels', help='Name of the labelmap file, if different than labelmap.txt',
default='labelmap.txt')
parser.add_argument('--threshold', help='Minimum confidence threshold for displaying detected objects',
default=0.5)
parser.add_argument('--resolution', help='Desired webcam resolution in WxH. If the webcam does not support the resolution entered, errors may occur.',
default='1280x720')
parser.add_argument('--edgetpu', help='Use Coral Edge TPU Accelerator to speed up detection',
action='store_true')
args = parser.parse_args()
MODEL_NAME = args.modeldir
GRAPH_NAME = args.graph
LABELMAP_NAME = args.labels
min_conf_threshold = float(args.threshold)
resW, resH = args.resolution.split('x')
imW, imH = int(resW), int(resH)
use_TPU = args.edgetpu
# Import TensorFlow libraries
# If tflite_runtime is installed, import interpreter from tflite_runtime, else import from regular tensorflow
# If using Coral Edge TPU, import the load_delegate library
pkg = importlib.util.find_spec('tflite_runtime')
if pkg:
from tflite_runtime.interpreter import Interpreter
if use_TPU:
from tflite_runtime.interpreter import load_delegate
else:
from tensorflow.lite.python.interpreter import Interpreter
if use_TPU:
from tensorflow.lite.python.interpreter import load_delegate
# If using Edge TPU, assign filename for Edge TPU model
if use_TPU:
# If user has specified the name of the .tflite file, use that name, otherwise use default 'edgetpu.tflite'
if (GRAPH_NAME == 'detect.tflite'):
GRAPH_NAME = 'edgetpu.tflite'
# Get path to current working directory
CWD_PATH = os.getcwd()
# Path to .tflite file, which contains the model that is used for object detection
PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,GRAPH_NAME)
# Path to label map file
PATH_TO_LABELS = os.path.join(CWD_PATH,MODEL_NAME,LABELMAP_NAME)
# Load the label map
with open(PATH_TO_LABELS, 'r') as f:
labels = [line.strip() for line in f.readlines()]
# Have to do a weird fix for label map if using the COCO "starter model" from
# https://www.tensorflow.org/lite/models/object_detection/overview
# First label is '???', which has to be removed.
if labels[0] == '???':
del(labels[0])
# Load the Tensorflow Lite model.
# If using Edge TPU, use special load_delegate argument
if use_TPU:
interpreter = Interpreter(model_path=PATH_TO_CKPT,
experimental_delegates=[load_delegate('libedgetpu.so.1.0')])
print(PATH_TO_CKPT)
else:
interpreter = Interpreter(model_path=PATH_TO_CKPT)
interpreter.allocate_tensors()
# Get model details
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]
floating_model = (input_details[0]['dtype'] == np.float32)
input_mean = 127.5
input_std = 127.5
# Initialize frame rate calculation
frame_rate_calc = 1
freq = cv2.getTickFrequency()
# Initialize video stream
videostream = VideoStream(resolution=(imW,imH),framerate=30).start()
time.sleep(1)
#for frame1 in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
while True:
# Start timer (for calculating frame rate)
t1 = cv2.getTickCount()
# Grab frame from video stream
frame1 = videostream.read()
# Acquire frame and resize to expected shape [1xHxWx3]
frame = frame1.copy()
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_resized = cv2.resize(frame_rgb, (width, height))
input_data = np.expand_dims(frame_resized, axis=0)
# Normalize pixel values if using a floating model (i.e. if model is non-quantized)
if floating_model:
input_data = (np.float32(input_data) - input_mean) / input_std
# Perform the actual detection by running the model with the image as input
interpreter.set_tensor(input_details[0]['index'],input_data)
interpreter.invoke()
# Retrieve detection results
boxes = interpreter.get_tensor(output_details[0]['index'])[0] # Bounding box coordinates of detected objects
classes = interpreter.get_tensor(output_details[1]['index'])[0] # Class index of detected objects
scores = interpreter.get_tensor(output_details[2]['index'])[0] # Confidence of detected objects
#num = interpreter.get_tensor(output_details[3]['index'])[0] # Total number of detected objects (inaccurate and not needed)
# Loop over all detections and draw detection box if confidence is above minimum threshold
for i in range(len(scores)):
if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):
# Get bounding box coordinates and draw box
# Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
ymin = int(max(1,(boxes[i][0] * imH)))
xmin = int(max(1,(boxes[i][1] * imW)))
ymax = int(min(imH,(boxes[i][2] * imH)))
xmax = int(min(imW,(boxes[i][3] * imW)))
cv2.rectangle(frame, (xmin,ymin), (xmax,ymax), (10, 255, 0), 2)
# Draw label
object_name = labels[int(classes[i])] # Look up object name from "labels" array using class index
label = '%s: %d%%' % (object_name, int(scores[i]*100)) # Example: 'person: 72%'
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) # Get font size
label_ymin = max(ymin, labelSize[1] + 10) # Make sure not to draw label too close to top of window
cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) # Draw white box to put label text in
cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) # Draw label text
# Draw framerate in corner of frame
cv2.putText(frame,'FPS: {0:.2f}'.format(frame_rate_calc),(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)
# All the results have been drawn on the frame, so it's time to display it.
cv2.imshow('Object detector', frame)
# Calculate framerate
t2 = cv2.getTickCount()
time1 = (t2-t1)/freq
frame_rate_calc= 1/time1
# Press 'q' to quit
if cv2.waitKey(1) == ord('q'):
break
# Clean up
cv2.destroyAllWindows()
videostream.stop()
'''
I've solved my own problem by adding these lines of code inside the for loop.
for i in range(len(scores)):
if classes[i] != 3:
scores[i]=0
if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):
NOTE: number 3 represents the motorcycle label in the labelmap

Categories

Resources