|  |  |  | @ -7,119 +7,138 @@ import cv2 | 
		
	
		
			
				|  |  |  |  | from picamera2 import MappedArray, Picamera2, Preview | 
		
	
		
			
				|  |  |  |  | from picamera2.previews.qt import QGlPicamera2 | 
		
	
		
			
				|  |  |  |  | import numpy as np | 
		
	
		
			
				|  |  |  |  | from pythonosc import udp_client | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def rectFromPoint(center, len, width, axis): | 
		
	
		
			
				|  |  |  |  |     rect = ((0, 0), (0, 0)) | 
		
	
		
			
				|  |  |  |  |     l = int(len/2) | 
		
	
		
			
				|  |  |  |  |     w = int(width/2) | 
		
	
		
			
				|  |  |  |  |     if(axis == 'x'): | 
		
	
		
			
				|  |  |  |  |         rect = ((center[0] - l, center[1] - w), (center[0] + l, center[1] + w)) | 
		
	
		
			
				|  |  |  |  |     elif(axis == 'y'): | 
		
	
		
			
				|  |  |  |  |         rect = ((center[0] - w, center[1] - l), (center[0] + w, center[1] + l)) | 
		
	
		
			
				|  |  |  |  |     return rect | 
		
	
		
			
				|  |  |  |  | 	rect = ((0, 0), (0, 0)) | 
		
	
		
			
				|  |  |  |  | 	l = int(len/2) | 
		
	
		
			
				|  |  |  |  | 	w = int(width/2) | 
		
	
		
			
				|  |  |  |  | 	if(axis == 'x'): | 
		
	
		
			
				|  |  |  |  | 		rect = ((center[0] - l, center[1] - w), (center[0] + l, center[1] + w)) | 
		
	
		
			
				|  |  |  |  | 	elif(axis == 'y'): | 
		
	
		
			
				|  |  |  |  | 		rect = ((center[0] - w, center[1] - l), (center[0] + w, center[1] + l)) | 
		
	
		
			
				|  |  |  |  | 	return rect | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def rectsFromPoint(center, l1, l2, l3, w, axis): | 
		
	
		
			
				|  |  |  |  |     centerFine = center | 
		
	
		
			
				|  |  |  |  |     fineInner = rectFromPoint(centerFine, l1, w, axis) | 
		
	
		
			
				|  |  |  |  |     fineOuter = rectFromPoint(centerFine, l2, w, axis) | 
		
	
		
			
				|  |  |  |  |     centerCoarse = center | 
		
	
		
			
				|  |  |  |  |     if(axis == 'x'): | 
		
	
		
			
				|  |  |  |  |         centerCoarse = (center[0], center[1] + w) | 
		
	
		
			
				|  |  |  |  |     elif(axis == 'y'): | 
		
	
		
			
				|  |  |  |  |         centerCoarse = (center[0] + w, center[1]) | 
		
	
		
			
				|  |  |  |  |     coarse = rectFromPoint(centerCoarse, l3, w, axis) | 
		
	
		
			
				|  |  |  |  |     return [fineInner, fineOuter, coarse, center] | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	centerFine = center | 
		
	
		
			
				|  |  |  |  | 	fineInner = rectFromPoint(centerFine, l1, w, axis) | 
		
	
		
			
				|  |  |  |  | 	if(axis == 'x'): | 
		
	
		
			
				|  |  |  |  | 		fineInnerNeg = rectFromPoint((centerFine[0] - int(l1 / 4), centerFine[1]), int(l1 / 2), w, axis) | 
		
	
		
			
				|  |  |  |  | 		fineInnerPos = rectFromPoint((centerFine[0] + int(l1 / 4), centerFine[1]), int(l1 / 2), w, axis) | 
		
	
		
			
				|  |  |  |  | 	elif(axis == 'y'): | 
		
	
		
			
				|  |  |  |  | 		fineInnerNeg = rectFromPoint((centerFine[0], centerFine[1] - int(l1 / 4)), int(l1 / 2), w, axis) | 
		
	
		
			
				|  |  |  |  | 		fineInnerPos = rectFromPoint((centerFine[0], centerFine[1] + int(l1 / 4)), int(l1 / 2), w, axis) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	fineOuter = rectFromPoint(centerFine, l2, w, axis) | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	centerCoarse = center | 
		
	
		
			
				|  |  |  |  | 	if(axis == 'x'): | 
		
	
		
			
				|  |  |  |  | 		centerCoarse = (center[0], center[1] + w) | 
		
	
		
			
				|  |  |  |  | 	elif(axis == 'y'): | 
		
	
		
			
				|  |  |  |  | 		centerCoarse = (center[0] + w, center[1]) | 
		
	
		
			
				|  |  |  |  | 	coarse = rectFromPoint(centerCoarse, l3, w, axis) | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 	return [fineInnerNeg, fineInnerPos, fineInner, fineOuter, coarse, center] | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | def moveROI(event, x, y, flags, params): | 
		
	
		
			
				|  |  |  |  |     global roiX, roiY, moving, l1, l2, l3, w, selectedAxis | 
		
	
		
			
				|  |  |  |  |     if event == cv2.EVENT_LBUTTONDOWN: | 
		
	
		
			
				|  |  |  |  |         moving = True | 
		
	
		
			
				|  |  |  |  | 	global roiX, roiY, moving, l1, l2, l3, w, selectedAxis | 
		
	
		
			
				|  |  |  |  | 	if event == cv2.EVENT_LBUTTONDOWN: | 
		
	
		
			
				|  |  |  |  | 		moving = True | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     elif event==cv2.EVENT_MOUSEMOVE: | 
		
	
		
			
				|  |  |  |  |         if moving==True: | 
		
	
		
			
				|  |  |  |  |             if(selectedAxis == 'x'): | 
		
	
		
			
				|  |  |  |  |                 roiX = rectsFromPoint((x, y), l1, l2, l3, w, selectedAxis) | 
		
	
		
			
				|  |  |  |  |             elif(selectedAxis == 'y'): | 
		
	
		
			
				|  |  |  |  |                 roiY = rectsFromPoint((x, y), l1, l2, l3, w, selectedAxis) | 
		
	
		
			
				|  |  |  |  | 	elif event==cv2.EVENT_MOUSEMOVE: | 
		
	
		
			
				|  |  |  |  | 		if moving==True: | 
		
	
		
			
				|  |  |  |  | 			if(selectedAxis == 'x'): | 
		
	
		
			
				|  |  |  |  | 				roiX = rectsFromPoint((x, y), l1, l2, l3, w, selectedAxis) | 
		
	
		
			
				|  |  |  |  | 			elif(selectedAxis == 'y'): | 
		
	
		
			
				|  |  |  |  | 				roiY = rectsFromPoint((x, y), l1, l2, l3, w, selectedAxis) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     elif event == cv2.EVENT_LBUTTONUP: | 
		
	
		
			
				|  |  |  |  |         moving = False | 
		
	
		
			
				|  |  |  |  | 	elif event == cv2.EVENT_LBUTTONUP: | 
		
	
		
			
				|  |  |  |  | 		moving = False | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def crop(frame, rect): | 
		
	
		
			
				|  |  |  |  |     return frame[rect[0][1]:rect[1][1], rect[0][0]:rect[1][0]] | 
		
	
		
			
				|  |  |  |  | 	return frame[rect[0][1]:rect[1][1], rect[0][0]:rect[1][0]] | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def replaceCrop(frame, rect, crop): | 
		
	
		
			
				|  |  |  |  |     frame[rect[0][1]:rect[1][1], rect[0][0]:rect[1][0]] = crop | 
		
	
		
			
				|  |  |  |  | 	frame[rect[0][1]:rect[1][1], rect[0][0]:rect[1][0]] = crop | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def genDKernel(dVal): | 
		
	
		
			
				|  |  |  |  |     return np.ones((dVal, dVal), np.uint8) | 
		
	
		
			
				|  |  |  |  | 	return np.ones((dVal, dVal), np.uint8) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def track(frame, roi, dKernel): | 
		
	
		
			
				|  |  |  |  |     exp = 2 | 
		
	
		
			
				|  |  |  |  |     roiFineInner, roiFineOuter, roiCourse, roiCenter = roi | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     cropFineOuter = crop(frame, roiFineOuter) | 
		
	
		
			
				|  |  |  |  |     cropCoarse = crop(frame, roiCourse) | 
		
	
		
			
				|  |  |  |  |     #gray = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     dilation = cv2.dilate(cropFineOuter, dKernel, iterations=1) | 
		
	
		
			
				|  |  |  |  |     ret,thresh = cv2.threshold(dilation,100,255,cv2.THRESH_BINARY) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     replaceCrop(frame, roiFineOuter, thresh) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     # this could potentially be made more efficient by cropping from cropFineOuter | 
		
	
		
			
				|  |  |  |  |     cropFineInner = crop(frame, roiFineInner) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     meanFine = pow(cropFineInner.mean(), exp) | 
		
	
		
			
				|  |  |  |  |     meanCourse = pow(cropCoarse.mean(), 1) | 
		
	
		
			
				|  |  |  |  |     mean = 0 | 
		
	
		
			
				|  |  |  |  |     if(meanCourse > 10): | 
		
	
		
			
				|  |  |  |  |         mean = meanFine | 
		
	
		
			
				|  |  |  |  |     distance = pow(255, exp) - mean | 
		
	
		
			
				|  |  |  |  | 	exp = 2 | 
		
	
		
			
				|  |  |  |  | 	roiFineInnerNeg, roiFineInnerPos, roiFineInner, roiFineOuter, roiCourse, roiCenter = roi | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	cropFineOuter = crop(frame, roiFineOuter) | 
		
	
		
			
				|  |  |  |  | 	cropCoarse = crop(frame, roiCourse) | 
		
	
		
			
				|  |  |  |  | 	#gray = cv2.cvtColor(crop, cv2.COLOR_BGR2GRAY) | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	dilation = cv2.dilate(cropFineOuter, dKernel, iterations=1) | 
		
	
		
			
				|  |  |  |  | 	ret,thresh = cv2.threshold(dilation,100,255,cv2.THRESH_BINARY) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     return distance | 
		
	
		
			
				|  |  |  |  | 	replaceCrop(frame, roiFineOuter, thresh) | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	meanCourse = pow(cropCoarse.mean(), 1) | 
		
	
		
			
				|  |  |  |  | 	mean = 0 | 
		
	
		
			
				|  |  |  |  | 	direction = 1 | 
		
	
		
			
				|  |  |  |  | 	if(meanCourse > 10): | 
		
	
		
			
				|  |  |  |  | 		# this could potentially be made more efficient by cropping from cropFineOuter | 
		
	
		
			
				|  |  |  |  | 		cropFineInner = crop(frame, roiFineInner) | 
		
	
		
			
				|  |  |  |  | 		# this could potentially be made more efficient by cropping from cropFineInner | 
		
	
		
			
				|  |  |  |  | 		cropFineInnerNeg = crop(frame, roiFineInnerNeg) | 
		
	
		
			
				|  |  |  |  | 		cropFineInnerPos = crop(frame, roiFineInnerPos) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		meanFine = pow(cropFineInner.mean(), exp) | 
		
	
		
			
				|  |  |  |  | 		direction = np.sign(cropFineInnerPos.mean() - cropFineInnerNeg.mean()) | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 		mean = meanFine | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	distance = direction * (pow(255, exp) - mean) | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	return distance | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def drawRect(frame, points): | 
		
	
		
			
				|  |  |  |  |      cv2.rectangle(frame, points[0], points[1], (0, 255, 0)) | 
		
	
		
			
				|  |  |  |  | 	cv2.rectangle(frame, points[0], points[1], (0, 255, 0)) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def drawRoi(frame, roi): | 
		
	
		
			
				|  |  |  |  |     for rect in roi[:3]: | 
		
	
		
			
				|  |  |  |  |         drawRect(frame, rect) | 
		
	
		
			
				|  |  |  |  |     center = roi[3] | 
		
	
		
			
				|  |  |  |  |     cv2.line(frame, (center[0] - 5, center[1]), (center[0] + 5, center[1]), (0, 255, 0), 1) | 
		
	
		
			
				|  |  |  |  |     cv2.line(frame, (center[0], center[1] - 5), (center[0], center[1] + 5), (0, 255, 0), 1) | 
		
	
		
			
				|  |  |  |  | 	for rect in roi[2:5]: | 
		
	
		
			
				|  |  |  |  | 		drawRect(frame, rect) | 
		
	
		
			
				|  |  |  |  | 	center = roi[5] | 
		
	
		
			
				|  |  |  |  | 	cv2.line(frame, (center[0] - 5, center[1]), (center[0] + 5, center[1]), (0, 255, 0), 1) | 
		
	
		
			
				|  |  |  |  | 	cv2.line(frame, (center[0], center[1] - 5), (center[0], center[1] + 5), (0, 255, 0), 1) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | def picameraToCVTrack(): | 
		
	
		
			
				|  |  |  |  | 	global roiX, roiY, moving, l1, l2, l3, w, selectedAxis, dilationKernel, calibrate | 
		
	
		
			
				|  |  |  |  | 	global roiX, roiY, moving, l1, l2, l3, w, selectedAxis, dilationKernel, calibrate, oscClient | 
		
	
		
			
				|  |  |  |  | 	 | 
		
	
		
			
				|  |  |  |  | 	while True: | 
		
	
		
			
				|  |  |  |  | 		frame = picam2.capture_buffer("lores") | 
		
	
		
			
				|  |  |  |  | 		frame = frame[:s1 * h1].reshape((h1, s1)) | 
		
	
		
			
				|  |  |  |  | 		#frame = picam2.capture_array("lores") | 
		
	
		
			
				|  |  |  |  | 		#frame = cv2.cvtColor(frame, cv2.COLOR_GRAY2RGB) | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		distanceX = track(frame, roiX, dilationKernel) | 
		
	
		
			
				|  |  |  |  | 		distanceY = track(frame, roiY, dilationKernel) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		oscClient.send_message("/distanceX", distanceX) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		drawRoi(frame, roiX) | 
		
	
		
			
				|  |  |  |  | 		drawRoi(frame, roiY) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		cv2.putText(frame, "{}: {:.2f}".format("distance x", distanceX), (10, 100), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3) | 
		
	
		
			
				|  |  |  |  | 		cv2.putText(frame, "{}: {:.2f}".format("distance y", distanceY), (10, 200), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 3) | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		if calibrate: | 
		
	
		
			
				|  |  |  |  | 			cv2.imshow("Frame", frame) | 
		
	
		
			
				|  |  |  |  | 			#cv2.imshow("Process", tresh) | 
		
	
		
			
				|  |  |  |  | 		   | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 		# Press Q on keyboard to exit | 
		
	
		
			
				|  |  |  |  | 		key = cv2.waitKey(20) | 
		
	
		
			
				|  |  |  |  | 		#if key == 32: | 
		
	
	
		
			
				
					|  |  |  | @ -140,22 +159,21 @@ def picameraToCVTrack(): | 
		
	
		
			
				|  |  |  |  | 				calibrate = False | 
		
	
		
			
				|  |  |  |  | 				cv2.destroyAllWindows() | 
		
	
		
			
				|  |  |  |  | 			else: | 
		
	
		
			
				|  |  |  |  | 				print("hello") | 
		
	
		
			
				|  |  |  |  | 				calibrate = True | 
		
	
		
			
				|  |  |  |  | 				cv2.startWindowThread() | 
		
	
		
			
				|  |  |  |  | 		#elif key == ord('q'): | 
		
	
		
			
				|  |  |  |  | 		#	break | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | class TrackerThread(QThread): | 
		
	
		
			
				|  |  |  |  |     def __init__(self, target=None): | 
		
	
		
			
				|  |  |  |  |         super().__init__() | 
		
	
		
			
				|  |  |  |  |         self.target = target | 
		
	
		
			
				|  |  |  |  |      | 
		
	
		
			
				|  |  |  |  |     def run(self): | 
		
	
		
			
				|  |  |  |  |         if self.target: | 
		
	
		
			
				|  |  |  |  |             self.target() | 
		
	
		
			
				|  |  |  |  |              | 
		
	
		
			
				|  |  |  |  | 	def __init__(self, target=None): | 
		
	
		
			
				|  |  |  |  | 		super().__init__() | 
		
	
		
			
				|  |  |  |  | 		self.target = target | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 	def run(self): | 
		
	
		
			
				|  |  |  |  | 		if self.target: | 
		
	
		
			
				|  |  |  |  | 			self.target() | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | class MainWindow(QGlPicamera2): | 
		
	
		
			
				|  |  |  |  | 	def __init__(self, *args, **kwargs): | 
		
	
	
		
			
				
					|  |  |  | @ -166,15 +184,15 @@ class MainWindow(QGlPicamera2): | 
		
	
		
			
				|  |  |  |  | 		self.shortcut_close_window.activated.connect(self.goFullscreen) | 
		
	
		
			
				|  |  |  |  | 		self.setWindowFlags(Qt.FramelessWindowHint) | 
		
	
		
			
				|  |  |  |  | 		self.move(0, 0) | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	def mousePressEvent(self, event): | 
		
	
		
			
				|  |  |  |  | 		self.oldPos = event.globalPos() | 
		
	
		
			
				|  |  |  |  | 		 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	def mouseMoveEvent(self, event): | 
		
	
		
			
				|  |  |  |  | 		delta = QPoint (event.globalPos() - self.oldPos) | 
		
	
		
			
				|  |  |  |  | 		self.move(self.x() + delta.x(), self.y() + delta.y()) | 
		
	
		
			
				|  |  |  |  | 		self.oldPos = event.globalPos() | 
		
	
		
			
				|  |  |  |  | 		  | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | 	def goFullscreen(self): | 
		
	
		
			
				|  |  |  |  | 		if self.isFullScreen(): | 
		
	
		
			
				|  |  |  |  | 			#self.setWindowFlags(self._flags) | 
		
	
	
		
			
				
					|  |  |  | @ -189,7 +207,7 @@ picam2 = Picamera2() | 
		
	
		
			
				|  |  |  |  | #max resolution is (4056, 3040) which is more like 10 fps | 
		
	
		
			
				|  |  |  |  | config = picam2.create_preview_configuration(main={"size": (2028, 1520)}, lores={"size": (1920, 1440), "format": "YUV420"}) | 
		
	
		
			
				|  |  |  |  | picam2.configure(config) | 
		
	
		
			
				|  |  |  |  | 			 | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | app = QApplication([]) | 
		
	
		
			
				|  |  |  |  | qpicamera2 = MainWindow(picam2, width=1920, height=1440, keep_ar=False) | 
		
	
		
			
				|  |  |  |  | qpicamera2.setWindowTitle("Qt Picamera2 App") | 
		
	
	
		
			
				
					|  |  |  | @ -208,6 +226,8 @@ dilationVal = 75 | 
		
	
		
			
				|  |  |  |  | dilationKernel = genDKernel(dilationVal) | 
		
	
		
			
				|  |  |  |  | calibrate = True | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | oscClient = udp_client.SimpleUDPClient("127.0.0.1", 57120) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | cv2.startWindowThread() | 
		
	
		
			
				|  |  |  |  | cv2.namedWindow("Frame") | 
		
	
		
			
				|  |  |  |  | cv2.setMouseCallback("Frame", moveROI) | 
		
	
	
		
			
				
					|  |  |  | 
 |