This is an OpenCV application to measure the x,y position of an object, using 2 cameras at right angles. It imports cam_display.py. See this post for a code description, and usage information: some code changes may be required.
# OpenCV application to measure the x,y position of an object
# Copyright (c) Jeremy P Bentham 2019
# Please credit iosoft.blog if you use the information or software in it
VERSION = "Campos v0.07"
import sys, time, threading, cv2, numpy as np
import cam_display as camdisp
IMG_SIZE = 1280,720 # 640,480 or 1280,720 or 1920,1080
DISP_SCALE = 2 # Scaling factor for display image
DISP_MSEC = 50 # Delay between display cycles
CAP_API = cv2.CAP_ANY # API: CAP_ANY or CAP_DSHOW etc...
LOWER_DET = np.array([240, 0, 0]) # Colour limits for detection
UPPER_DET = np.array([255,200,200])
LABEL_FONT = camdisp.QFont("Courier", 16) # Font for image label
# Do colour detection on image
def colour_detect(img):
mask = cv2.inRange(img, LOWER_DET, UPPER_DET)
ctrs = cv2.findContours(mask, cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)[-2]
if len(ctrs) > 0:
(x,y),radius = cv2.minEnclosingCircle(ctrs[0])
radius = int(radius)
cv2.circle(img, (int(x),int(y)), radius, (255,255,0), 2)
return x
return 0
# Class to hold capture & display data for a camera
class CamCap(object):
def __init__(self, cam_num, label, disp):
self.cam_num, self.label, self.display = cam_num, label, disp
self.imageq = camdisp.Queue.Queue()
self.pos = 0
self.cap = cv2.VideoCapture(self.cam_num-1 + CAP_API)
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, IMG_SIZE[0])
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, IMG_SIZE[1])
# Main window
class MyWindow(camdisp.MyWindow):
def __init__(self, parent=None):
camdisp.MyWindow.__init__(self, parent)
self.label.setFont(LABEL_FONT)
self.camcaps = []
self.disp2 = camdisp.ImageWidget(self)
self.displays.addWidget(self.disp2)
self.capturing = True
# Start image capture & display
def start(self):
self.timer = camdisp.QTimer(self) # Timer to trigger display
self.timer.timeout.connect(self.show_images)
self.timer.start(DISP_MSEC) # Thread to grab images
self.capture_thread = threading.Thread(target=self.grab_images)
self.capture_thread.start()
# Grab camera images (separate thread)
def grab_images(self):
while self.capturing:
for cam in self.camcaps:
if cam.cap.grab():
retval, image = cam.cap.retrieve(0)
if image is not None and cam.imageq.qsize() 0:
img = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
cam.pos = colour_detect(img)
self.display_image(img, cam.display, DISP_SCALE)
self.show_positions()
# Show position values given by cameras
def show_positions(self, s=""):
for cam in self.camcaps:
s += "%s=%-5.1f " % (cam.label, cam.pos)
self.label.setText(s)
# Window is closing: stop video capture
def closeEvent(self, event):
self.capturing = False
self.capture_thread.join()
if __name__ == '__main__':
app = camdisp.QApplication(sys.argv)
win = MyWindow()
win.camcaps.append(CamCap(2, 'x', win.disp))
win.camcaps.append(CamCap(1, 'y', win.disp2))
win.show()
win.setWindowTitle(VERSION)
win.start()
sys.exit(app.exec_())
#EOF