문제

주 2d 사각형의 왜곡하여 원근법:

enter image description here

내가 알고있는 모래 사각형,그러나 나는 알 수 없었습니다.

는 사실을 알고 있는 경우에는 픽셀의 좌표 코너에는 이 사진,어떻게 계산할 수 있습니 원래의 비율,즉몫(가로/세로)직사각형의?

(배경:의 목표는 자동으로 undistort 사진 직사각형의 문서,가장자리 검색 것으로 수행 hough transform)

업데이트:

몇 가지 논의가 있었지에 그것은 가능한 모든 결정하는 폭:높이의 비율과 정보를 주어집니다.나의 순진한 생각해야한다는 가능한 한,이후의 생각할 수 있는 방법에 대한 프로젝트 예제 1:4 형에 사각형을 묘사했다.비율이 나타나는 명확하게 가깝 1:1 할 수있는 방법을 결정하는 그것을 자극으로 이용합니다.그러나 나는 아무 증거도 없이 내 직관적인 생각한다.

나는 아직 완전히 이해 인수를 발표 아래,하지만 내가 있어야합니다 생각 어떤 암시는 가정을 우리는 여기에는 다르게 해석됩니다.

그러나,시간 후기 내용을 마지막으로 일부를 발견한 논문에 관련된 문제입니다.내가 이해하기 위해 고군분투하는 수학에서 사용되는,그래서 거기다.특히 종이 먼저 보인다 정확히 무엇인가 하고 싶은,불행하게도 없는 예제 코드와 매우 밀도 수학이다.

  • Zhengyou 장,리튬-웨이 그는,"화이트 보드 스캐닝 및 이미지 향상" http://research.microsoft.com/en-us/um/people/zhang/papers/tr03-39.pdf p.11

    "때문에 초점의 이미지를 사각형을 나타나게 될 사각형.그러나 우리가 알고 있기 때문에 그것은 사각형 공간에서,우리는 예측할 수 있을 두 카메라의 초점 길이 및 직사각형의 비율."

  • ROBERT M.HARALICK"을 결정하는 카메라는 매개 변수는 관점에서의 프로젝션형" http://portal.acm.org/citation.cfm?id=87146

    "우리가 사용하는 방법을 보여 2D 관점의 투영이 직사각형의 미지의 크기와 위치 3D 에서 공간을 결정하는 카메라 모 각 매개변수에 상대적 계획의 사각형입니다."

도움이 되었습니까?

해결책

다음은 종이를 읽은 후 내 질문에 대답하려는 시도입니다.

나는 세이지에서 한동안 방정식을 조작 하고이 의사 코드를 C 스타일로 생각해 냈습니다.


// 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;

업데이트 : 다음은 다음과 같은 방정식이 다음과 같습니다.

다음은 코드입니다 세이지. 온라인으로 액세스 할 수 있습니다 http://www.sagenb.org/home/pub/704/. (Sage는 방정식을 해결하는 데 정말 유용하며 모든 브라우저에서 사용할 수 있습니다.

# 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())
              ) 

C- 코드의 단순화 된 방정식에 의해 결정됩니다

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

다른 팁

업데이트

업데이트를 읽고 첫 번째 참조 (화이트 보드 스캔 및 이미지 향상)를 살펴본 후 누락 된 지점이 어디에 있는지 알 수 있습니다.

문제의 입력 데이터는 4 배 (a, b, c, d)입니다. 그리고 투사 된 이미지의 중심 O. 이 기사에서는 U0 = v0 = 0 가정에 해당합니다. 이 점을 추가하면 문제가 사각형의 종횡비를 얻을 수있을 정도로 문제가 발생합니다.

그런 다음 문제는 다음과 같이 재조정됩니다. z = 0 평면에서 4 배 (a, b, c, d)가 주어지면 눈 위치 e (0,0, h), H> 0 및 3D 평면 P를 찾으십시오. p에서 (a, b, c, d)의 투영은 사각형이다.

P는 평행 사변형을 얻으려면 e : 평행 사변형에 의해 결정됩니다. p는 U = (ab) x (cd) 및 v = (ad) x (bc)와 (EU) 및 (EV)와 평행을 포함해야합니다.

실험적으로,이 문제는 일반적으로 직사각형의 W/H 비율의 고유 한 값에 해당하는 하나의 고유 한 솔루션을 가지고있는 것으로 보입니다.

alt text alt text

이전 게시물

아니요, 투영에서 사각형 비율을 결정할 수 없습니다.

일반적으로 Z = 0 평면의 4 개의 비 콜린 핵심 점의 4 배 (a, b, c, d)는 무한히 많은 직사각형의 투영이며, 무한한 폭/높이 비율이 있습니다.

두 가지 소실점 U, (AB) 및 (CD) 및 V의 교차점, (AD) 및 (BC)의 교차점 및 포인트 I, 두 대각선 (AC) 및 (BD)의 교차점을 고려하십시오. 중앙의 평행 사변형 인 ABCD로 투사하려면 지점 I을 통해 (UV)와 평행 한 선을 포함하는 평면에 누워 있어야합니다. 하나의 평면에서는 ABCD로 투영되는 많은 직사각형을 찾을 수 있습니다.

Cabri 3D로 수행 된이 두 이미지를 참조하십시오. 두 경우에 ABCD는 변하지 않고 (회색 Z = 0 평면에서) 사각형을 포함하는 파란색 평면도 변경되지 않습니다. 부분적으로 숨겨진 녹색 선은 (UV) 라인이고 가시 녹색 선은 그것과 평행하고 I를 포함합니다.

alt text alt text

크기는 실제로 필요하지 않으며 비율도 아닙니다. 그리고 어느 쪽이 올라 있는지 아는 것은 그가 문서의 사진/스캔을 사용하고 있다는 것을 고려할 때 관련이 없습니다. 나는 그가 그들의 뒷면을 스캔 할 것 같다.

"코너 교차로"는 관점을 수정하는 방법입니다. 도움이 될 수 있습니다.

2D에서 원근법 그리드를 그리는 방법

결과가 왜 H/W를 제공하는지에 대한 문제에 대해, W/H : 위의 식 20의 표현이 정확한지 궁금합니다. 게시 된 IS :

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

OpenCV로 실행하려고하면 예외가됩니다. 그러나 다음 방정식을 사용할 때 모든 것이 올바르게 작동합니다.

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

이 답변으로 너비 / 높이를 결정할 수 있습니다 사각형 3D 조정을 계산하여 그림자 코디네이션?. 교차로 대각선 지점에서 사각형이 회전한다고 가정하면 폭과 높이를 계산하십시오. 그러나 가정 섀도우 평면 사이의 거리를 실제 그림자 평면 사이의 거리를 실제 그림자 평면으로 바꾸면 계산 된 너비 / 높이와 동일합니다!

'카메라'의 거리를 알지 못하고이 사각형의 너비를 아는 것은 불가능합니다.

5 센티미터 거리에서 볼 수있는 작은 사각형은 미터 떨어진 곳에서 볼 수있는 거대한 사각형과 동일하게 보입니다.

이 두 번의 소실점과 수평선 아래의 세 번째 점 (즉, 직사각형과 같은 수평선의 동일한 쪽)으로 오른쪽 이등변 삼각형을 그립니다. 그 세 번째 요점은 우리의 원점이 될 것이며 소실점의 두 줄은 우리의 축입니다. 원점에서 소실점 PI/2까지의 거리를 호출하십시오. 이제 사각형의 측면을 사라지는 지점에서 축으로 확장하고 축과 교차하는 위치를 표시하십시오. 축을 선택하고 두 자국에서 원점까지의 거리를 측정하고 그 거리를 변형 시키십시오 : x-> tan (x), 그 차이는 해당 측면의 "진정한"길이입니다. 다른 축에 대해서도 똑같이하십시오. 이 두 길이의 비율을 취하면 완료되었습니다.

더 많은 정보가 필요합니다. 변형 된 수치는 임의의 관점에서 평행 사변형에서 나올 수 있습니다.

따라서 먼저 어떤 종류의 교정을해야한다고 생각합니다.

편집하다: 내가 틀렸다고 말한 사람들을 위해, 여기에는 동일한 투영을 산출하는 직사각형/카메라의 무한한 조합이 있다는 수학적 증거가 있습니다.

문제를 단순화하려면 (측면의 비율 만 필요하므로) 사각형이 다음 지점으로 정의된다고 가정 해 봅시다. R=[(0,0),(1,0),(1,r),(0,r)] (이 단순화는 아핀 공간에서 문제를 동등한 문제로 변환하는 것과 동일합니다).

변환 된 다각형은 다음과 같이 정의됩니다. T=[(tx0,ty0),(tx1,ty1),(tx2,ty2),(tx3,ty3)]

변환 매트릭스가 있습니다 M = [[m00,m01,m02],[m10,m11,m12],[m20,m21,m22]] 만족합니다 (Rxi,Ryi,1)*M=wi(txi,tyi,1)'

포인트에 대한 위의 방정식을 확장하면

~을 위한 R_0 우리는 얻는다 : m02-tx0*w0 = m12-ty0*w0 = m22-w0 = 0

~을 위한 R_1 우리는 얻는다 : m00-tx1*w1 = m10-ty1*w1 = m20+m22-w1 = 0

~을 위한 R_2 우리는 얻는다 : m00+r*m01-tx2*w2 = m10+r*m11-ty2*w2 = m20+r*m21+m22-w2 = 0

그리고 R_3 우리는 얻는다 : m00+r*m01-tx3*w3 = m10+r*m11-ty3*w3 = m20 + r*m21 + m22 -w3 = 0

지금까지 우리는 12 개의 방정식, 14 개의 알 수없는 변수 (매트릭스에서 9 개, 4에서 4 wi, 비율의 경우 1 r) 그리고 나머지는 알려진 값입니다 (txi 그리고 tyi 주어진다).

시스템이 지정되지 않은 경우에도 미지수 중 일부는 그들 사이에 곱합니다 (r 그리고 mi0 제품) 시스템을 비선형으로 만들 수 있습니다 (각 제품에 새 이름을 할당하는 선형 시스템으로 변환 할 수 있지만 13 개의 미지의 것으로 끝나고 3 개는 무한 솔루션으로 확장됩니다).

추론이나 수학에서 결함을 찾을 수 있다면 알려주십시오.

Dropbox는 기술 블로그에 광범위한 기사를 통해 스캐너 앱의 문제를 해결하는 방법을 설명합니다.

https://blogs.dropbox.com/tech/2016/08/fast-document-rectification-and-enhancement/

문서 수정

우리는 입력 문서가 물리적 세계에서 직사각형이라고 가정하지만 카메라를 정확하게 직면하지 않으면 이미지의 결과 코너는 일반적인 볼록 사변형이됩니다. 따라서 첫 번째 목표를 충족시키기 위해 캡처 프로세스에 의해 적용된 기하학적 변환을 취소해야합니다. 이 변환은 카메라의 초점 길이 (본질 매개 변수)와 같은 것 외에도 문서에 대한 카메라의 관점 (소위 외부 매개 변수입니다)에 따라 다릅니다. 다음은 캡처 시나리오의 다이어그램입니다.

기하학적 변환을 취소하려면 먼저 상기 매개 변수를 결정해야합니다. 우리가 멋지게 대칭 카메라를 가정하면 (비 점수증, 왜곡 등 없음),이 모델의 미지는 다음과 같습니다.

  • 문서와 관련된 카메라의 3D 위치 (자유도),
  • 문서에 대한 카메라의 3D 방향 (3도 자유도),
  • 문서의 차원 (2도 자유도),
  • 카메라의 초점 길이 (1도 자유).

반대로, 4 개의 감지 된 문서 모서리의 X- 및 y 코디네이트는 우리에게 효과적으로 8 개의 제약 조건을 제공합니다. 제약 조건 (8)보다 알려지지 않은 겉보기 (9)가 있지만, 미지의 것은 완전히 자유로운 변수가 아닙니다. 하나는 문서를 물리적으로 스케일링하고 카메라에서 더 배치하여 동일한 사진을 얻는 것을 상상할 수 있습니다. 이 관계는 추가적인 제약 조건을 제시하므로 해결해야 할 완전히 제한된 시스템이 있습니다. (우리가 해결하는 실제 방정식 시스템에는 몇 가지 다른 고려 사항이 포함됩니다. 관련 Wikipedia 기사는 좋은 요약을 제공합니다. https://en.wikipedia.org/wiki/camera_resection)

파라미터가 복구되면 캡처 프로세스에 의해 적용된 기하학적 변환을 취소하여 멋진 직사각형 이미지를 얻을 수 있습니다. 그러나 이것은 잠재적으로 시간이 많이 걸리는 프로세스입니다. 하나는 소스 이미지에서 해당 입력 픽셀의 값을 각 출력 픽셀에 대해 조회합니다. 물론 GPU는 이와 같은 작업을 위해 특별히 설계되었습니다. 가상 공간에서 질감을 렌더링합니다. 우리가 방금 해결 한 카메라 변환의 역수가 발생하는 뷰 변환이 존재합니다! (이를 볼 수있는 쉬운 방법은 전화 화면에 전체 입력 이미지가 있으면 화면의 문서 영역의 투영이 직접 나타나도록 휴대 전화를 기울이고 번역 할 수 있습니다.)

마지막으로, 규모와 관련하여 모호함이 있음을 기억하십시오. 예를 들어 문서가 문자 크기의 논문 (8.5”x 11”)인지 포스터 보드 (17”x 22”)인지 알 수 없습니다. 출력 이미지의 크기는 무엇입니까? 이 모호성을 해결하기 위해 입력 이미지의 사변형 내의 픽셀 수를 계산 하고이 픽셀 수와 일치하도록 출력 해상도를 설정합니다. 아이디어는 이미지를 너무 많이 올리거나 다운 샘플링하고 싶지 않다는 것입니다.

가 여전히 일부에 혼란을 이 흥미로운 문제입니다.I want to give easy-to-follow 에 대한 설명을 할 때 문제할 수 있고 해결할 수 없습니다.

제약 조건과 자유도

일반적으로 할 때 우리는 문제에 직면 다음과 같이 할 첫 번째 일을 평가하는 것은 번호를 알 수 없는 자유도(자유도)N 및 독립적 방정식 M 우리가 제한하는 알 수 없는 자유도.그것은 불가능한 문제를 해결하기하는 경우 N 를 초과하는 경우 M(의미가 적은 제약조건 보다는 미지수).우리가 배제할 수 있습니다 모든 문제는 이 경우로 풀지 못하게 됩니다.경 N 초과하지 않 M 음 될 가능한 문제를 해결하기 위해 독특한 솔루션이지만,이지상(참조로 두 번째 마지막 문단에 대한 예).

자 사용 p1, p2, p3 p4 을 나타내는 위치의 4 개의 모서리 평면 세계에서 좌표입니다.자 사용 Rt 수 3D 회전과 번역을 변환하는 이러한 카메라의 좌표입니다.자 사용 K 을 나타내기 위 3x3 카메라 본질적인 행렬입니다.우리는 무시 렌즈의 왜곡한다.2D 위치 번째 코너에서 카메라의 이미지가에 의해 주어 qi=f(K(Rpi+t))는 f 프로젝션 기능을 f(x,y,z)=(x/z,y/z).이 방정식을 사용하여 우리가 알고 있는 각 코너에서는 이미지가 우리에게 두 가지 방정식(i.e두 개의 제약 조건)에서 우리의 미지수:에서 하나 x 의 구성 요소 q난과에서 하나 y 구성 요소입니다.그래서 우리는 총 8 개의 제약으로 작동합니다.의 공식 이름이 이러한 제약 조건은 재투영약.

그래서 우리는 알 수 없는 자유도?실 Rt 알 수 있기 때문에,우리는 알지 못한 카메라세 세계에서 좌표입니다.따라서 우리는 이미 6 자유도 알 수 없는:3 R (예:yaw,피치와 롤)및 3 t.따라서 수 있는 최대의 두 개의 미지의 나머지 조(K, p1, p2, p3, p4). 

다른 문제

우리가 구성할 수 있는 다른 문제에 따라서는 두 가지 측면에서(K, p1, p2, p3, p4)우리는 것을 고려으로 알 수 없습니다.이 시점에서 의 작성 K 에서 일반적인 형태: K=(fx,0,cx;0,fy,cy;0,0,1)디 fx 및 fy 초점 길이 조(fx/fy 은 일반적으로 불리는 이미지 측면 비율)과(cx,cy)은 주점(중심의 투상에서 이미지).

우리는 얻을 수 있는 하나의 문제는 fx 및 fy 으로 우리의 두 가지 미지수 및 가정(cx,cy, p1, p2, p3, p4)모든 알려져 있습니다.실제로 바로 이 문제가 사용되고 해결에 OpenCV 의 카메라 구경측정 방법을 사용하여 이미지의 바둑판은 평면 대상입니다.이것을 사용하면 초기에 대한 견적 fx 및 fy 는 것으로 가정하여 주 시점에 이미지 센터(는 매우 합리적인 가정 대부분의 카메라에서).

또한을 만들 수 있습니다 다른 문제를 가정하여 fx=회계연도는 매우 합리적인을 위해 많은 카메라,그리고 이 초점 길이(로 표시됩 f) 알 수 없음에 K.따라서 우리는 여전히 미지 왼쪽으로 재생(을 기억할 수 있는 최대의 두 가지 미지수).그래서 이것을 사용해서 벗어나 우리는 잘 알려진 모양의 비행기:사각형으로(본래 가정에서 질문).정의할 수 없습니다 따라서 모서리에 다음과 같다: p1=(0,0,0), p2=(0,w,0), p3=(h,0,0) p4=(h,w,0),어디서와 w 을 나타내의 너비와 높이를 사용합니다.지금 가지고 있기 때문에 우리는 1 는 알 수 없는 남자 설정으로 이것이 비행기의 화면 비율:x=w/h.이 질문은 우리는 동시에 복 x,f, Rt 에서 8 인해야 합 제약 조건?답변 그것을 밝혀 그렇습니다!고의 솔루션에 주어진 장의 종이에서 인용한 문제입니다.

규모가 모호성

나면 또 다른 문제를 해결할 수 있습니다:면 우리는 가정 K 알려져 있으며 2 개의 알가서고 있습니다.할 수 있습니에서 해결해야 합 방정식?대답은 아니고 있기 때문에 모호성의 크기 사이에 비행기 비행기의 깊이를 카메라가 있습니다.특히면 우리는 가늠자 모서리 pi s 고 규모 t s,그 s 을 취소하에 재투영 답변을 받으실 수 있습니다.따라서 절대 규모의 비행기는 복구되지 않습니다.

있을 수 있습니다 다른 문제를 다양한 조합으로 알 수없는 자유도,예를 들어 가 R, t, 하나의 주요 포인트 구성 요소와 비행기"s 폭됩니다.그러나 하나가 필요로 생각하는 경우는 실제 사용.그럼에도 불구하고 나는 아직 보지 못했다 체계적인 설정의 솔루션에 대한 유용한 모든 조합에!

더 많은 포인트

우리는 생각할 수 있습니다면 우리가 추가로 지점의 대응이 비행기와 이미지,또는 부당하게 사용할 가장자리가 비행기에서,우리는 복구할 수 있는 8 개 이상 자유도 알 수 없는.슬프게도 답은 없습니다.이것은 추가하지 않기 때문에 추가 독립적인 제약 조건이 있습니다.기 때문에 그 이유는 4 코너 설명 변형 비행기에서 이미지입니다.이해 볼 수 있는 원 포인트는 다른 포인트로 적합 매트릭스를 사용하여 네 개의 모서리,그 결정의 위치를 다른 모든 지점에서 비행기에서 이미지입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top