def measure_target_width_on_segment(self, pt1, pt2): """ Given the line segment L defined by 2d points pt1 and pt2 from a camera frame, find the points pt3 and pt4 the nearest points to pt1 and pt2 on L that are masked according to self.mask8. Then calculate the distance D between 3d points pt5 and pt6 in self.xyz which correspond to pt3 and pt4. return pt3, pt4, D, fx, fy, where pt3 = (x, y) pt4 = (x, y) fx is the function f(distance from pt3 on L) = x fy is the function f(distance from pt3 on L) = y If anything goes wrong, return None """ from scipy.interpolate import interp1d dist2d = distance(pt1, pt2) interpx = interp1d([0, dist2d], [pt1[0], pt2[0]]) interpy = interp1d([0, dist2d], [pt1[1], pt2[1]]) t = numpy.linspace(0, int(dist2d), int(dist2d)+1) xs = numpy.int0(interpx(t)) ys = numpy.int0(interpy(t)) ixs, = self.mask8[ys, xs].nonzero() if len(ixs) >= 2: x1 = xs[ixs[0]] y1 = ys[ixs[0]] x2 = xs[ixs[-1]] y2 = ys[ixs[-1]] xyz1 = self.xyz[:, y1, x1] xyz2 = self.xyz[:, y2, x2] dist3d = distance(xyz1, xyz2) interpx2 = lambda d: (x2-x1)*d/dist2d + x1 interpy2 = lambda d: (y2-y1)*d/dist2d + y1 return (x1, y1), (x2, y2), dist3d, interpx2, interpy2
def display_measurement(self, stuff): pt1, pt2, dist, fx, fy = stuff dist2d = distance(pt1, pt2) txt_x = int(fx(dist2d+20)) txt_y = int(fy(dist2d+20)) cv2.circle(self.contour_img, pt1, 2, rgbhex2bgr(0xf7ff1e), thickness=2) cv2.circle(self.contour_img, pt2, 2, rgbhex2bgr(0xf7ff1e), thickness=2) cv2.putText(self.contour_img, ("%.2f in" % mm_to_in(dist)), (txt_x, txt_y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, rgbhex2bgr(0xf7ff1e))