6 import matplotlib.pyplot
as plt
7 import matplotlib.animation
as animation
9 from sklearn
import linear_model
20 from sensor_msgs.msg
import Image
21 from cv_bridge
import CvBridge, CvBridgeError
32 lock = threading.Lock()
39 MODELS = [
"linear",
"quadratic",
"quadratic-uv",
"quadratic-uv-abs",
"quadratic-uv-quadratic",
"quadratic-uv-quadratic-abs"]
42 """Ask a yes/no question via raw_input() and return their answer. 44 "question" is a string that is presented to the user. 45 "default" is the presumed answer if the user just hits <Enter>. 46 It must be "yes" (the default), "no" or None (meaning 47 an answer is required of the user). 49 The "answer" return value is one of "yes" or "no". 51 valid = {
"yes":
True,
"y":
True,
"ye":
True,
52 "no":
False,
"n":
False}
55 elif default ==
"yes":
60 raise ValueError(
"invalid default answer: '%s'" % default)
63 sys.stdout.write(question + prompt)
64 choice = raw_input().lower()
65 if default
is not None and choice ==
'':
70 sys.stdout.write(
"Please respond with 'yes' or 'no' " 77 elif model ==
"quadratic":
79 elif model ==
"quadratic-uv" or model ==
"quadratic-uv-abs":
81 elif model ==
"quadratic-uv-quadratic" or model ==
"quadratic-uv-quadratic-abs":
91 elif model ==
"quadratic":
93 elif model ==
"quadratic-uv":
94 return [u * x2, v * x2, x2,
97 elif model ==
"quadratic-uv-abs":
100 return [u * x2, v * x2, x2,
103 elif model ==
"quadratic-uv-quadratic":
104 return [u2 * x2, u * x2, v2 * x2, v * x2, x2,
105 u2 * x, u * x, v2 * x, v * x, x,
107 elif model ==
"quadratic-uv-quadratic-abs":
112 return [u2 * x2, u * x2, v2 * x2, v * x2, x2,
113 u2 * x, u * x, v2 * x, v * x, x,
119 c0 = classifier.intercept_
120 return not hasattr(c0,
"__len__");
125 c0 = classifier.intercept_
126 param = DepthCalibrationParameter()
128 print(
"parameters are list")
130 if model ==
"linear":
131 param.coefficients2 = [0, 0, 0, 0, 0]
132 param.coefficients1 = [0, 0, 0, 0, c[0]]
133 param.coefficients0 = [0, 0, 0, 0, c0]
134 param.use_abs =
False 135 elif model ==
"quadratic":
136 param.coefficients2 = [0, 0, 0, 0, c[0]]
137 param.coefficients1 = [0, 0, 0, 0, c[1]]
138 param.coefficients0 = [0, 0, 0, 0, c0]
139 param.use_abs =
False 140 elif model ==
"quadratic-uv":
141 param.coefficients2 = [0, c[0], 0, c[1], c[2]]
142 param.coefficients1 = [0, c[3], 0, c[4], c[5]]
143 param.coefficients0 = [0, c[6], 0, c[7], c0]
144 param.use_abs =
False 145 elif model ==
"quadratic-uv-abs":
146 param.coefficients2 = [0, c[0], 0, c[1], c[2]]
147 param.coefficients1 = [0, c[3], 0, c[4], c[5]]
148 param.coefficients0 = [0, c[6], 0, c[7], c0]
150 elif model ==
"quadratic-uv-quadratic":
151 param.coefficients2 = c[0:5]
152 param.coefficients1 = c[5:10]
153 param.coefficients0 = [c[10], c[11], c[12], c[13], c0]
154 param.use_abs =
False 155 elif model ==
"quadratic-uv-quadratic-abs":
156 param.coefficients2 = c[0:5]
157 param.coefficients1 = c[5:10]
158 param.coefficients0 = [c[10], c[11], c[12], c[13], c0]
163 global xs, ys, classifier, u_min, u_max, v_min, v_max, raw_xs
167 if value_cache.has_key((uu, vv)):
168 zs = value_cache[(uu, vv)]
170 if abs(z - y) < eps_z:
171 print(
"duplicated value")
174 value_cache[(uu, vv)].append(y)
176 value_cache[(uu, vv)] = [y]
182 if u > u_min
and u < u_max
and v < v_max
and v > v_min:
187 classifier.fit(xs, ys)
190 except rospy.service.ServiceException
as e:
191 rospy.logfatal(
"failed to call service: %s" % (e.message))
194 except Exception
as e:
195 rospy.logwarn(
"failed to print model: %s" % e.message)
198 print(
"(%d, %d) is out of range" % (u, v))
201 global xs, ys, classifier, u_min, u_max, v_min, v_max, raw_xs
203 x = msg.observed_depth
207 if math.isnan(x)
or math.isnan(y):
209 processData(x, y, u, v, msg.center_u, msg.center_v)
214 return "%f|u| + %f|v| + %f" % (c[0], c[1], c[2])
216 return "%fu + %fv + %f" % (c[0], c[1], c[2])
219 return "%f|u|^2 + %f|u| + %f|v|^2 + %f|v| + %f" % (c[0], c[1], c[2], c[3], c[4])
221 return "%fu^2 + %fu + %fv^2 + %fv + %f" % (c[0], c[1], c[2], c[3], c[4])
226 i = classifier.intercept_
227 if model ==
"linear":
228 return "%fz + %f\n(score: %f)" % (
230 classifier.score(xs, ys))
231 elif model ==
"quadratic":
232 return "%fz^2 + %fz + %f\n(score: %f)" % (
236 classifier.score(xs, ys))
237 elif model ==
"quadratic-uv":
238 return "(%s)z^2 +\n(%s)z +\n%s\n(score: %f)" % (
242 classifier.score(xs, ys))
243 elif model ==
"quadratic-uv-abs":
244 return "(%s)z^2 +\n(%s)z +\n%s\n(score: %f)" % (
248 classifier.score(xs, ys))
249 elif model ==
"quadratic-uv-quadratic":
250 return "(%s)z^2 +\n(%s)z +\n%s\n(score: %f)" % (
254 classifier.score(xs, ys))
255 elif model ==
"quadratic-uv-quadratic-abs":
256 return "(%s)z^2 +\n(%s)z +\n%s\n(score: %f)" % (
260 classifier.score(xs, ys))
265 i = classifier.intercept_
266 if model ==
"linear":
268 elif model ==
"quadratic":
269 return c[0] * x * x + c[1] * x + i
270 elif model ==
"quadratic-uv":
271 return ((c[0] * u + c[1] * v + c[2]) * x * x +
272 (c[3] * u + c[4] * v + c[5]) * x +
273 c[6] * u + c[7] * v + i)
274 elif model ==
"quadratic-uv-abs":
277 return ((c[0] * u + c[1] * v + c[2]) * x * x +
278 (c[3] * u + c[4] * v + c[5]) * x +
279 c[6] * u + c[7] * v + i)
280 elif model ==
"quadratic-uv-quadratic":
283 return ((c[0] * u2 + c[1] * u + c[2] * v2 + c[3] * v + c[4]) * x * x +
284 (c[5] * u2 + c[6] * u + c[7] * v2 + c[8] * v + c[9]) * x +
285 (c[10] * u2 + c[11] * u + c[12] * v2 + c[13] * v + i))
286 elif model ==
"quadratic-uv-quadratic-abs":
291 return ((c[0] * u2 + c[1] * u + c[2] * v2 + c[3] * v + c[4]) * x * x +
292 (c[5] * u2 + c[6] * u + c[7] * v2 + c[8] * v + c[9]) * x +
293 (c[10] * u2 + c[11] * u + c[12] * v2 + c[13] * v + i))
297 global xs, ax, width, height
298 if rospy.is_shutdown():
306 plt.xlabel(
'Z from depth image')
307 plt.ylabel(
'Z from checker board')
311 ys[:-1], s=10, c=
'b', zorder=10, alpha=0.1)
313 [ys[-1]], s=10, c=
'r', zorder=10, alpha=1.0) 316 X_test = [[xmin * xmin, xmin], [xmax * xmax, xmax]]
317 X_range = np.linspace(xmin, xmax, 100)
318 ax.plot(X_range, X_range, linewidth=2, color=
'green', alpha=0.5)
321 width / 2, height / 2,
322 width / 2, height / 2,
324 linewidth=2, color=
'red', alpha=0.5)
325 plt.text(xmin, xmax - 0.1,
331 pub_image.publish(bridge.cv2_to_imgmsg(img,
"bgr8"))
335 w, h = fig.canvas.get_width_height()
336 plot_img = np.fromstring(fig.canvas.tostring_rgb(), dtype=np.uint8)
338 plot_img.shape = (h, w, 3)
340 pub_error_plot.publish(bridge.cv2_to_imgmsg(plot_img,
"bgr8"))
341 except Exception
as e:
342 rospy.logerr(e.message)
347 img = np.tile(np.uint8([0,0,0]), (height / 10, width / 10, 1))
349 for (u, v)
in value_cache.keys():
350 min_color = np.uint8([255, 0, 0])
351 max_color = np.uint8([0, 0, 255])
354 if frequency.has_key((uu, vv)):
355 frequency[(uu, vv)] = frequency[(uu, vv)] + len(value_cache[(u, v)])
357 frequency[(uu, vv)] = len(value_cache[(u, v)])
358 for (u, v)
in frequency.keys():
359 r =
min(frequency[(u, v)] / 10.0, 1)
360 img[v, u] = min_color * (1 - r) + max_color * r
364 global ax, xs, ys, classifier, u_min, u_max, v_min, v_max, model, set_param
365 global width, height, pub_image, pub_error_plot
366 pub_image = rospy.Publisher(
"~frequency_image", Image, queue_size=1)
367 pub_error_plot = rospy.Publisher(
"~error_plot_image", Image, queue_size=1)
368 set_param = rospy.ServiceProxy(
"/camera_remote/depth_calibration/set_calibration_parameter",
369 SetDepthCalibrationParameter)
371 parser = argparse.ArgumentParser()
372 parser.add_argument(
'--csv')
373 parser.add_argument(
'--model', default=
"linear")
374 parser.add_argument(
'--models', action=
"store_true", default=
False)
375 parser.add_argument(
"--width", default=640)
376 parser.add_argument(
"--height", default=480)
377 args = parser.parse_args(rospy.myargv()[1:])
385 if model
not in MODELS:
386 raise Exception(
"Unknown Model: %s" % (model))
389 sub = rospy.Subscriber(
"depth_image_error/output",
390 DepthErrorResult, callback)
393 ax = plt.axes([.12, .12, .8, .8])
394 classifier = linear_model.LinearRegression()
395 u_min = rospy.get_param(
"~u_min", 0)
396 u_max = rospy.get_param(
"~u_max", 4096)
397 v_min = rospy.get_param(
"~v_min", 0)
398 v_max = rospy.get_param(
"~v_max", 4096)
401 for row
in csv.reader(open(args.csv,
"rb")):
409 classifier.fit(xs, ys)
412 except rospy.service.ServiceException
as e:
413 rospy.logfatal(
"failed to call service: %s" % (e.message))
418 csv_filename =
"calibration-%s.csv" % datetime.datetime.now().strftime(
'%Y-%m-%d-%H-%M-%S')
419 print(
"Save calibration parameters to %s" % (csv_filename))
420 with open(csv_filename,
"w")
as f:
421 for x, y, u, v, cu, cv
in zip(raw_xs, ys, us, vs, c_us, c_vs):
422 f.write(
"%f,%f,%d,%d,%f,%f\n" % (x, y, u, v, cu, cv))
423 dump = rospy.get_param(
"~dump_result_into_yaml",
"query")
425 (dump ==
"query" and query_yes_no(
"Dump result into yaml file?")):
426 yaml_filename =
"calibration_parameter_%s.yaml" % datetime.datetime.now().strftime(
'%Y_%m_%d_%H_%M_%S')
427 print(
"writing to %s" % yaml_filename)
429 if model ==
"quadratic-uv-abs" or model ==
"quadratic-uv-quadratic-abs":
434 with open(yaml_filename,
"w")
as f:
436 coefficients2: [%s, %s, %s, %s, %s] 437 coefficients1: [%s, %s, %s, %s, %s] 438 coefficients0: [%s, %s, %s, %s, %s] 441 repr(c[0]), repr(c[1]), repr(c[2]), repr(c[3]), repr(c[4]),
442 repr(c[5]), repr(c[6]), repr(c[7]), repr(c[8]), repr(c[9]),
443 repr(c[10]), repr(c[11]), repr(c[12]), repr(c[13]), repr(classifier.intercept_),
446 if __name__ ==
"__main__":
447 rospy.init_node(
"depth_error_logistic_regression")
double min(const OneDataStat &d)
wrapper function for min method for boost::function
def setParameter(classifier)
def applyModel(x, u, v, cu, cv, clssifier)
def isValidClassifier(classifier)
def modelEquationString(classifier)
def uvQuadraticCoefString(c, absolute=False)
def uvCoefString(c, absolute=False)
def query_yes_no(question, default=None)
def processData(x, y, u, v, cu, cv, fit=True)
def generateFrequencyMap()
def getXFromFeatureVector(v)
def genFeatureVector(x, u, v, cu, cv)