-
Notifications
You must be signed in to change notification settings - Fork 9
/
color_picker.py
executable file
·178 lines (147 loc) · 6.05 KB
/
color_picker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import logging
import time
import arc852.camera as camera
import arc852.cli_args as cli
import arc852.opencv_defaults as defs
import cv2
import imutils
import numpy as np
from arc852.cli_args import LOG_LEVEL
from arc852.cli_args import setup_cli_args
from arc852.image_server import ImageServer
from arc852.opencv_utils import GREEN
from arc852.opencv_utils import RED
from arc852.utils import setup_logging
from arc852.utils import strip_loglevel
logger = logging.getLogger(__name__)
class ColorPicker(object):
roi_size = 24
orig_roi_size = roi_size
roi_inc = 6
move_inc = 4
x_adj = 0
y_adj = 0
def __init__(self,
width,
usb_camera,
flip_x,
flip_y,
display,
http_host,
http_file,
http_delay_secs,
http_verbose):
self.__width = width
self.__usb_camera = usb_camera
self.__flip_x = flip_x
self.__flip_y = flip_y
self.__display = display
self.__orig_width = self.__width
self.__cam = camera.Camera(usb_camera=usb_camera)
self.__image_server = ImageServer(http_file,
camera_name="Color Picker",
http_host=http_host,
http_delay_secs=http_delay_secs,
http_verbose=http_verbose)
# Do not run this in a background thread. cv2.waitKey has to run in main thread
def start(self):
self.__image_server.start()
cnt = 0
while self.__cam.is_open():
image = self.__cam.read()
if image is None:
logger.error("Null image read from camera")
time.sleep(.5)
continue
image = imutils.resize(image, width=self.__width)
if self.__flip_x:
image = cv2.flip(image, 0)
if self.__flip_y:
image = cv2.flip(image, 1)
height, width = image.shape[:2]
roi_x = int((width / 2) - (self.roi_size / 2) + self.x_adj)
roi_y = int((height / 2) - (self.roi_size / 2) + self.y_adj)
roi = image[roi_y:roi_y + self.roi_size, roi_x:roi_x + self.roi_size]
roi_h, roi_w = roi.shape[:2]
roi_canvas = np.zeros((roi_h, roi_w, 3), dtype="uint8")
roi_canvas[0:roi_h, 0:roi_w] = roi
# Calculate averge color in ROI
avg_color_per_row = np.average(roi_canvas, axis=0)
avg_color = np.average(avg_color_per_row, axis=0)
avg_color = np.uint8(avg_color)
# Draw a rectangle around the sample area
cv2.rectangle(image, (roi_x, roi_y), (roi_x + self.roi_size, roi_y + self.roi_size), GREEN, 1)
# Add text info
bgr_text = "BGR value: [{0}, {1}, {2}]".format(avg_color[0], avg_color[1], avg_color[2])
roi_text = " ROI: {0}x{1} ".format(str(self.roi_size), str(self.roi_size))
cv2.putText(image, bgr_text + roi_text, defs.TEXT_LOC, defs.TEXT_FONT, defs.TEXT_SIZE, RED, 1)
# Overlay color swatch on image
size = int(width * 0.20)
image[height - size:height, width - size:width] = avg_color
cnt += 1
# if self.__image_server.enabled and cnt % 30 == 0:
if cnt % 30 == 0:
logger.info(bgr_text)
self.__image_server.image = image
if self.__display:
# Display image
cv2.imshow("Image", image)
key = cv2.waitKey(30) & 0xFF
if key == 255:
pass
elif key == ord("c") or key == ord(" "):
print(bgr_text)
elif roi_y >= self.move_inc and (key == 0 or key == ord("k")): # Up
self.y_adj -= self.move_inc
elif roi_y <= height - self.roi_size - self.move_inc and (key == 1 or key == ord("j")): # Down
self.y_adj += self.move_inc
elif roi_x >= self.move_inc and (key == 2 or key == ord("h")): # Left
self.x_adj -= self.move_inc
elif roi_x <= width - self.roi_size - self.move_inc - self.move_inc \
and (key == 3 or key == ord("l")): # Right
self.x_adj += self.move_inc
elif self.roi_size >= self.roi_inc * 2 and (key == ord("-") or key == ord("_")):
self.roi_size -= self.roi_inc
self.x_adj, self.y_adj = 0, 0
elif self.roi_size <= self.roi_inc * 49 and (key == ord("+") or key == ord("=")):
self.roi_size += self.roi_inc
self.x_adj, self.y_adj = 0, 0
elif key == ord("r"):
self.__width = self.__orig_width
self.roi_size = self.orig_roi_size
elif key == ord("<"):
self.__width -= 10
elif key == ord(">"):
self.__width += 10
elif key == ord("q"):
self.__cam.close()
break
def stop(self):
self.__image_server.stop()
def main():
# Parse CLI args
args = setup_cli_args(cli.width,
cli.usb_camera,
# cli.usb_port,
cli.display,
cli.flip_x,
cli.flip_y,
cli.http_host,
cli.http_file,
cli.http_delay_secs,
cli.http_verbose,
cli.log_level)
# Setup logging
setup_logging(level=args[LOG_LEVEL])
color_picker = ColorPicker(**strip_loglevel(args))
try:
color_picker.start()
except KeyboardInterrupt:
pass
finally:
color_picker.stop()
logger.info("Exiting...")
if __name__ == "__main__":
main()