سؤال

بالنظر إلى صورة 2D لمستطيل مشوهة عن طريق المنظور:

enter image description here

أعلم أن الشكل كان في الأصل مستطيلا، لكنني لا أعرف حجمها الأصلي.

إذا كنت أعرف إحداثيات بكسل للزوايا في هذه الصورة، كيف يمكنني حساب النسب الأصلية، أي الحاصل (العرض / الارتفاع) للمستطيل؟

(الخلفية: الهدف هو إشراف صور المستندات المستطيلة تلقائيا، من المحتمل أن يتم اكتشاف الحافة مع تحويل Hough)

تحديث:

كان هناك بعض النقاش حول ما إذا كان من الممكن على الإطلاق لتحديد العرض: نسبة الارتفاع مع المعلومات المقدمة. كان فكرتي السذاجة أنه يجب أن يكون من الممكن، لأنه لا يمكنني التفكير في أي طريقة للمشروع على سبيل المثال مستطيل 1: 4 على Quadrangle المصور أعلاه. تظهر النسبة قريبة بوضوح من 1: 1، لذلك يجب أن تكون هناك طريقة لتحديدها رياضيا. ومع ذلك، لم يكن لدي دليل على هذا تخمين بلدي البديهي.

لم أفهم ذلك بعد تماما الحجج المقدمة أدناه، لكنني أعتقد أنه يجب أن يكون هناك بعض الافتراض الضمني الذي نفتقده هنا وهذا يتم تفسيره بشكل مختلف.

ومع ذلك، بعد ساعات من البحث، وجدت أخيرا بعض الأوراق ذات صلة بالمشكلة. أنا تكافح لفهم الرياضيات المستخدمة في هناك، حتى الآن دون نجاح. يبدو أن الورقة الأولى تناقش بالضبط ما أردت القيام به، لسوء الحظ دون أمثلة شفرة والرياضيات الكثيفة للغاية.

  • Zhengyou Zhang، Li-Wei هو، "المسح الضوئي السبورة وتعزيز الصورة"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.

    "نعرض كيفية استخدام الإسقاط المنظور ثنائي الأبعاد لمستطيل حجم غير معروف وموضعه في مساحة ثلاثية الأبعاد لتحديد معلمات زاوية مظهر الكاميرا نسبة إلى خطط المستطيل".

هل كانت مفيدة؟

المحلول

هنا هي محاولتي في الإجابة على سؤالي بعد قراءة الورق

التلاعب بمعادلات لبعض الوقت في حالة حكيم، وتوصلت إلى هذا الرمز الزائف في 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;

تحديث: إليك كيفية تحديد هذه المعادلات:

فيما يلي رمز في المريمية. وبعد يمكن الوصول إليها عبر الإنترنت في http://www.sagenb.org/home/pub/704/وبعد (حكيم مفيد حقا في حل المعادلات، وقابلة للاستخدام في أي متصفح، والتحقق من ذلك)

# 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-Code عند تحديدها

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

نصائح أخرى

تحديث

بعد قراءة التحديث الخاص بك، والنظر في المرجع الأول (مسح السبورة وتحسين الصور)، أرى أين النقطة المفقودة هي.

بيانات الإدخال للمشكلة هو رباعي (A، B، C، D)، و المركز O من الصورة المتوقعة. في المقالة، يتوافق مع افتراض u0 = v0 = 0. إضافة هذه النقطة، تصبح المشكلة مقيدة بما يكفي للحصول على نسبة العرض إلى الارتفاع للمستطيل.

ثم يتم استعادة المشكلة على النحو التالي: مع إعطاء رباعي (A، B، C، D) في الطائرة Z = 0، ابحث عن موقف العين E (0،0، H)، H> 0 ومستوى ثلاثي الأبعاد P بحيث الإسقاط (أ، ب، ج، د) على ف هو مستطيل.

لاحظ أن P يتم تحديده بواسطة E: للحصول على متوازي، يجب أن يحتوي P على أوجه التشابه إلى (EU) و (EV)، حيث U = (AB) X (CD) و V = (AD) X (BC).

تجريفيا، يبدو أن هذه المشكلة لها حل عام واحد فريد، مما يتوافق مع قيمة فريدة من نسبة W / H من المستطيل.

alt text alt text

المنشور السابق

لا، لا يمكنك تحديد نسبة المستطيل من الإسقاط.

في الحالة العامة، رباعي (A، B، C، D) من أربع نقاط غير رسمية في الطائرة Z = 0 هي إسقاط العديد من المستطيلات بلا حدود، مع العديد من نسب العرض / الارتفاع بلا حدود.

النظر في نقطة التلاشي يو، تقاطع (AB) و (CD) و V، تقاطع (AD) و (BC)، ونقطة I، تقاطع الأقطار (AC) و (BD). إلى مشروع ABCD، وهو متوازي للمركز يجب أن أستلقي على متن طائرة تحتوي على الخط الموازي مع (الأشعة فوق البنفسجية) من خلال النقطة الأولى. في أحد هذه الطائرة، يمكنك العثور على العديد من المستطيلات المتطرفة إلى ABCD، كلها نسبة W / H مختلفة.

شاهد هذه الصورتين تتم مع Cabri 3D. في حالتين، لم تتغير ABCD (على الطائرة Z = 0 الطائرة)، ولم يتم تغيير الطائرة الزرقاء التي تحتوي على المستطيل أيضا. الخط الأخضر مخفي جزئيا هو خط (UV) والخط الأخضر المرئي مواز له ويحتوي على I.

alt text alt text

الحجم ليس مطلوبا حقا، ولا توجد أبعاد. ومعرفة أي جانب هو نوع من غير ذي صلة بالنظر إلى أنه يستخدم صور / مسح المستندات. أشك في أن Hes ذاهب لمسح الجانبين الخلفي منهم.

"تقاطع الزاوية" هي طريقة تصحيح المنظور. قد يكون هذا مساعد:

كيفية رسم شبكة منظور الصحيح في 2D

وعلى مسألة سبب إعطاء النتائج H / W. ثم W / H: أنا أتساءل عما إذا كان التعبير عن المعادلة 20 أعلاه صحيح. نشر هو:

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

عندما أحاول تنفيذ ذلك مع OpenCV، أحصل على استثناء. ولكن كل شيء يعمل بشكل صحيح عندما أستخدم المعادلة التالية التي يبدو لي أشبه المعادلة 20: ولكن بناء على المعادلة 20، يبدو أنه ينبغي أن يكون:

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

يمكنك تحديد العرض / الارتفاع عن طريق هذه الإجابة حساب تنسيق مستطيل 3D مع تنسيق ظله؟. وبعد افترض أن المستطيل الخاص بك تدوير عند تقاطع النقطة القطرية احسب عرضه وارتفاعه. ولكن عند تغيير المسافة بين طائرة الظل الافتراضية إلى الطائرة الظل الحقيقية تتناسب مع المستطيل هو نفسه مع العرض / الارتفاع المحسوب!

من المستحيل معرفة عرض هذا المستطيل دون معرفة مسافة "الكاميرا".

مستطيل صغير ينظر إليه من مسافة سنتيمترات تبدو نفس المستطيل الضخم كما يظهر من الأمتار

ارسم مثلث متساوي الأيمن مع هذين من نقاط التلاشي ونقطة ثالثة أسفل الأفق (وهذا هو، على نفس الجانب من الأفق هو المستطيل). ستكون هذه النقطة الثالثة أصلنا وستكون سطرين إلى نقاط التلاشي محاورنا. اتصل بالمسافة من الأصل إلى نقطة التلاشي PI / 2. قم الآن بتوسيع جوانب المستطيل من نقاط التلاشي إلى المحاور، وعلامة حيث تتقاطع في المحاور. اختر محورا، وقياس المسافات من علامتين إلى الأصل، وتحويل تلك المسافات: X-> Tan (x)، والفرق سيكون الفرق هو الطول "الحقيقي" لهذا الجانب. تفعل الشيء نفسه بالنسبة للمحور الآخر. خذ نسبة هذين الأطوال وأنت انتهيت.

تحتاج إلى مزيد من المعلومات، قد يأتي الرقم الذي يتحول من أي موازية بالنظر إلى منظور تعسفي.

لذلك أعتقد أنك بحاجة إلى القيام ببعض المعايرة أولا.

تعديل: بالنسبة لأولئك الذين قالوا إنني كنت مخطئا، هنا يذهب الدليل الرياضي على أن هناك مجموعات لا حصر لها من المستطيلات / الكاميرات التي تسفر عن نفس الإسقاط:

من أجل تبسيط المشكلة (نظرا لأننا نحتاج فقط إلى نسبة الجانبين)، دعنا نفترض أن مستطيلنا يتم تعريفه بالنقاط التالية: R=[(0,0),(1,0),(1,r),(0,r)] (هذا التبسيط هو نفسه تحويل أي مشكلة إلى واحد مكافئ في مساحة Affine).

يتم تعريف المضلع المحول على النحو التالي: 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 من wi, و 1 للنسبة r) والباقي قيم معروفة (txi و tyi أعطي).

حتى لو لم يكن النظام غير محققت، فإن بعض المجهولين تضاعف فيما بينها (r و mi0 المنتجات) جعل النظام غير خطي (يمكنك تحويله إلى نظام خطي لتعيين اسم جديد لكل منتج، ولكن عليك أن تنتهي مع 13 غير معروف، و 3 منهم يتوسعون إلى حلول لا نهائية).

إذا كنت تستطيع العثور على أي عيب في التفكير أو الرياضيات، واسمحوا لي أن أعرف.

يحتوي Dropbox على مقالة واسعة النطاق حول بلوق التكنولوجيا الخاصة بهم حيث يصفون كيفية حل مشكلة تطبيق الماسح الضوئي الخاص بهم.

https:/blogs.dropbox.com/Tech2016/08/fast-document-Rectification-and-enhancent/

تصحيح المستند

نفترض أن وثيقة الإدخال مستطيلة في العالم المادي، ولكن إذا لم تكن مواجهة الكاميرا بالضبط، فإن الزوايا الناتجة في الصورة ستكون رباعية محدبة عامة. إذ تلبية هدفنا الأول، يجب علينا التراجع عن التحول الهندسي المطبق من خلال عملية الالتقاط. يعتمد هذا التحول على وجهة نظر الكاميرا بالنسبة إلى المستند (هذه هي المعلمات الخارجية المزعومة)، بالإضافة إلى أشياء مثل البعد البؤري للكاميرا (المعلمات الجوهرية). إليك مخطط لسيناريو القبض:

من أجل التراجع عن التحويل الهندسي، يجب علينا أولا تحديد المعلمات المذكورة. إذا افترضنا كاميرا متناظرة بشكل جيد (لا توجد استجماتية، ولا تشفى، وآخرون Cetera)، فإن المجهولين في هذا النموذج هي:

  • الموقع ثلاثي الأبعاد للكاميرا نسبة إلى المستند (3 درجات من الحرية)،
  • الاتجاه ثلاثي الأبعاد للكاميرا نسبة إلى الوثيقة (3 درجات من الحرية)،
  • أبعاد الوثيقة (2 درجة من الحرية)، و
  • البعد البؤري للكاميرا (درجة 1 من الحرية).

على الجانب الآخر، يمنحنا إحداثيات X و Y من زوايا المستندات الأربعة التي تم اكتشافها ثمانية قيود فعالة. في حين أن هناك مجهولين أكثر من غير المعروفين (9) من القيود (8)، فإن المجهولين غير مجهولين غير متغيرات مجانية تماما، يمكن أن يتخيل المرء تحجيم المستند جسديا ووضعه أكثر من الكاميرا، للحصول على صورة متطابقة. تضع هذه العلاقة حدودا إضافيا، لذلك لدينا نظام مقيد بالكامل ليتم حلها. (النظام الفعلي للمعادلات التي نحلها تنطوي على بعض الاعتبارات الأخرى؛ مقالة ويكيبيديا ذات الصلة تعطي ملخصا جيدا: https://en.wikipedia.org/wiki/camera_resctioning.)

بمجرد استرداد المعلمات، يمكننا التراجع عن التحول الهندسي المطبق من خلال عملية الالتقاط للحصول على صورة مستطيلة لطيفة. ومع ذلك، من المحتمل أن تكون هذه عملية تستغرق وقتا طويلا: سيبحث المرء، لكل بكسل الإخراج، قيمة بكسل المدخلات المقابلة في الصورة المصدر. بالطبع، يتم تصميم GPUs خصيصا للمهام مثل هذا: تقديم نسيج في مساحة افتراضية. هناك محول عرض - يحدث أن تكون معكوس تحويل الكاميرا الذي تم حله للتو من أجله! - مع أي واحد يمكن أن يجعل صورة الإدخال الكامل والحصول على المستند الصادر. (طريقة سهلة لرؤية ذلك هي ملاحظة أنه بمجرد أن يكون لديك صورة الإدخال الكاملة على شاشة هاتفك، يمكنك إمالة وترجمة الهاتف بحيث يظهر إسقاط منطقة المستندات على الشاشة مستطيلا إليك.)

أخيرا، أذكر أنه كان هناك غموض فيما يتعلق بالمقياس: لا يمكننا معرفة ما إذا كانت الوثيقة كانت ورقة بحجم حرف (8.5 "× 11") أو لوحة ملصقة (17 "× 22")، على سبيل المثال. ماذا يجب أن تكون أبعاد صورة الإخراج؟ لحل هذا الغموض، نحسب عدد البكسلات داخل الرباعي في صورة الإدخال، وقم بتعيين دقة الإخراج لتتناسب مع عدد البكسل هذا. الفكرة هي أننا لا نريد أن نملك صامته أو downs sample الصورة أكثر من اللازم.

يبدو أن هناك بعض الارتباك في هذه المشكلة المثيرة للاهتمام. أريد أن أعطي تفسيرا سهلة متابعة عندما يمكن حل المشكلة ولا يمكن حلها.

القيود والدرجات الحرية

عادة عندما نواجه مشكلة مثل هذا أول شيء يجب القيام به هو تقييم عدد درجات الحرية غير المعروفة (DOF) N، وعدد المعادلات المستقلة التي لدينا من أجل تقييد DOFs غير معروف. من المستحيل حل المشكلة إذا كان n إذا تجاوز م (وهذا يعني أن هناك قيودا أقل من غير المعروفة). يمكننا استبعاد جميع المشاكل التي يكون فيها الأمر غير قابل للحل. إذا كان n لا يتجاوز م ثم مايو يكون من الممكن حل المشكلة مع حل فريد، ولكن هذا غير مضمون (انظر الثاني إلى الفقرة الأخيرة للحصول على مثال).

لنستخدم ب1, ب2, ب3 و ب4 للدلالة على مواقف الزوايا الأربعة من سطح مستو في الإحداثيات العالمية. لنستخدم رديئة و ب أن تكون الدوران ثلاثي الأبعاد والترجمة التي تحول هذه إحداثيات الكاميرا. لنستخدم ك للإشارة إلى مصفوفة جوهرية كاميرا 3x3. سوف نتجاهل تشويه العدسة في الوقت الحالي. موقف ثنائي الأبعاد لل أنايرد في صورة الزاوية في صورة الكاميرا س:i = f (ك(RPأنا +.ب)) حيث f هو وظيفة الإسقاط f (x، y، z) = (x / z، y / z). باستخدام هذه المعادلة نعلم أن كل ركن في الصورة يعطينا معادين (أي قيود) على مجهولنا: واحد من مكون X من س:أنا وواحد من مكون y. لذلك لدينا ما مجموعه 8 قيود للعمل معها. الاسم الرسمي لهذه القيود قيود القيود.

إذن ما هي dofs غير معروفة؟ بالتأكيد رديئة و ب غير معروفة، لأننا لا نعرف أن تشكل الكاميرا في الإحداثيات العالمية. لذلك لدينا بالفعل 6 dofs غير معروف: 3 ل رديئة (مثل ياو، الملعب والفة) و 3 ل بوبعد لذلك يمكن أن يكون هناك أقصى قدر من اثنين غير معروف في المصطلحات المتبقية (ك, ب1, ب2, ب3, ب4). 

مشاكل مختلفة

يمكننا بناء مشاكل مختلفة اعتمادا على الشروط التي في (ك, ب1, ب2, ب3, ب4) سننظر كما غير معروف. في هذه المرحلة دعونا نكتب ك في الشكل المعتاد: ك= (FX، 0، CX؛ 0، fy، cy؛ 0،0،1) حيث FX و FY هي شروط البعد البؤري (FX / FY يسمى عادة نسبة الصورة الصورة) و (CX، CY) هي الرئيسية نقطة (مركز الإسقاط في الصورة).

يمكن أن نحصل على مشكلة واحدة من خلال وجود FX و FY كمجهولة، ويفترضون (CX، CY، ب1, ب2, ب3, ب4) جميعهم معروفون. في الواقع يتم استخدام هذه المشكلة ذاتها وحلها داخل طريقة معايرة كاميرا OpenCV، باستخدام صور لهدف مستودع الرقبة. يستخدم هذا للحصول على تقدير أولي ل FX و FY، من خلال افتراض أن النقطة الرئيسية في مركز الصورة (وهو افتراض معقول للغاية بالنسبة لمعظم الكاميرات).

بدلا من ذلك، يمكننا إنشاء مشكلة مختلفة عن طريق افتراض FX = FY، والذي مرة أخرى معقولة جدا بالنسبة للعديد من الكاميرات، ويفترض أن هذا البعد البؤري (يشار إليه كما F) هو فقط غير معروف في ك. وبعد لذلك لا يزال لدينا واحدة مجهولة اليسار للعب مع (أذكر يمكننا أن يكون لدينا كحد أقصى مجهولين). لذلك دعونا نستخدم هذا من خلال افتراض أننا نعرف شكل الطائرة: كمستطيل (كان الافتراض الأصلي في السؤال). لذلك يمكننا تحديد الزوايا على النحو التالي: ب1=(0,0,0), ب2 = (0، ث، 0)، ب3 = (ح، 0،0) و ب4 = (H، W، 0)، حيث تشير H و W إلى ارتفاع وعرض المستطيل. الآن، لأن لدينا فقط 1 غير معروفة اليسار، دعونا أن نضع هذا كنسبة إسباع الطائرة: x = w / h. الآن السؤال هو هل يمكننا في وقت واحد استرداد X، F، رديئة و ب من قيود القيود الثمانية؟ الجواب الذي اتضح هو نعم! ويرد الحل في ورقة تشانغ المذكورة في السؤال.

غموض النطاق

قد يتساءل المرء عما إذا كان يمكن حل مشكلة أخرى: إذا افترضنا ك هو معروف و 2 المجهول هم H و W. هل يمكن حلها من معادلات إعادة التوطين؟ الجواب لا، وهو لأن هناك غموض بين حجم الطائرة وعمق الطائرة إلى الكاميرا. على وجه التحديد إذا نقطع الزوايا بأنا بالمقدم ب بواسطة S، ثم يلغي في معادلات القمجة. لذلك النطاق المطلق للطائرة غير قابلة للاسترداد.

قد تكون هناك مشاكل أخرى مع مجموعات مختلفة ل DOF غير معروف، على سبيل المثال رديئة, ب, ، أحد مكونات النقاط الرئيسية وعرض الطائرة كمجهادين. ومع ذلك يحتاج المرء إلى التفكير في الحالات ذات الاستخدام العملي. ومع ذلك، لم أر الآن مجموعة منهجية من الحلول لجميع المجموعات المفيدة!

المزيد من النقاط

قد نفكر في أنه إذا كنا نضيف المراسف نقطة إضافية بين الطائرة والصورة، أو استغلال حواف الطائرة، يمكننا استرداد أكثر من 8 DOFs غير معروف. للأسف، الاجابة هي لا. هذا لأنهم لا يضيفون أي قيود مستقلة إضافية. السبب هو أن الزوايا الأربعة تصف تماما التحويل من الطائرة إلى الصورة. يمكن ملاحظة ذلك من خلال تركيب مصفوفة الموارد الزراعية باستخدام الزوايا الأربع، والتي يمكن بعد ذلك تحديد مواقف جميع النقاط الأخرى على الطائرة في الصورة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top