Domanda

Dato un 2d picture di un rettangolo distorto dalla prospettiva:

entrare descrizione dell'immagine qui

Lo so che la forma era in origine un rettangolo, ma non so la sua dimensione originale.

Se so che le coordinate dei pixel degli angoli in questa immagine, come posso calcolare le proporzioni originali, vale a dire il quoziente (larghezza / altezza) del rettangolo?

(sfondo: l'obiettivo è quello automaticamente undistort foto di documenti rettangolari, il rilevamento dei bordi sarà probabilmente essere fatto con trasformata di Hough)

UPDATE:

C'è stata qualche discussione sul se sia possibile a tutti per determinare la larghezza: rapporto di altezza con le informazioni fornite. Il mio pensiero ingenuo è stato che deve essere possibile, dato che posso pensare a un modo di progettare, ad esempio un 1: rettangolo di 4 sul quadrilatero raffigurato sopra. Il rapporto appare chiaramente vicino a 1: 1, quindi ci deve essere un modo per determinare matematicamente. Non ho tuttavia alcuna prova per questo oltre la mia congettura intuitiva.

Non ho ancora pienamente compreso gli argomenti presentati qui di seguito, ma penso che ci deve essere qualche presupposto implicito che ci manca qui e che viene interpretato in modo diverso.

Tuttavia, dopo ore di ricerca, ho finalmente trovato alcuni documenti rilevanti per il problema. Ho difficoltà a capire la matematica utilizzata in là, finora senza successo. In particolare il primo articolo sembra per discutere esattamente quello che volevo fare, purtroppo senza esempi di codice e molto denso per la matematica.

  • Zhengyou Zhang, Li-Wei He, "Lavagna bianca scansione e ottimizzazione delle immagini" http://research.microsoft.com/en -us / um / persone / Zhang / documenti / tr03-39.pdf p.11

      

    "A causa della distorsione prospettica, l'immagine di un rettangolo sembra essere un quadrilatero. Tuttavia, poiché sappiamo che è un rettangolo nello spazio, siamo in grado di stimare sia la lunghezza focale della fotocamera e le proporzioni del rettangolo. "

  • ROBERT M. HARALICK "Determinazione parametri della telecamera dalla proiezione prospettica di un rettangolo" http://portal.acm.org/citation.cfm?id=87146

      

    "mostriamo come utilizzare il 2D proiezione prospettica di un rettangolo di dimensioni e la posizione sconosciuta nello spazio 3D per determinare i parametri di angolo fotocamera sguardo relativi ai piani del rettangolo."

È stato utile?

Soluzione

Ecco il mio tentativo di rispondere alla mia domanda dopo aver letto il giornale

I manipolato le equazioni per qualche tempo in SAGE, e si avvicinò con questa pseudo-codice in C-style:


// in case it matters: licensed under GPLv2 or later
// legend:
// sqr(x)  = x*x
// sqrt(x) = square root of x

// let m1x,m1y ... m4x,m4y be the (x,y) pixel coordinates
// of the 4 corners of the detected quadrangle
// i.e. (m1x, m1y) are the cordinates of the first corner, 
// (m2x, m2y) of the second corner and so on.
// let u0, v0 be the pixel coordinates of the principal point of the image
// for a normal camera this will be the center of the image, 
// i.e. u0=IMAGEWIDTH/2; v0 =IMAGEHEIGHT/2
// This assumption does not hold if the image has been cropped asymmetrically

// first, transform the image so the principal point is at (0,0)
// this makes the following equations much easier
m1x = m1x - u0;
m1y = m1y - v0;
m2x = m2x - u0;
m2y = m2y - v0;
m3x = m3x - u0;
m3y = m3y - v0;
m4x = m4x - u0;
m4y = m4y - v0;


// temporary variables k2, k3
double k2 = ((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x) /
            ((m2y - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) ;

double k3 = ((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y - m1y*m4x) / 
            ((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) ;

// f_squared is the focal length of the camera, squared
// if k2==1 OR k3==1 then this equation is not solvable
// if the focal length is known, then this equation is not needed
// in that case assign f_squared= sqr(focal_length)
double f_squared = 
    -((k3*m3y - m1y)*(k2*m2y - m1y) + (k3*m3x - m1x)*(k2*m2x - m1x)) / 
                      ((k3 - 1)*(k2 - 1)) ;

//The width/height ratio of the original rectangle
double whRatio = sqrt( 
    (sqr(k2 - 1) + sqr(k2*m2y - m1y)/f_squared + sqr(k2*m2x - m1x)/f_squared) /
    (sqr(k3 - 1) + sqr(k3*m3y - m1y)/f_squared + sqr(k3*m3x - m1x)/f_squared) 
) ;

// if k2==1 AND k3==1, then the focal length equation is not solvable 
// but the focal length is not needed to calculate the ratio.
// I am still trying to figure out under which circumstances k2 and k3 become 1
// but it seems to be when the rectangle is not distorted by perspective, 
// i.e. viewed straight on. Then the equation is obvious:
if (k2==1 && k3==1) whRatio = sqrt( 
    (sqr(m2y-m1y) + sqr(m2x-m1x)) / 
    (sqr(m3y-m1y) + sqr(m3x-m1x))


// After testing, I found that the above equations 
// actually give the height/width ratio of the rectangle, 
// not the width/height ratio. 
// If someone can find the error that caused this, 
// I would be most grateful.
// until then:
whRatio = 1/whRatio;

Aggiornamento: ecco come queste equazioni in cui determinate:

Il seguente è codice SAGE . Vi si può accedere online all'indirizzo http://www.sagenb.org/home/pub/704/ . (Sage è davvero utile per risolvere le equazioni, e utilizzabile con qualsiasi browser, check it out)

# CALCULATING THE ASPECT RATIO OF A RECTANGLE DISTORTED BY PERSPECTIVE

#
# BIBLIOGRAPHY:
# [zhang-single]: "Single-View Geometry of A Rectangle 
#  With Application to Whiteboard Image Rectification"
#  by Zhenggyou Zhang
#  http://research.microsoft.com/users/zhang/Papers/WhiteboardRectification.pdf

# pixel coordinates of the 4 corners of the quadrangle (m1, m2, m3, m4)
# see [zhang-single] figure 1
m1x = var('m1x')
m1y = var('m1y')
m2x = var('m2x')
m2y = var('m2y')
m3x = var('m3x')
m3y = var('m3y')
m4x = var('m4x')
m4y = var('m4y')

# pixel coordinates of the principal point of the image
# for a normal camera this will be the center of the image, 
# i.e. u0=IMAGEWIDTH/2; v0 =IMAGEHEIGHT/2
# This assumption does not hold if the image has been cropped asymmetrically
u0 = var('u0')
v0 = var('v0')

# pixel aspect ratio; for a normal camera pixels are square, so s=1
s = var('s')

# homogenous coordinates of the quadrangle
m1 = vector ([m1x,m1y,1])
m2 = vector ([m2x,m2y,1])
m3 = vector ([m3x,m3y,1])
m4 = vector ([m4x,m4y,1])


# the following equations are later used in calculating the the focal length 
# and the rectangle's aspect ratio.
# temporary variables: k2, k3, n2, n3

# see [zhang-single] Equation 11, 12
k2_ = m1.cross_product(m4).dot_product(m3) / m2.cross_product(m4).dot_product(m3)
k3_ = m1.cross_product(m4).dot_product(m2) / m3.cross_product(m4).dot_product(m2)
k2 = var('k2')
k3 = var('k3')

# see [zhang-single] Equation 14,16
n2 = k2 * m2 - m1
n3 = k3 * m3 - m1


# the focal length of the camera.
f = var('f')
# see [zhang-single] Equation 21
f_ = sqrt(
         -1 / (
          n2[2]*n3[2]*s^2
         ) * (
          (
           n2[0]*n3[0] - (n2[0]*n3[2]+n2[2]*n3[0])*u0 + n2[2]*n3[2]*u0^2
          )*s^2 + (
           n2[1]*n3[1] - (n2[1]*n3[2]+n2[2]*n3[1])*v0 + n2[2]*n3[2]*v0^2
          ) 
         ) 
        )


# standard pinhole camera matrix
# see [zhang-single] Equation 1
A = matrix([[f,0,u0],[0,s*f,v0],[0,0,1]])


#the width/height ratio of the original rectangle
# see [zhang-single] Equation 20
whRatio = sqrt (
               (n2*A.transpose()^(-1) * A^(-1)*n2.transpose()) / 
               (n3*A.transpose()^(-1) * A^(-1)*n3.transpose())
              ) 

Le equazioni semplificate del c-codice in cui determinati da

print "simplified equations, assuming u0=0, v0=0, s=1"
print "k2 := ", k2_
print "k3 := ", k3_
print "f  := ", f_(u0=0,v0=0,s=1)
print "whRatio := ", whRatio(u0=0,v0=0,s=1)

    simplified equations, assuming u0=0, v0=0, s=1
    k2 :=  ((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)/((m2y
    - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x)
    k3 :=  ((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)/((m3y
    - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x)
    f  :=  sqrt(-((k3*m3y - m1y)*(k2*m2y - m1y) + (k3*m3x - m1x)*(k2*m2x
    - m1x))/((k3 - 1)*(k2 - 1)))
    whRatio :=  sqrt(((k2 - 1)^2 + (k2*m2y - m1y)^2/f^2 + (k2*m2x -
    m1x)^2/f^2)/((k3 - 1)^2 + (k3*m3y - m1y)^2/f^2 + (k3*m3x -
    m1x)^2/f^2))

print "Everything in one equation:"
print "whRatio := ", whRatio(f=f_)(k2=k2_,k3=k3_)(u0=0,v0=0,s=1)

    Everything in one equation:
    whRatio :=  sqrt(((((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y -
    m1y*m4x)/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) -
    1)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)/((m2y -
    m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) - 1)*(((m1y -
    m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)*m2y/((m2y - m4y)*m3x
    - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) - m1y)^2/((((m1y - m4y)*m2x -
    (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)*m3y/((m3y - m4y)*m2x - (m3x -
    m4x)*m2y + m3x*m4y - m3y*m4x) - m1y)*(((m1y - m4y)*m3x - (m1x -
    m4x)*m3y + m1x*m4y - m1y*m4x)*m2y/((m2y - m4y)*m3x - (m2x - m4x)*m3y
    + m2x*m4y - m2y*m4x) - m1y) + (((m1y - m4y)*m2x - (m1x - m4x)*m2y +
    m1x*m4y - m1y*m4x)*m3x/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y
    - m3y*m4x) - m1x)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y -
    m1y*m4x)*m2x/((m2y - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x)
    - m1x)) + (((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y -
    m1y*m4x)/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) -
    1)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)/((m2y -
    m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) - 1)*(((m1y -
    m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)*m2x/((m2y - m4y)*m3x
    - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) - m1x)^2/((((m1y - m4y)*m2x -
    (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)*m3y/((m3y - m4y)*m2x - (m3x -
    m4x)*m2y + m3x*m4y - m3y*m4x) - m1y)*(((m1y - m4y)*m3x - (m1x -
    m4x)*m3y + m1x*m4y - m1y*m4x)*m2y/((m2y - m4y)*m3x - (m2x - m4x)*m3y
    + m2x*m4y - m2y*m4x) - m1y) + (((m1y - m4y)*m2x - (m1x - m4x)*m2y +
    m1x*m4y - m1y*m4x)*m3x/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y
    - m3y*m4x) - m1x)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y -
    m1y*m4x)*m2x/((m2y - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x)
    - m1x)) - (((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y -
    m1y*m4x)/((m2y - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) -
    1)^2)/((((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y -
    m1y*m4x)/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) -
    1)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)/((m2y -
    m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) - 1)*(((m1y -
    m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)*m3y/((m3y - m4y)*m2x
    - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) - m1y)^2/((((m1y - m4y)*m2x -
    (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)*m3y/((m3y - m4y)*m2x - (m3x -
    m4x)*m2y + m3x*m4y - m3y*m4x) - m1y)*(((m1y - m4y)*m3x - (m1x -
    m4x)*m3y + m1x*m4y - m1y*m4x)*m2y/((m2y - m4y)*m3x - (m2x - m4x)*m3y
    + m2x*m4y - m2y*m4x) - m1y) + (((m1y - m4y)*m2x - (m1x - m4x)*m2y +
    m1x*m4y - m1y*m4x)*m3x/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y
    - m3y*m4x) - m1x)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y -
    m1y*m4x)*m2x/((m2y - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x)
    - m1x)) + (((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y -
    m1y*m4x)/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) -
    1)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y - m1y*m4x)/((m2y -
    m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x) - 1)*(((m1y -
    m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)*m3x/((m3y - m4y)*m2x
    - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) - m1x)^2/((((m1y - m4y)*m2x -
    (m1x - m4x)*m2y + m1x*m4y - m1y*m4x)*m3y/((m3y - m4y)*m2x - (m3x -
    m4x)*m2y + m3x*m4y - m3y*m4x) - m1y)*(((m1y - m4y)*m3x - (m1x -
    m4x)*m3y + m1x*m4y - m1y*m4x)*m2y/((m2y - m4y)*m3x - (m2x - m4x)*m3y
    + m2x*m4y - m2y*m4x) - m1y) + (((m1y - m4y)*m2x - (m1x - m4x)*m2y +
    m1x*m4y - m1y*m4x)*m3x/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y
    - m3y*m4x) - m1x)*(((m1y - m4y)*m3x - (m1x - m4x)*m3y + m1x*m4y -
    m1y*m4x)*m2x/((m2y - m4y)*m3x - (m2x - m4x)*m3y + m2x*m4y - m2y*m4x)
    - m1x)) - (((m1y - m4y)*m2x - (m1x - m4x)*m2y + m1x*m4y -
    m1y*m4x)/((m3y - m4y)*m2x - (m3x - m4x)*m2y + m3x*m4y - m3y*m4x) -
    1)^2))


# some testing:
# - choose a random rectangle, 
# - project it onto a random plane,
# - insert the corners in the above equations,
# - check if the aspect ratio is correct.

from sage.plot.plot3d.transform import rotate_arbitrary

#redundandly random rotation matrix
rand_rotMatrix = \
           rotate_arbitrary((uniform(-5,5),uniform(-5,5),uniform(-5,5)),uniform(-5,5)) *\
           rotate_arbitrary((uniform(-5,5),uniform(-5,5),uniform(-5,5)),uniform(-5,5)) *\
           rotate_arbitrary((uniform(-5,5),uniform(-5,5),uniform(-5,5)),uniform(-5,5))

#random translation vector
rand_transVector = vector((uniform(-10,10),uniform(-10,10),uniform(-10,10))).transpose()

#random rectangle parameters
rand_width =uniform(0.1,10)
rand_height=uniform(0.1,10)
rand_left  =uniform(-10,10)
rand_top   =uniform(-10,10)

#random focal length and principal point
rand_f  = uniform(0.1,100)
rand_u0 = uniform(-100,100)
rand_v0 = uniform(-100,100)

# homogenous standard pinhole projection, see [zhang-single] Equation 1
hom_projection = A * rand_rotMatrix.augment(rand_transVector)

# construct a random rectangle in the plane z=0, then project it randomly 
rand_m1hom = hom_projection*vector((rand_left           ,rand_top            ,0,1)).transpose()
rand_m2hom = hom_projection*vector((rand_left           ,rand_top+rand_height,0,1)).transpose()
rand_m3hom = hom_projection*vector((rand_left+rand_width,rand_top            ,0,1)).transpose()
rand_m4hom = hom_projection*vector((rand_left+rand_width,rand_top+rand_height,0,1)).transpose()

#change type from 1x3 matrix to vector
rand_m1hom = rand_m1hom.column(0)
rand_m2hom = rand_m2hom.column(0)
rand_m3hom = rand_m3hom.column(0)
rand_m4hom = rand_m4hom.column(0)

#normalize
rand_m1hom = rand_m1hom/rand_m1hom[2]
rand_m2hom = rand_m2hom/rand_m2hom[2]
rand_m3hom = rand_m3hom/rand_m3hom[2]
rand_m4hom = rand_m4hom/rand_m4hom[2]

#substitute random values for f, u0, v0
rand_m1hom = rand_m1hom(f=rand_f,s=1,u0=rand_u0,v0=rand_v0)
rand_m2hom = rand_m2hom(f=rand_f,s=1,u0=rand_u0,v0=rand_v0)
rand_m3hom = rand_m3hom(f=rand_f,s=1,u0=rand_u0,v0=rand_v0)
rand_m4hom = rand_m4hom(f=rand_f,s=1,u0=rand_u0,v0=rand_v0)

# printing the randomly choosen values
print "ground truth: f=", rand_f, "; ratio=", rand_width/rand_height

# substitute all the variables in the equations:
print "calculated: f= ",\
f_(k2=k2_,k3=k3_)(s=1,u0=rand_u0,v0=rand_v0)(
  m1x=rand_m1hom[0],m1y=rand_m1hom[1],
  m2x=rand_m2hom[0],m2y=rand_m2hom[1],
  m3x=rand_m3hom[0],m3y=rand_m3hom[1],
  m4x=rand_m4hom[0],m4y=rand_m4hom[1],
),"; 1/ratio=", \
1/whRatio(f=f_)(k2=k2_,k3=k3_)(s=1,u0=rand_u0,v0=rand_v0)(
  m1x=rand_m1hom[0],m1y=rand_m1hom[1],
  m2x=rand_m2hom[0],m2y=rand_m2hom[1],
  m3x=rand_m3hom[0],m3y=rand_m3hom[1],
  m4x=rand_m4hom[0],m4y=rand_m4hom[1],
)

print "k2 = ", k2_(
  m1x=rand_m1hom[0],m1y=rand_m1hom[1],
  m2x=rand_m2hom[0],m2y=rand_m2hom[1],
  m3x=rand_m3hom[0],m3y=rand_m3hom[1],
  m4x=rand_m4hom[0],m4y=rand_m4hom[1],
), "; k3 = ", k3_(
  m1x=rand_m1hom[0],m1y=rand_m1hom[1],
  m2x=rand_m2hom[0],m2y=rand_m2hom[1],
  m3x=rand_m3hom[0],m3y=rand_m3hom[1],
  m4x=rand_m4hom[0],m4y=rand_m4hom[1],
)

# ATTENTION: testing revealed, that the whRatio 
# is actually the height/width ratio, 
# not the width/height ratio
# This contradicts [zhang-single]
# if anyone can find the error that caused this, I'd be grateful

    ground truth: f= 72.1045134124554 ; ratio= 3.46538779959142
    calculated: f=  72.1045134125 ; 1/ratio= 3.46538779959
    k2 =  0.99114614987 ; k3 =  1.57376280159

Altri suggerimenti

Aggiorna

Dopo aver letto l'aggiornamento, e guardando il primo riferimento (Lavagna scansione e l'ottimizzazione delle immagini), vedo dove il punto che manca è.

I dati di ingresso del problema è una quadrupla (A, B, C, D), E il centro O dell'immagine proiettata. Nell'articolo, corrisponde all'assunzione u0 = v0 = 0. L'aggiunta di questo punto, il problema diventa vincolata sufficiente per ottenere il rapporto di aspetto del rettangolo.

Il problema è quindi riaffermato come segue: Data una quadrupla (A, B, C, D) nel piano Z = 0, trovare la posizione degli occhi E (0,0, h), h> 0 e un piano 3D P tale che la proiezione di (a, B, C, D) su P è un rettangolo.

Si noti che P è determinata da E: per ottenere un parallelogramma, P deve contenere paralleli (UE) e (EV), dove U = (AB) x (CD) e V = (AD) x (BC).

Sperimentalmente, sembra che questo problema è in generale una soluzione unica, corrispondente ad un valore univoco del rapporto w / h del rettangolo.

alt text alt text

Post precedente

No, non è possibile determinare il rapporto di rettangolo di dalla proiezione.

Nel caso generale, una quadrupla (A, B, C, D) di quattro punti non collineari del piano Z = 0 è la proiezione di infiniti rettangoli, con infiniti rapporti larghezza / altezza.

Si considerino i due punti di fuga U, intersezione di (AB) e (CD) e V, intersezione di (AD) e (BC), e il punto I, intersezione delle due diagonali (AC) e (BD). Per proiettare come ABCD, un parallelogramma del centro devo giacere su un piano contenente la retta parallela a (UV) attraverso il punto I. Da un tale piano, si possono trovare molti rettangoli sporgenti di ABCD, il tutto con un diverso w / h il rapporto.

Vedere queste due immagini fatte con Cabri 3D. Nei due casi ABCD è invariato (in grigio piano Z = 0), e il piano blu contenente il rettangolo non cambia neanche. La linea verde parzialmente nascosto è la linea (UV) e la linea verde visibile è parallelo ad esso e contiene io.

alt text alt text

Dimensioni non è realmente necessario, e né lo sono le proporzioni. E sapendo da che parte è fino è una specie di irrilevante considerare sta usando foto / scansioni di documenti. Dubito hes intenzione di eseguire la scansione del retro di loro.

"angolo di intersezione" è il metodo per correggere la prospettiva. Questo potrebbe essere di aiuto:

Come disegnare una griglia prospettive-corretta in 2D

Sulla questione del perché i risultati danno h / w piuttosto allora w / h: Mi chiedo se l'espressione di Equazione 20 di cui sopra è corretta. Posted è:

       whRatio = sqrt (
            (n2*A.transpose()^(-1) * A^(-1)*n2.transpose()) / 
            (n3*A.transpose()^(-1) * A^(-1)*n3.transpose())
           ) 

Quando provo ad eseguire quello con OpenCV, ottengo un'eccezione. Ma tutto funziona correttamente quando uso la seguente equazione che a me sembra più Equazione 20: Ma sulla base Equazione 20, sembra che dovrebbe essere:

        whRatio = sqrt (
            (n2.transpose()*A.transpose()^(-1) * A^(-1)*n2) /
            (n3.transpose()*A.transpose()^(-1) * A^(-1)*n3)
           )

È possibile determinare la larghezza / altezza da questa risposta Calcolo rettangolo di coordinate 3D con la coordinata ombra? . Si supponga che il rettangolo di ruotare sul punto di intersezione diagonale calcolarlo larghezza e l'altezza. Ma quando si cambia la distanza tra il piano di assunzione ombra la vera ombra piano proporzionale del rettangolo è lo stesso con larghezza / altezza calcolata!

è impossibile conoscere l'ampiezza di questo rettangolo senza conoscere la distanza della 'macchina'.

un piccolo rettangolo visto da 5 cm di distanza sembra la stessa di un rettangolo enorme come visto da metri di distanza

Disegnare un triangolo rettangolo isoscele con i due punti di fuga e un terzo punto sotto l'orizzonte (cioè, sullo stesso lato dell'orizzonte del rettangolo è). Che terzo punto sarà nostra origine e le due linee per i punti di fuga sarà nostri assi. Chiamare la distanza dall'origine a un punto di fuga pi / 2. Ora estendere i lati del rettangolo dai punti di fuga agli assi, e segnare dove si intersecano gli assi. Scegliere un asse, misurare le distanze dalle due marchi all'origine, trasformare quelle distanze: x-> tan (x), e la differenza sarà la "vera" lunghezza di quel lato. Fare lo stesso per l'altro asse. Prendere il rapporto tra questi due lunghezze e il gioco è fatto.

Hai bisogno di ulteriori informazioni, tale cifra trasformata potrebbe provenire da qualsiasi parallelogramma dato un punto di vista arbitrario.

Quindi credo che avete bisogno di fare una sorta di calibrazione prima.

Modifica per chi ha detto che mi sbagliavo, qui va la dimostrazione matematica che ci sono infinite combinazioni di rettangoli / fotocamere che producono per la stessa proiezione:

Per semplificare il problema (come abbiamo solo bisogno il rapporto dei lati) supponiamo che il nostro rettangolo è definita dai punti seguenti: R=[(0,0),(1,0),(1,r),(0,r)] (questa semplificazione è la stessa di trasformare qualsiasi problema di una equivalente in un affine spazio).

Il poligono trasformata è definito come: T=[(tx0,ty0),(tx1,ty1),(tx2,ty2),(tx3,ty3)]

Esiste una matrice di trasformazione che soddisfa M = [[m00,m01,m02],[m10,m11,m12],[m20,m21,m22]] (Rxi,Ryi,1)*M=wi(txi,tyi,1)'

se espandiamo l'equazione di cui sopra per i punti,

per R_0 otteniamo: m02-tx0*w0 = m12-ty0*w0 = m22-w0 = 0

per R_1 otteniamo: m00-tx1*w1 = m10-ty1*w1 = m20+m22-w1 = 0

per R_2 otteniamo: m00+r*m01-tx2*w2 = m10+r*m11-ty2*w2 = m20+r*m21+m22-w2 = 0

e per R_3 otteniamo: m00+r*m01-tx3*w3 = m10+r*m11-ty3*w3 = m20 + r*m21 + m22 -w3 = 0

Finora abbiamo 12 equazioni, 14 incognite (9 dalla matrice, 4 dal wi e 1 per il rapporto r) e il resto sono noti valori (txi e tyi sono dati).

Anche se il sistema non fosse underspecified, alcune delle incognite sono moltiplicati tra loro (r e mi0 prodotti) rendendo il sistema non lineare (si potrebbe trasformare in un sistema lineare di assegnare un nuovo nome a ciascun prodotto, ma si 'll finiscono ancora con 13 incognite, e 3 delle quali è ampliato a infinite soluzioni).

Se si riesce a trovare alcun vizio di motivazione o la matematica, per favore fatemelo sapere.

Dropbox ha un ampio articolo sul loro blog di tecnologia in cui essi descrivono come hanno risolto il problema per loro app scanner.

https: //blogs.dropbox. com / tecnologia / 2016/08 / fast-documento rettifica-e-enhancement /

  

Rettificare un documento

     

Supponiamo che il documento di input è rettangolare nel mondo fisico, ma se non è esattamente di fronte alla telecamera, angoli risultanti nell'immagine sarà un quadrilatero convesso generale. Quindi, per soddisfare il nostro primo obiettivo, dobbiamo annullare la trasformazione geometrica applicata dal processo di acquisizione. Questa trasformazione dipende dal punto di vista della telecamera rispetto al documento (questi sono i cosiddetti parametri estrinseci), oltre a cose come la lunghezza focale della telecamera (i parametri intrinseci). Ecco un diagramma dello scenario di acquisizione:

     

Per annullare la trasformazione geometrica, dobbiamo prima determinare i detti parametri. Se assumiamo una telecamera ben simmetrica (senza astigmatismo, senza inclinazione, eccetera), le incognite di questo modello sono:

     
      
  • la posizione 3D della telecamera rispetto al documento (3 gradi di libertà),
  •   
  • l'orientamento 3D della telecamera rispetto al documento (3 gradi di libertà),
  •   
  • le dimensioni del documento (2 gradi di libertà), e
  •   
  • la lunghezza focale della telecamera (1 grado di libertà).
  •   
     

D'altro canto, la xey coordinate dei quattro angoli del documento identificati ci dà efficacemente otto vincoli. Mentre ci sono apparentemente più incognite (9) di vincoli (8), le incognite non sono del tutto liberi variabili-uno poteva immaginare scalare il documento fisicamente e posizionandolo più lontano dalla fotocamera, per ottenere una foto identica. Questa relazione pone un vincolo aggiuntivo, in modo da avere un sistema completamente vincolato da risolvere. (Il sistema attuale di equazioni risolviamo coinvolge alcune altre considerazioni, il relativo articolo di Wikipedia fornisce una buona sintesi: https : //en.wikipedia.org/wiki/Camera_resectioning)

     

Quando i parametri sono stati recuperati, possiamo annullare la trasformazione geometrica applicata dal processo di cattura per ottenere una bella immagine rettangolare. Tuttavia, questo è potenzialmente un processo che richiede tempo: si potrebbe cercare, per ciascun pixel di output, il valore del pixel corrispondente ingresso nell'immagine sorgente. Naturalmente, le GPU sono specificamente progettati per compiti come questo: il rendering di una texture in uno spazio virtuale. Esiste una vista trasformare il che sembra essere l'inverso della telecamera trasformare abbiamo risolto per! -Con cui si può rendere l'immagine in ingresso pieno e ottenere il documento rettificato. (Un modo semplice per vedere questo è da notare che una volta che hai l'immagine completa di input sullo schermo del telefono, è possibile inclinare e tradurre il telefono in modo tale che la proiezione della regione del documento sullo schermo appare rettilinea a voi.)

     

Infine, ricordo che c'era un equivoco rispetto alla scala: non possiamo dire se il documento è stato un formato lettera (8,5” x 11” ) o un poster (17” x 22” ), per esempio. Quali dovrebbero essere le dimensioni dell'immagine in uscita essere? Per risolvere questa ambiguità, si conta il numero di pixel all'interno del quadrilatero nell'immagine in ingresso, e impostare la risoluzione di uscita da corrispondere questo conteggio di pixel. L'idea è che noi non vogliamo upsample o downsample troppo l'immagine.

Sembra che ci sia ancora una certa confusione su questo problema interessante. Voglio dare una spiegazione facile da seguire per quando il problema può e non può essere risolto.

Vincoli e gradi di libertà

In genere quando ci troviamo di fronte a un problema come questo la prima cosa da fare è quello di valutare il numero di gradi sconosciuti di libertà (DOF) N, e il numero di equazioni indipendenti M che abbiamo per vincolare i gradi di libertà sconosciuti. È impossibile risolvere il problema se N se supera M (significa che ci sono meno vincoli di incognite). Siamo in grado di escludere tutti i problemi in cui questo è il caso ad essere irrisolvibile. Se N non supera M allora possono essere possibile risolvere il problema con una soluzione unica, ma questo non è garantito (vedi il secondo per l'ultimo paragrafo per un esempio).

Usiamo p 1, p 2, p 3 e p 4 per indicare le posizioni della 4 angoli della superficie piana in coordinate mondo. Usiamo R e t per essere la rotazione 3D e la traduzione che trasforma questi per le coordinate della macchina fotografica. Usiamo K per indicare la matrice intrinseca fotocamera 3x3. Ignoreremo distorsione della lente per ora. La posizione 2D del i th angolo dell'immagine della telecamera è data da q i = f ( K ( Rp i + t )) dove f è la funzione di proiezione f (x, y, z) = (x / z, y / z). Usando questa equazione sappiamo che ogni angolo nell'immagine ci dà due equazioni (cioè due vincoli) sulle nostre incognite: uno dal componente x di q i e uno dalla componente y. Quindi abbiamo un totale di 8 vincoli con cui lavorare. Il nome ufficiale di questi vincoli sono le vincoli riproiezione .

Dunque, quali sono i nostri gradi di libertà sconosciuti? Certamente R e t sono sconosciuti, perché non sappiamo posa della telecamera in coordinate mondo. Perciò abbiamo già 6 DOF sconosciuti: 3 per R (ad esempio imbardata, rollio e beccheggio) e 3 per t . Pertanto vi può essere un massimo di due incognite termini rimanenti ( K , p 1, p 2, p 3, p 4).

Diversi problemi

Possiamo costruire problemi diversi a seconda di quale due termini in ( K , p 1, p 2, p 3, p 4) si deve considerare come sconosciuto. A questo punto scriviamo su K nella forma usuale: K = (fx, 0, cx, 0, fy, cy; 0,0,1) dove fx e fy sono i termini lunghezza focale (fx / fy è normalmente chiamato il formato dell'immagine) e (cx, cy) è il punto principale (il centro di proiezione nell'immagine).

Si potrebbe ottenere un problema avendo fx e fy come i nostri due incognite, ed assumere (cx, cy, p 1, p 2, p 3, p 4) sono tutti noti. Infatti questo problema viene utilizzato e risolto in metodo di calibrazione fotocamera di OpenCV, utilizzando immagini di un bersaglio scacchiera planare. Questo è utilizzato per ottenere una stima iniziale per fx e fy, assumendo che il punto principale è al centro dell'immagine (che è un presupposto molto ragionevole per la maggior parte telecamere).

In alternativa, possiamo creare un problema diverso assumendo fx = fy, che è ancora abbastanza ragionevole per molte fotocamere, ed assumere questa lunghezza focale (indicato come f) è la solo sconosciuta in K . Quindi abbiamo ancora uno incognite a sinistra per giocare con (richiamo possiamo avere un massimo di due incognite). Quindi cerchiamo di utilizzare questo supponendo abbiamo conosciuto la forma del piano: come un rettangolo (che era l'assunto originale nella questione). Quindi possiamo definire gli angoli come segue: p 1 = (0,0,0), p 2 = (0, w, 0), P 3 = (h, 0,0) e p 4 = (h, w, 0), dove h e w denota l'altezza e la larghezza del rettangolo. Ora, perché abbiamo solo 1 sconosciuta sinistra, mettiamoci questo come rapporto di aspetto del piano: x = w / h. Ora la domanda è: possiamo allo stesso tempo recuperare x, f, R e t dalle 8 vincoli riproiezione? La risposta si scopre è sì! E la soluzione è data in carta di Zhang citato nella domanda.

L'ambiguità scala

Ci si potrebbe chiedere se un altro problema può essere risolto: se assumiamo K è nota e la 2 incognite sono he w. essi possono essere risolti dalle equazioni riproiezione? La risposta è no, e perché v'è un'ambiguità tra la dimensione del piano e la profondità del piano rispetto alla telecamera. In particolare se si scala angoli p I In s e scale t da s, allora s annulla nelle equazioni riproiezione. Pertanto la scala assoluta del piano non è recuperabile.

Ci possono essere altri problemi con diverse combinazioni per i DOF sconosciuti, per esempio a R , t , uno dei componenti del punto principali e il piano "s larghezza incognite. Tuttavia si ha la necessità di pensare a quali casi sono di uso pratico. Tuttavia non ho ancora visto un insieme sistematico di soluzioni per tutte le combinazioni utili!

Più punti

Si potrebbe pensare che se dovessimo aggiungere corrispondenze tra punti in più tra il piano e l'immagine, o sfruttare i bordi del piano, potremmo recuperare più di 8 gradi di libertà sconosciuti. Purtroppo la risposta è no. Questo è perché non aggiungono alcun vincolo in più indipendenti. La ragione è che i 4 angoli descrivono completamente la trasformazione dal piano all'immagine. Questo può essere visto montando una matrice omografia utilizzando i quattro angoli, che può quindi determinare le posizioni di tutti gli altri punti sul piano dell'immagine.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top