def update(): key, img = next(stream) g = cv.cvtColor(img, cv.COLOR_BGR2GRAY) cs = extractContours(g, minarea=5, reduprec=2) good = polygons(cs, 6, 3) poses = [] for c in good: p = bestPose(K, c, marker) if p.rms < 2: poses += [p.M] cv.polylines(img, [c], True, (255, 255, 0), 3) if poses: p = poses[0] T = cameraTransf(p) cam.setData(pos=htrans(T, drawCam)) view.setData(data=img2tex(img)) m = T @ A view.setTransform(QtGui.QMatrix4x4(*(m.flatten()))) axc.setTransform(QtGui.QMatrix4x4(*(T.flatten()))) #print(p) cv.imshow('input', img)
def readModels(path): fmods = sorted( [name for name in glob.glob(path + '/*.*') if name[-3:] != 'txt']) models = sum([[biggest(extractContours(rgb2gray(readrgb(f))))] for f in fmods], []) if not models: models = [marker * [1, -1]] return [fixOrientation(autoscale(c.astype(float))) for c in models]
def find(img, poly): g = cv.cvtColor(img, cv.COLOR_BGR2GRAY) cs = extractContours(g, minarea=5, reduprec=2) good = polygons(cs, len(poly), 3) poses = [] for g in good: p = bestPose(K, g, poly) if p.rms < 2: poses += [p] return poses
def __init__(self, x, lab='?', full=False, eps_w=10, **args): self.orig = x (A, self.s1, self.s2, ad), H, W = whitenedMoments(x, th=eps_w) self.H = H self.W = W self.SBar, self.S, self.K = KSsignature(W) self.Ts = [ np.dot(t, H) for t in canonicTransforms((self.SBar, self.K), **args) ] self.can = [warpW(x, T, sz=(100, 100), sigma=3) for T in self.Ts] self.dtc = [dt(c) for c in self.can] self.auxh1 = [ np.hstack([self.can[k], self.dtc[k]]) for k in range(len(self.can)) ] self.auxh2 = [ np.hstack([self.dtc[k], self.can[k]]) for k in range(len(self.can)) ] pl = min(x.shape) self.pad = np.pad(x, pl, 'constant') if full: self.dto = dt(self.pad) / self.s1 self.dtco = [ warpW(self.dto, T, sz=(100, 100), sigma=3, offset=pl, borderMode=cv.BORDER_REPLICATE) for T in self.Ts ] self.auxh3 = [ np.hstack([self.can[k], self.dtco[k]]) for k in range(len(self.can)) ] self.auxh4 = [ np.hstack([self.dtco[k], self.can[k]]) for k in range(len(self.can)) ] conts = extractContours(255 - 255 * self.pad.astype(np.uint8), minarea=0, minredon=0, reduprec=0.5) assert len(conts) > 0, (len(conts), lab) self.wcont = sorted(conts, key=len)[-1] self.invar = invar(spectralFeat(self.wcont)) r, s, t, g = orientability((self.SBar, self.S, self.K)) self.skf = vec(self.S.max(), s, (self.K.min() + self.K.max()) / 2, r, t / r, g / r) self.lab = lab
def update(): key, img = next(stream) g = cv.cvtColor(img, cv.COLOR_BGR2GRAY) cs = extractContours(g, minarea=5, reduprec=2) good = polygons(cs, 6, 3) poses = [] for c in good: p = bestPose(K, c, marker) if p.rms < 2: poses += [p.M] #cv.polylines(img,[c],True,(255,255,0),3) if poses: M = poses[0] # hasta aquí todo es igual que antes. # Tenemos la matriz de cámara M # sacamos la tranformación que nos permite situar en 3D # el esqueleto de la cámara, sus ejes, y la imagen que se ve en ella T = cameraTransf(M) transform(T, axc) cam.setData(pos=htrans(T, drawCam)) view.setData(data=img2tex(img)) m = T @ A transform(m, view) # A partir de la matriz de cámara sacamos la homografía del plano # (esto también se puede hace como en el capítulo anterior) # La homografía del plano z=0 se puede extraer de la matriz de cámara # simplemente quitando la 3 columna (la que corresponde a la coordenada z). # Hay que escalar para que encaje con el tamaño de la escena 3D. s = 1 / 50 S = scale((s, s)) HZ0 = desp((250, 250)) @ la.inv(M[:, [0, 1, 3]] @ S) # rectificamos la imagen rectif = cv.warpPerspective(img, HZ0, (500, 500)) # la situamos en la escena con la escala adecuada world.setData(data=img2tex(rectif)) transform(scale((s, s, 1)) @ desp((-250, -250, 0)), world) cv.imshow('input', img)
from umucv.stream import autoStream import cv2 as cv import numpy as np from umucv.util import mkParam, putText # Toda la maquinaria anterior de detección de elipses está disponible en umucv from umucv.contours import extractContours, detectEllipses cv.namedWindow("elipses") param = mkParam("elipses") param.addParam("err",30,50) for key,frame in autoStream(): g = cv.cvtColor(frame,cv.COLOR_BGR2GRAY) cs = extractContours(g, minarea=5) els = detectEllipses(cs, tol=param.err) # para cada elipse detectada for e in els: cv.ellipse(frame,e, color=(0,0,255)) # sacamos el centro cx,cy = int(e[0][0]), int(e[0][1]) # y escribimos el nivel de gris que tiene el centro de la elipse info = '{}'.format(g[cy,cx]) putText(frame, info, (cx,cy),color=(255,255,255)) # Lo necesitamos para detectar el círculo especial que no está # relleno, situado en el origen de coordenadas.
# igual que la semana pasada, probamos todas las asociaciones de puntos # imagen - modelo y nos quedamos con la que produzca menos error de ajuste def bestPose(K,view,model): poses = [ pose(K, v.astype(float), model) for v in rots(view) ] return sorted(poses,key=lambda p: p[0])[0] # cambia esto para mostrar los contornos y el marcador detectado debug = False # empezamos el bucle de captura for key,frame in stream: # extraemos los contornos como siempre, con la utilidad de umucv g = cv.cvtColor(frame,cv.COLOR_BGR2GRAY) cs = extractContours(g, minarea=5, reduprec=2) # buscamos polígonos con los mismos lados que el marcador good = polygons(cs,6,3) #print(len(good)) # bestPose nos da la cámara y el error # si encontramos varios posibles marcadores nos quedamos solo con los # que tengan un error de reproyección menor de 2 pixels # Si aparece un polígono por casualidad con 6 lados, es muy difícil que # sea consistente con una posible imagen del marcador. # Este critero elimina casi todos los falsos positivos poses = [] for g in good: rms, M = bestPose(K,g,marker) if rms < 2:
s1, s2 = np.sqrt(v1), np.sqrt(v2) e = p, (4 * s1, 4 * s2), a / np.pi * 180 err = errorEllipse(e, c, mindiam=mindiam, minratio=minratio) if err < tol / 100: res.append(e) return sorted(res, key=lambda x: -x[1][0] * x[1][1]) cv.namedWindow("elipses") param = mkParam("elipses") param.addParam("err", 30, 50) param.addParam("area", 5, 20) for key, frame in autoStream(): g = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) cs = extractContours(g, minarea=max(1, param.area)) els = detectEllipses(cs, tol=param.err) for e in els: # podemos dibujar directamente las elipses con opencv cv.ellipse(frame, e, color=(0, 0, 255), thickness=2, lineType=cv.LINE_AA) cv.imshow('elipses', frame)