Files
kick-it/scripts/colorpicker.py
Pavel Lutskov 79f9b587db Started overall project refactoring
1. Git will now be ignoring files whose names start with `exp_`.
   If you want to do quick experimenting but are not ready to add
   such files to repository, name them starting with `exp_`. For
   example `exp_cool_motion.py`.
2  Use the file `nao_defaults.json` to store the global project
   settings (such as IP address of the robot, or our preferred
   resolution). In your scripts make sure to load the default
   values from that file if needed (i.e. do NOT hard-code any
   configuration in your scripts). `nao_defaults.json` is a file
   with the stable config. If you need to experiment with configs,
   create a file `exp_config.json`.
3. Colorpicker is now a saner tool (you can specify output width, and
   the default IP address of the nao is pulled from the JSON config
   file).
2018-06-03 13:45:53 +02:00

173 lines
5.2 KiB
Python

from __future__ import print_function
from __future__ import division
import json
import argparse
import cv2
from imagereaders import VideoReader, NaoImageReader, PictureReader
# import imutils
class Colorpicker(object):
WINDOW_CAPTURE_NAME = 'Video Capture'
WINDOW_DETECTION_NAME = 'Object Detection'
def __init__(self):
parameters = ['low_h', 'low_s', 'low_v', 'high_h', 'high_s', 'high_v']
maxes = [180, 255, 255, 180, 255, 255]
checkers = [
lambda x: min(x, self.settings['high_h'] - 1), # LOW H
lambda x: min(x, self.settings['high_s'] - 1), # LOW S
lambda x: min(x, self.settings['high_v'] - 1), # LOW H
lambda x: max(x, self.settings['low_h'] + 1), # HIGH H
lambda x: max(x, self.settings['low_s'] + 1), # HIGH S
lambda x: max(x, self.settings['low_v'] + 1), # HIGH V
]
self.settings = {
'low_h': 0,
'low_s': 0,
'low_v': 0,
'high_h': 180,
'high_s': 255,
'high_v': 255
}
cv2.namedWindow(self.WINDOW_CAPTURE_NAME)
cv2.namedWindow(self.WINDOW_DETECTION_NAME)
self.trackers = [
cv2.createTrackbar(
name, self.WINDOW_DETECTION_NAME, self.settings[name], max_v,
lambda val, name=name, checker=checker: self._on_trackbar(
val, name, checker
)
)
for name, max_v, checker in zip(parameters, maxes, checkers)
]
def do_print(self):
print(self.settings)
def _on_trackbar(self, val, name, checker):
self.settings[name] = checker(val)
cv2.setTrackbarPos(name, self.WINDOW_DETECTION_NAME,
self.settings[name])
def show_frame(self, frame, width=None):
frame_HSV = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
frame_threshold = cv2.inRange(
frame_HSV,
tuple(map(self.settings.get, ('low_h', 'low_s', 'low_v'))),
tuple(map(self.settings.get, ('high_h', 'high_s', 'high_v')))
)
if width:
sf = width / frame.shape[1]
frame = cv2.resize(frame, (0, 0), fx=sf, fy=sf)
frame_threshold = cv2.resize(frame_threshold, (0, 0), fx=sf, fy=sf)
cv2.imshow(self.WINDOW_CAPTURE_NAME, frame)
cv2.imshow(self.WINDOW_DETECTION_NAME, frame_threshold)
return cv2.waitKey(1)
def save(self, filename):
with open(filename, 'w') as f:
json.dump(self.settings, f, indent=4)
def load(self, filename):
with open(filename) as f:
self.settings = json.load(f)
for name in self.settings:
cv2.setTrackbarPos(name, self.WINDOW_DETECTION_NAME,
self.settings[name])
if __name__ == '__main__':
with open('nao_defaults.json') as f:
defaults = json.load(f)
parser = argparse.ArgumentParser(
epilog='When called without arguments specifying the video source, ' +
'will try to use the webcam'
)
parser.add_argument(
'-o', '--output-config',
help='file, to which the settings will be saved (if given)'
)
parser.add_argument(
'-i', '--input-config',
help='file, from which to read the initial values'
)
imsource = parser.add_mutually_exclusive_group()
imsource.add_argument(
'--video-file',
help='video file to use'
)
imsource.add_argument(
'--image-file',
help='image to use'
)
imsource.add_argument(
'--nao-ip',
help='ip address of the nao robot, from which to capture',
default=False,
const=defaults['ip'],
nargs='?'
)
parser.add_argument(
'--still',
help='only take one image from video stream',
action='store_true'
)
parser.add_argument(
'--nao-cam',
choices=[0, 1],
help='0 for top camera, 1 for bottom camera',
default=defaults['cam']
)
parser.add_argument(
'--nao-res',
choices=[1, 2, 3],
help='choose a nao resolution',
type=int,
default=defaults['res']
)
parser.add_argument(
'--width',
help='specify width of the image output',
type=int,
default=640
)
args = parser.parse_args()
cp = Colorpicker()
if args.input_config:
cp.load(args.input_config)
if args.video_file:
rdr = VideoReader(args.video_file, loop=True)
elif args.image_file:
rdr = PictureReader(args.image_file)
elif args.nao_ip:
rdr = NaoImageReader(
args.nao_ip,
cam_id=args.nao_cam,
res=args.nao_res
)
else:
rdr = VideoReader(0)
try:
if args.still:
frame = rdr.get_frame()
rdr.close()
while True:
if not args.still:
frame = rdr.get_frame()
key = cp.show_frame(frame, args.width)
if key == ord('q') or key == 27:
break
finally:
cp.do_print()
if args.output_config:
cp.save(args.output_config)
if not args.still:
rdr.close()