블로그 이미지
Leeway is... the freedom that someone has to take the action they want to or to change their plans.
maetel

Notice

Recent Post

Recent Comment

Recent Trackback

Archive

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
  • total
  • today
  • yesterday

Category

'Computer Vision'에 해당되는 글 50건

  1. 2011.01.17 Seam Carving
  2. 2010.11.11 Velho, Frery & Gomes [Image Processing for Computer Graphics and Vision] (2nd ed)
  3. 2010.09.26 Dazhi Chen & Guangjun Zhan, "A New Sub-Pixel Detector for X-Corners in Camera Calibration Targets"
  4. 2010.09.26 Luca Lucchese & Sanjit K. Mitra "Using saddle points for subpixel feature detection in camera calibration targets"
  5. 2010.09.25 Otsu's method
  6. 2010.07.07 Tomas Svoboda <Multi-Camera Self-Calibration>
  7. 2010.06.22 Rafael Grompone von Gioi et al. "LSD: A Fast Line Segment Detector with a False Detection Control"
  8. 2010.06.14 E. Trucco and A. Verri <Introductory Techniques for 3-D Computer Vision>
  9. 2010.06.14 pinhole camera model
  10. 2010.06.04 OpenCV: cvFindCornerSubPix()
  11. 2010.06.02 Duane C. Brown "Close-Range Camera Calibration"
  12. 2010.05.26 virtual studio 구현: camera calibration
  13. 2010.05.18 Jonathan Merritt's Camera Calibration for Blender
  14. 2010.05.18 virtual studio 구현: camera calibration test 1
  15. 2010.05.14 virtual studio 구현: feature points matching test
  16. 2010.04.07 OpenCV: cvHoughLines2() 연습 코드
  17. 2010.04.06 virtual studio 구현: line fitting test
  18. 2010.03.31 Harris corner detector
  19. 2010.03.31 OpenCV: cvCanny() 연습 코드
  20. 2010.03.30 Canny edge detection
  21. 2010.03.15 Three-dimensional computer vision: a geometric viewpoint By Olivier Faugeras
  22. 2010.03.03 ARToolKit test log
  23. 2010.02.10 R. Y. Tsai "A Versatile Camera Calibration Technique for High Accuracy 3-D Maching Vision Metrology Using Off-the-shelf TV Cameras and Lenses"
  24. 2010.02.10 Seong-Woo Park & Yongduek Seo & Ki-Sang Hong <Real-Time Camera Calibration for Virtual Studio>
  25. 2010.02.09 Moons & Gool & Vergauwen [3D Reconstruction from Multiple Images]
2011. 1. 17. 01:21 Computer Vision
Shai Avidan, Ariel Shamir, Seam Carving for Content-Aware Image Resizing, SIGGRAPH, 2007





posted by maetel
2010. 11. 11. 16:22 Computer Vision
Image Processing for Computer Graphics and Vision, 2nd ed. 
Velho, Luiz, Frery, Alejandro C., Gomes, Jonas
Springer, 2009


비록 학부 4학년은 아니었더라도 석사 1학기에 봤었다면 좋았을 것을...


'Computer Vision' 카테고리의 다른 글

Winsock  (0) 2010.11.26
camera Firefly (FFMV-03M2M)  (0) 2010.11.25
Duda, Hart & Stork [Pattern Classification] (2nd ed)  (0) 2010.11.11
OpenCV 2.1.0 Installation on Mac OS X Snow Leopard  (0) 2010.11.02
OpenCV: Decision Trees  (0) 2010.10.12
posted by maetel
2010. 9. 26. 15:57 Computer Vision
Dazhi Chen & Guangjun Zhan, "A New Sub-Pixel Detector for X-Corners in Camera Calibration Targets," WSCG Short Papers (2005): 97-100



The School of Instrumentation Scienc & Optoelectronics Engineering (SISOE), Beijing University of Aeronautics and Astronautics
posted by maetel
2010. 9. 26. 15:47 Computer Vision
L. Lucchese and S.K. Mitra. Using saddle points for subpixel feature detection in camera calibration targets. In Proceedings of the 2002, Asia Pacific Conference on Circuits and Systems, volume 2, pages 191-195, 2002.



posted by maetel
2010. 9. 25. 01:44 Computer Vision
http://en.wikipedia.org/wiki/Otsu's_method informed by prof.


Nobuyuki Otsu (1979). "A threshold selection method from gray-level histograms". IEEE Trans. Sys., Man., Cyber. 9: 62–66. doi:10.1109/TSMC.1979.4310076



OpenCV 함수 cvThreshold()


ref.
Bryan S. Morse's Brigham Young University (1998-2000) Lecture 4: Thresholding

Milan Sonka, Vaclav Hlavac, Roger Boyle, <Image Processing, Analysis, and Machine Vision> (3rd ed.), Thomson (2008)
: Chapter 6 Segmentation I: 6.1.2 Optimal thresholding (180p)






posted by maetel
http://cmp.felk.cvut.cz/~svoboda/SelfCal/

Center for Machine Perception, Department of Cybernetics, Czech Technical University in Prague
posted by maetel
2010. 6. 22. 17:51 Computer Vision
Rafael Grompone von Gioi, Jérémie Jakubowicz, Jean-Michel Morel, Gregory Randall, LSD: A Fast Line Segment Detector with a False Detection Control, IEEE Transactions on Pattern Analysis and Machine Intelligence, vol. 32, no. 4, pp. 722-732, Apr. 2010. doi:10.1109/TPAMI.2008.300


http://www.ipol.im/pub/algo/gjmr_line_segment_detector/

올~ 짱! 지난 2년 동안 발견한 논문 중 가장 마음에 들고 게다가 와 닿는다! (다른 논문들은 대부분 내게 우이독경이어서 그런 거지만...) 그래 난 이런 가장 상식적이고 기본적인 접근이 좋더라.


http://en.wikipedia.org/wiki/Linear_time#Linear_time


posted by maetel
2010. 6. 14. 22:14 Computer Vision
E. Trucco and A. Verri, Introductory Techniques for 3-D Computer Vision, Englewood Cliffs, NJ: Prentice-Hall, 1998.

(google books overview)
posted by maetel
2010. 6. 14. 22:13 Computer Vision
ref.
Learning OpenCV
Chapter 11: Camera Models and Calibration


Al-Hytham, Book of Optics, 1038

Descartes
Kepler
Galileo
Newton
Hooke
Euler
Fermat
Snell

J. J. O'Connor and E. F. Roberson, "Light through the ages: Ancient Greece to Maxwell," http://www-groups.dcs.st-and.ac.uk/~history/HistTopics/Light_1.html

E. Trucco and A. Verri, Introductory Techniques for 3-D Computer Vision, Englewood Cliffs, NJ: Prentice-Hall, 1998.

B. Jaehne, Digital Image Processing, 3rd ed., Berlin: Springer-Verlag, 1995.

B. Jaehne, Practical Handbook on Image Processing for Scientific Applications, Boca Raton, FL: CRC Press, 1997

R. Hartley and A. Zisserman, Multiple View Geometry in Computer Vision, Cambridge, UK: Cambridge University Press, 2006.

D. Forsyth and J. Ponce, Computer Vision: A Modern Approach, Englewood Cliffs, NJ: Prentice-Hall, 2003.

L. G. Shapiro and G. C. Stockman, Computer Vision, Englewood Cliffs, NJ: Prentice-Hall, 2002

G. Xu and Z. Zhang, Epipolar Geometry in Stereo, Motion and Object Recognition, Dordrecht: Kluwer, 1996




posted by maetel
2010. 6. 4. 22:16 Computer Vision
OpenCV 함수 cvFindCornerSubPix or cv::cornerSubPix

ref.
Learning OpenCV: Chapter 10. Tracking and Motion: "Subpixel Corners"
319p: If you are processing images for the purpose of extracting geometric measurements, as opposed to extracting features for recognition, then you will normally need more resolution than the simple pixel values supplied by cvGoodFeaturesToTrack(). That is subpixels come with integer coordinates whereas we sometimes require real-valued coordinates.

source code file: /opencv/src/cv/cvcornersubpix.cpp
link: https://code.ros.org/trac/opencv/browser/tags/2.1/opencv/src/cv/cvcornersubpix.cpp


fitting a curve (a parabola)
ref. newer techniques
Lucchese02
Chen05

CvTermCriteria


icvGetRectSubPix_8u32f_C1R()
definition: source code file: /opencv/src/cv/cvsamplers.cpp


icvSepConvSmall3_32f()
definition: source code file: /opencv/src/cv/cvderiv.cpp


posted by maetel
2010. 6. 2. 20:57 Computer Vision
D.C. Brown, Close-Range Camera Calibration, Photogrammetric Engineering, pages 855-866, Vol. 37, No. 8, 1971.









posted by maetel
2010. 5. 26. 22:59 Computer Vision
2010/02/10 - [Visual Information Processing Lab] - Seong-Woo Park & Yongduek Seo & Ki-Sang Hong
2010/05/18 - [Visual Information Processing Lab] - virtual studio 구현: camera calibration test



1. 내부 파라미터 계산

cvCalibrateCamera2() 함수를 이용하여 카메라 내부/외부 파라미터와 렌즈 왜곡 변수를 얻는다.


frame # 191  ---------------------------
# of found lines = 8 vertical, 6 horizontal
vertical lines:
horizontal lines:
p.size = 48
CRimage.size = 48
# of corresponding pairs = 15 = 15

camera matrix
fx=286.148 0 cx=207.625
0 fy=228.985 cy=98.8437
0 0 1

lens distortion
k1 = 0.0728017
k2 = -0.0447815
p1 = -0.0104295
p2 = 0.00914935

rotation vector
-0.117104  -0.109022  -0.0709096

translation vector
-208.234  -160.983  163.298



이 결과를 가지고 cvProjectPoints2()를 써서 패턴의 점에 대응되는 이미지 상의 점을 찾은 결과는 아래와 같다.




1-1.

카메라 내부 파라미터와 외부 파라미터를 모두 계산하는 cvCalibrateCamera2() 함수 대신 내부 파라미터만 계산하는
cvInitIntrinsicParams2D() 함수를 써 본다.



2. lens distortion(kappa1, kappa2)을 가지고 rectification

패턴 인식이 성공적인 경우 당연히 카메라 캘리브레이션 결과가 정확해지며, 이로부터 가상의 물체를 합성하기 위해 필요한 object 또는 graphic coordinate을 실시간으로 계산할 수 있다. 현재 우리 프로그램에서 패턴 인식이 실패하는 원인은 직선 검출의 오차인데, 이 오차의 원인으로는 여러가지가 있지만 가장 큰 것은 렌즈 왜곡이다. (현재 렌즈 왜곡을 고려하지 않고 있다.) 그래서 실제로는 하나의 직선에 대해 여러 개 (2-3개)의 직선을 검출하며 (NMS 알고리즘만으로는 이 오차를 줄이는 데 한계를 보이고 있어), 이로부터 계산된 교차점들의 위치 좌표 오차는 cross ratio 계산에 결정적인 오차로 작용한다. 현재 방식의 패턴 생성과 패턴 인식은 cross ratios 값에 절대적으로 의존하고 있기 때문에 이 문제를 반드시 해결해야 한다. 그러므로 렌즈 왜곡을 고려하여 입력 이미지를 펴서 (rectification) 기존의 패턴 인식 알고리즘을 적용하자.

ref.
Learning OpenCV: Chapter 6: Image Trasnforms
opencv v2.1 documentation — Geometric Image Transformations


1) Undistortion

Learning OpenCV: 396p
"OpenCV provides us with a ready-to-use undistortion algorithm that takes a raw image and the distortion coefficients from cvCalibrateCamera2() and produces a corrected image (see Figure 11-12). We can access this algorithm either through the function cvUndistort2(), which does everything we need in one shot, or through the pair of routines cvInitUndistortMap() and cvRemap(), which allow us to handle things a little more efficiently for video or other situations where we have many images from the same camera. ( * We should take a moment to clearly make a distinction here between undistortion, which mathematically removes lens distortion, and rectifi cation, which mathematically aligns the images with respect to each other. )

입력 영상 (렌즈 왜곡)

출력 영상 (왜곡 제거)






 

# of corresponding pairs = 30 = 30

camera matrix
fx=94.6664 0 cx=206.772
0 fy=78.3349 cy=158.782
0 0 1

lens distortion
k1 = 0.0130734
k2 = -0.000955421
p1 = 0.00287948
p2 = 0.00158042









            if ( ( k1 > 0.3 && k1 < 0.6 ) && ( cx > 150.0 && cx < 170.0 ) && ( cy > 110 && cy < 130 ) )


# of corresponding pairs = 42 = 42

camera matrix
fx=475.98 0 cx=162.47
0 fy=384.935 cy=121.552
0 0 1

lens distortion
k1 = 0.400136
k2 = -0.956089
p1 = 0.00367761
p2 = 0.00547217







2) Recitifaction




cvInitUndistortRectifyMap



3. line detection




4. 패턴 인식 (대응점 찾기)




5. 외부 파라미터 계산 (4의 결과 & lens distortion = 0 입력)
cvFindExtrinsicCameraParams2()



6. reprojection
2에서 얻은 rectificated image에 할 것




posted by maetel
2010. 5. 18. 01:43 Computer Vision
http://jmerritt.warpax.com/pytsai/

Jonathan Merritt (j.merritt@pgrad.unimelb.edu.au), PhD Student (Equine Biomechanics), The University of Melbourne Equine Centre

posted by maetel
2010. 5. 18. 00:26 Computer Vision
ref.
2010/02/10 - [Visual Information Processing Lab] - R. Y. Tsai "A Versatile Camera Calibration Technique for High Accuracy 3-D Maching Vision Metrology Using Off-the-shelf TV Cameras and Lenses"


(1) 고정되어 있는 것으로 가정한 카메라의 내부 파라미터 값들을 구하고 (2) 실시간으로 들어오는 이미지 프레임마다 카메라의 회전과 이동을 계산하기 위하여 Tsai 알고리즘을 쓰기로 하고, C 또는 C++로 구현된 소스코드 또는 라이브러리를 찾아서 붙여 보기로 한다.


Try #1.
처음에는 CMU의 Reg Willson가 C로 짠 Tsai Camera Calibration 코드 에서 필요한 부분을 include하여 쓰려고 했는데, C++ 문법에 맞지 않는 구식 C 문법으로 코딩된 부분이 많아서 고치는 데 애를 먹었다. (Xcode의 C++ 프로젝트에서 .c 파일을 include하면 compile은 되지만, linking error가 난다. 때문에 .c를 .cpp로 바꾸어야 함.)  그런데 결정적으로, "cal_main.cpp" 파일에 정의된, 캘리브레이션의 최종 결과값을 주는 함수들이 호출하는 optimization을 실행하는 함수 lmdif_()가  Fortan 파일 "lmdif.f"에 정의되어 있고, Fortran을 C로 변환해 주는 "f2c.h"에 의해 이것을 "lmdif.c"로 하여 가지고 있다는 문제가 있었다. lmdif.c를 lmdif.cpp 형태로 만들기 위해서는 Fortran 언어와 Fortran을 C++로 변환하는 방법을 알아야 하므로, 결국 포기했다.



Try #2.
Michigan State University Charles B. Owen Display-Relative Calibration (DRC)을 구현한 DRC 프로그램( DRC.zip )에서 카메라 캘리브레이션에 Tsai의 알고리즘 libtsai.zip을 쓰고 있다. 이 라이브러리는 위의 C 코드를 C++로 수정하면서 "CTsai"라는 클래스를 사용하고 여러 함수들을 수정/보완/결합한 것인데, Visual Studio 용 프로젝트 프로그램을 만들면서 Windows 환경에 기반하여 MFC를 활용하였다. 그래서 이것을 나의 Mac OS X 기반 Xcode 프로젝트에서 그대로 가져다 쓸 수는 없다. 용법은 다음과 같다.

DRC/DisplayRelativeCalibration.cpp:
bool CDisplayRelativeCalibration::ComputeCameraCalibration(void)
{
    CTsai tsai;

    tsai.Width(m_camerawid);
    tsai.Height(m_camerahit);

    for(std::list<Corr>::const_iterator i=m_cameracorr.begin();  i!=m_cameracorr.end();  i++)
    {
        tsai.Point(i->x, i->y, i->z, i->u, i->v);
    }

    if(tsai.PointCount() < 8)
        return Error("Didn't get enough points");

    if(!tsai.Compute())
        return Error("Camera calibration failed");

    for(int n=0;  n<tsai.PointCount();  n++)
    {
        double ux, uy;
        tsai.WorldToImage (tsai.PointX(n), tsai.PointY(n), tsai.PointZ(n), ux, uy);

        m_cameraproj.push_back(CGrPoint(ux, uy, 0));
    }

   
    m_cameraf = tsai.F();
    m_cameracx = tsai.Cx();
    m_cameracy = tsai.Cy();
    m_camerakappa1 = tsai.Kappa1();
    m_camerasx = tsai.Sx();
    memcpy(m_cameramatrix, tsai.CameraMatrix(), sizeof(double) * 16);

    return true;
}




문제점#1.

class CTsai 안의 member functions 중에  ncc_compute_exact_f_and_Tz( )와 ncc_compute_exact_f_and_Tz_error( )가 있는데,

libtsai.h:21
class CTsai
{

    bool ncc_compute_exact_f_and_Tz();
    bool ncc_compute_exact_f_and_Tz_error (int m_ptr, int n_ptr, const double *params, double *err);

};

전자인 ncc_compute_exact_f_and_Tz()가 정의된 부분을 보면, 

Tsai_ncc.cpp:274
bool CTsai::ncc_compute_exact_f_and_Tz()
{
    CLmdif<CTsai> lmdif;

    lmdif.Lmdif (this, ncc_compute_exact_f_and_Tz_error,
            m_point_count, NPARAMS, x,
            NULL, NULL, NULL, NULL);
}

클래스 형태의 템플릿( CLmdif )으로 선언된 "lmdif"의 member function "Lmdif"를 호출할 때, 

min/Lmdif.h:48
template<class T> class CLmdif : private CLmdif_
{

int Lmdif(T *p_user, bool (T::*p_func)(int m, int n, const double *parms, double *err),
        int m, int n, double *x, double *fvec, double *diag, int *ipvt, double *qtf)

};

후자인 같은 member function, ncc_compute_exact_f_and_Tz_error()를 인자로 넣고 있고 (위 부분 코드들 중 오렌지 색 부분), 컴파일 하면 이 부분을 <unknown type>으로 인식하지 못 하겠다는 에러 메시지를 보낸다. 그리고 다음과 같은 형태를 추천한다고 한다.
 
note: candidates are: int CLmdif<T>::Lmdif(T*, bool (T::*)(int, int, const double*, double*), int, int, double*, double*, double*, int*, double*) [with T = CTsai]

function pointer의 형태가 틀린 모양인데, 오렌지색 부분을 그냥 함수가 아닌 어떤 class의 non-static member function을 가리키는 pointer로  &CTsai::ncc_compute_exact_f_and_Tz_error 이렇게 바꾸어 주면, 에러 메시지가 다음과 같이 바뀐다.

error: no matching function for call to 'CLmdif<CTsai>::Lmdif(CTsai* const, bool (*)(int, int, const double*, double*), int&, const int&, double [3], NULL, NULL, NULL, NULL)'

연두색 부분 대신 CTsai::ncc_compute_exact_f_and_Tz_error 이렇게 바꾸어 주면, 에러 메시지가 다음과 같다.

error: no matching function for call to 'CLmdif<CTsai>::Lmdif(CTsai* const, bool (&)(int, int, const double*, double*), int&, const int&, double [3], NULL, NULL, NULL, NULL)'

해결:
편법으로, class CLmdif를 클래스 형 템플릿이 아닌 그냥 클래스로 바꾸어서 선언하고 연두색 부분처럼 호출하면 에러는 안 나기에 일단 이렇게 넘어가기로 한다.


문제점#2.
코드에서 Windows OS 기반 MFC를 사용하고 있어 Mac OS X에서 에러가 난다.

해결:
MFC를 사용하는 "StdAfx.h"는 모두 주석 처리한다.


문제점#3.
Lmdif.h



... 기타 등등의 문제점들을 해결하고, 캘리브레이션을 수행한 결과가 맞는지 확인하자.

source code:
           if ( CRimage.size() > 0 ) // if there is a valid point with its cross ratio
            {  
                correspondPoints(indexI, indexW, p, CRimage, linesYorder.size(), linesXorder.size(), world, CRworld, dxList.size(), dyList.size(), iplMatch, scale );
            }  
            cvShowImage( "match", iplMatch );
            cvSaveImage( "match.bmp", iplMatch );
           
            cout << "# of pairs = " << indexI.size() << " = " << indexW.size() << endl;
           
            // # 6. camera calibration
           
            int numPair = indexI.size();
           
            tsai.Clear();
           
            for( int n = 0;  n < numPair;  n++ )
            {
                tsai.Point(world[indexW[n]].x, world[indexW[n]].y, world[indexW[n]].z, p[indexI[n]].x, p[indexI[n]].y);
               
                cout << "pair #" << n << ": " << p[indexI[n]].x << "  " <<  p[indexI[n]].y << "  : "
                    << world[indexW[n]].x << "  " << world[indexW[n]].y << "  " << world[indexW[n]].z << endl;
            }
           
            if( numPair < 8 )
                cout << "Didn't get enough points" << endl;
           
            if(!tsai.Compute())
                cout << "Camera calibration failed" << endl;
           
            cout << endl << "camera parameter" << endl
            << "focus = " << tsai.F() << endl
            << "principal axis (x,y) = " <<  tsai.Cx() << ", " <<  tsai.Cy() << endl
            << "kappa1 (lens distortion) = " <<  tsai.Kappa1() << endl
            << "skew_x = " << tsai.Sx() << endl;
          
            // reproject world points on to the image frame to check the result of computing camera parameters
            for(int n=0;  n<tsai.PointCount();  n++)
            {
                double ux, uy;
                tsai.WorldToImage (tsai.PointX(n), tsai.PointY(n), tsai.PointZ(n), ux, uy);
                CvPoint reproj = cvPoint( cvRound(ux), cvRound(uy) );
                cvCircle( iplInput, reproj, 3, CV_RGB(200,100,200), 2 );
            }
           
// draw a cube on the image coordinate computed by camera parameters according to the world coordinate
            drawcube( tsai, iplInput, patSize );
            cvShowImage( "input", iplInput );  



아래 사진은 구해진 카메라 내부/외부 파라미터들을 가지고 (1) 실제 패턴의 점에 대응하는 이미지 프레임 (image coordinate) 상의 점을 찾아 (reprojection) 보라색 원으로 그리고, (2) 실제 패턴이 있는 좌표 (world coordinate)를 기준으로 한 graphic coordinate에 직육면체 cube를 노란색 선으로 그린 결과이다.

이미지 프레임과 실제 패턴 상의 점을 1 대 1로 비교하여 연결한 16쌍의 대응점

구한 카메라 파라미터를 가지고 실제 패턴 위의 점들을 이미지 프레임에 reproject한 결과 (보라색 점)와 실제 패턴의 좌표를 기준으로 한 그래픽이 이미지 프레임 상에 어떻게 나타나는지 그린 결과 (노란색 상자)

 

위 왼쪽 사진에서 보여지는 16쌍의 대응점들의 좌표값을 "이미지 좌표(x,y) : 패턴 좌표 (x,y,z)"로 출력한 결과:
# of pairs = 16 = 16
pair #0: 7.81919  36.7864  : 119.45  82.8966  0
pair #1: 15.1452  71.2526  : 119.45  108.484  0
pair #2: 26.1296  122.93  : 119.45  147.129  0
pair #3: 36.6362  172.36  : 119.45  182.066  0
pair #4: 77.3832  20.4703  : 159.45  82.8966  0
pair #5: 85.4293  53.7288  : 159.45  108.484  0
pair #6: 97.8451  105.05  : 159.45  147.129  0
pair #7: 109.473  153.115  : 159.45  182.066  0
pair #8: 96.6046  15.962  : 171.309  82.8966  0
pair #9: 105.046  48.8378  : 171.309  108.484  0
pair #10: 118.177  99.9803  : 171.309  147.129  0
pair #11: 130.4  147.586  : 171.309  182.066  0
pair #12: 145.469  4.50092  : 199.965  82.8966  0
pair #13: 154.186  36.5857  : 199.965  108.484  0
pair #14: 168.033  87.5497  : 199.965  147.129  0
pair #15: 180.732  134.288  : 199.965  182.066  0


그런데 위 오른쪽 사진에서 보여지는 결과는 이전 프레임에서 20쌍의 대응점으로부터 구한 카메라 파라미터 값을 가지고 계산한 결과이다.
# of found lines = 8 vertical, 7 horizontal
vertical lines:
horizontal lines:
p.size = 56
CRimage.size = 56

# of pairs = 20 = 20
pair #0: -42.2331  53.2782  : 102.07  108.484  0
pair #1: -22.6307  104.882  : 102.07  147.129  0
pair #2: -4.14939  153.534  : 102.07  182.066  0
pair #3: 1.81771  169.243  : 102.07  193.937  0
pair #4: -10.9062  41.1273  : 119.45  108.484  0
pair #5: 8.69616  92.7309  : 119.45  147.129  0
pair #6: 27.0108  140.945  : 119.45  182.066  0
pair #7: 32.9779  156.653  : 119.45  193.937  0
pair #8: 57.4164  14.6267  : 159.45  108.484  0
pair #9: 77.7374  65.9516  : 159.45  147.129  0
pair #10: 96.3391  112.934  : 159.45  182.066  0
pair #11: 102.524  128.555  : 159.45  193.937  0
pair #12: 76.5236  7.21549  : 171.309  108.484  0
pair #13: 97.5633  58.2616  : 171.309  147.129  0
pair #14: 116.706  104.705  : 171.309  182.066  0
pair #15: 123.108  120.238  : 171.309  193.937  0
pair #16: 125.015  -11.5931  : 199.965  108.484  0
pair #17: 146.055  39.453  : 199.965  147.129  0
pair #18: 164.921  85.2254  : 199.965  182.066  0
pair #19: 171.323  100.758  : 199.965  193.937  0

camera parameter
focus = 3724.66
principal axis (x,y) = 168.216, 66.5731
kappa1 (lens distortion) = -6.19473e-07
skew_x = 1



대응점 연결에 오차가 없으면, 즉, 패턴 인식이 잘 되면, Tsai 알고리즘에 의한 카메라 파라미터 구하기가 제대로 되고 있음을 확인할 수 있다. 하지만, 현재 full optimization (모든 파라미터들에 대해 최적화 과정을 수행하는 것)으로 동작하게 되어 있고, 프레임마다 모든 파라미터들을 새로 구하고 있기 때문에, 속도가 매우 느리다. 시험 삼아 reprojection과 간단한 graphic을 그리는 과정은 속도에 큰 영향이 없지만, 그전에 카메라 캘리브레이션을 하는 데 필요한 계산 시간이 길다. 입력 프레임이 들어오는 시간보다 훨씬 많은 시간이 걸려 실시간 구현이 되지 못 하고 있다.

따라서, (1) 내부 파라미터는 첫 프레임에서 한 번만 계산하고 (2) 이후 매 프레임마다 외부 파라미터 (카메라의 회전과 이동)만을 따로 계산하는 것으로 코드를 수정해야 한다.




Try#3.
OpenCV 함수 이용

1) 내부 파라미터 계산
cvCalib
rateCamera2


2) lens distortion(kappa1, kappa2)을 가지고 rectification
cvInitUndistortRectifyMap

3) line detection

4) 패턴 인식 (대응점 찾기)

5) 외부 파라미터 계산 (4의 결과 & lens distortion = 0 입력)
cvFindExtrinsicCameraParams2

6) reprojection
2)에서 얻은 rectificated image에 할 것


posted by maetel
2010. 5. 14. 21:50 Computer Vision
Test on the correspondences of feature points
특징점 대응 시험

교점의 cross ratio 값을 구하고, 그 값과 가장 가까운 cross ratio 값을 가지는 점을 패턴에서 찾아 대응시킨다.


Try #1. one-to-all

입력 영상에서 검출한 직선들로부터 생기는 각 교점에서 수평 방향으로 다음 세 개의 교점, 수직 방향으로 다음 세 개의 교점을 지나는 직선에 대한 cross ratio (x,y)값을 구한다. 이상적으로, 1에서 구한 cross ratio 값과 일치하는 cross ratio 값을 가지는 패턴의 격자점이 입력 영상의 해당 교차점과 실제로 대응하는 점이라고 볼 수 있다.

직선 검출에 오차나 오류가 적을 경우, 아래 테스트 결과에서 보듯 입력 영상의 교차점에 대해 실제 패턴의 직선을 1대 1로 즉각적으로 찾는다. 즉, 입력 영상의 한 점에서의 수평 방향 cross ratio 값에 대해 패턴의 모든 수평선들의 cross ratio 값을 일일이 대조하여 가장 근접한 값을 가지는 직선을 대응시키는 방식이다. (아래 오른쪽 사진은 같은 방식으로 수직 방향 cross ratio 값을 가지고 대응되는 직선을 찾는 경우임.) (point-to-line)

수평선 위의 점들에 대한 cross ratio 값만 비교한 결과

수선 위의 점들에 대한 cross ratio 값만 비교한 결과



입력 영상에서 하나의 교차점의 x방향 cross ratio 값과 같은 cross ratio 값을 가지는 세로선을 실제 패턴에서 찾고, y방향 cross ratio 값에 대해서 가로선을 찾으면, 패턴 위에 그 세롯선과 가로선이 교차하는 점 하나가 나온다. 입력 이미지 상의 한 점에 대해 패턴의 모든 직선을 (가로선의 개수+세로선의 개수) 번 비교하여 대응점을 연결하는 것이다. (point-to-point)

(패턴 인식이 성공적인 경우)

(잘못된 대응점 연결이 발생한 경우)




그러므로 현재는 (1) 입력 영상에서 한 직선 위에 있는 것으로 추산된 일련의 점들에서의 cross ratio 값들의 수치적 경향을 고려하지 않고 있으며, (2) 입력 영상에 실제 패턴의 어느 부분(위치나 범위)이 잡힌 것인지를 판단하지 않고 무조건 전체 패턴의 모든 격자점들에 대해서 cross ratio 값을 비교하고 있다.      




Try #2. line-to-line




잘 되는 경우:
# of pairs = 25 = 25
# of imagePoints = 25 , 25
# of worldPoints = 25 , 25
imagePoint (0, 0) : worldPoint (4, 1)
imagePoint (0, 1) : worldPoint (4, 2)
imagePoint (0, 2) : worldPoint (4, 3)
imagePoint (0, 3) : worldPoint (4, 4)
imagePoint (0, 4) : worldPoint (4, 5)
imagePoint (1, 0) : worldPoint (5, 1)
imagePoint (1, 1) : worldPoint (5, 2)
imagePoint (1, 2) : worldPoint (5, 3)
imagePoint (1, 3) : worldPoint (5, 4)
imagePoint (1, 4) : worldPoint (5, 5)
imagePoint (2, 0) : worldPoint (6, 1)
imagePoint (2, 1) : worldPoint (6, 2)
imagePoint (2, 2) : worldPoint (6, 3)
imagePoint (2, 3) : worldPoint (6, 4)
imagePoint (2, 4) : worldPoint (6, 5)
imagePoint (3, 0) : worldPoint (7, 1)
imagePoint (3, 1) : worldPoint (7, 2)
imagePoint (3, 2) : worldPoint (7, 3)
imagePoint (3, 3) : worldPoint (7, 4)
imagePoint (3, 4) : worldPoint (7, 5)
imagePoint (4, 0) : worldPoint (8, 1)
imagePoint (4, 1) : worldPoint (8, 2)
imagePoint (4, 2) : worldPoint (8, 3)
imagePoint (4, 3) : worldPoint (8, 4)
imagePoint (4, 4) : worldPoint (8, 5)



잘 안 되는 경우:
# of pairs = 28 = 28
# of imagePoints = 28 , 28
# of worldPoints = 28 , 28
imagePoint (0, 0) : worldPoint (4, 6)
imagePoint (0, 1) : worldPoint (4, 7)
imagePoint (0, 2) : worldPoint (4, 1)
imagePoint (0, 3) : worldPoint (4, 2)
imagePoint (0, 4) : worldPoint (4, 3)
imagePoint (0, 5) : worldPoint (4, 4)
imagePoint (0, 6) : worldPoint (4, 5)
imagePoint (1, 0) : worldPoint (9, 6)
imagePoint (1, 1) : worldPoint (1, 7)
imagePoint (1, 2) : worldPoint (5, 1)
imagePoint (1, 3) : worldPoint (5, 2)
imagePoint (1, 4) : worldPoint (5, 3)
imagePoint (1, 5) : worldPoint (5, 4)
imagePoint (1, 6) : worldPoint (5, 5)
imagePoint (2, 0) : worldPoint (9, 6)
imagePoint (2, 1) : worldPoint (3, 7)
imagePoint (2, 2) : worldPoint (6, 1)
imagePoint (2, 3) : worldPoint (6, 2)
imagePoint (2, 4) : worldPoint (6, 3)
imagePoint (2, 5) : worldPoint (6, 4)
imagePoint (2, 6) : worldPoint (6, 5)
imagePoint (3, 0) : worldPoint (9, 6)
imagePoint (3, 1) : worldPoint (0, 7)
imagePoint (3, 2) : worldPoint (7, 1)
imagePoint (3, 3) : worldPoint (7, 2)
imagePoint (3, 4) : worldPoint (7, 3)
imagePoint (3, 5) : worldPoint (7, 4)
imagePoint (3, 6) : worldPoint (7, 5)

posted by maetel
2010. 4. 7. 00:16 Computer Vision
OpenCV 라이브러리의 Hough transform에 의한 직선 찾기 함수


CvSeq* cvHoughLines2(CvArr* image, void* storage, int method, double rho, double theta, int threshold, double param1=0, double param2=0)

Finds lines in a binary image using a Hough transform.

Parameters:
  • image – The 8-bit, single-channel, binary source image. In the case of a probabilistic method, the image is modified by the function
  • storage – The storage for the lines that are detected. It can be a memory storage (in this case a sequence of lines is created in the storage and returned by the function) or single row/single column matrix (CvMat*) of a particular type (see below) to which the lines’ parameters are written. The matrix header is modified by the function so its cols or rows will contain the number of lines detected. If storage is a matrix and the actual number of lines exceeds the matrix size, the maximum possible number of lines is returned (in the case of standard hough transform the lines are sorted by the accumulator value)
  • method

    The Hough transform variant, one of the following:

    • CV_HOUGH_STANDARD - classical or standard Hough transform. Every line is represented by two floating-point numbers $(\rho , \theta )$, where $\rho $ is a distance between (0,0) point and the line, and $\theta $ is the angle between x-axis and the normal to the line. Thus, the matrix must be (the created sequence will be) of CV_32FC2 type
    • CV_HOUGH_PROBABILISTIC - probabilistic Hough transform (more efficient in case if picture contains a few long linear segments). It returns line segments rather than the whole line. Each segment is represented by starting and ending points, and the matrix must be (the created sequence will be) of CV_32SC4 type
    • CV_HOUGH_MULTI_SCALE - multi-scale variant of the classical Hough transform. The lines are encoded the same way as CV_HOUGH_STANDARD
  • rho – Distance resolution in pixel-related units
  • theta – Angle resolution measured in radians
  • threshold – Threshold parameter. A line is returned by the function if the corresponding accumulator value is greater than threshold
  • param1

    The first method-dependent parameter:

    • For the classical Hough transform it is not used (0).
    • For the probabilistic Hough transform it is the minimum line length.
    • For the multi-scale Hough transform it is the divisor for the distance resolution $\rho $. (The coarse distance resolution will be $\rho $ and the accurate resolution will be $(\rho / \texttt{param1})$).
  • param2

    The second method-dependent parameter:

    • For the classical Hough transform it is not used (0).
    • For the probabilistic Hough transform it is the maximum gap between line segments lying on the same line to treat them as a single line segment (i.e. to join them).
    • For the multi-scale Hough transform it is the divisor for the angle resolution $\theta $. (The coarse angle resolution will be $\theta $ and the accurate resolution will be $(\theta / \texttt{param2})$).

Memory storage is a low-level structure used to store dynamicly growing data structures such as sequences, contours, graphs, subdivisions, etc.


입력 이미지가 8비트 단일 채널이어야 하므로,
다음과 같이 "IPL_DEPTH_32F"로 생성했던 입력 이미지 (iplDoGx)를 바꾸어 "8" 비트 depth짜리 새로운 이미지 (iplEdgeY)에 저장한다.

            cvConvert(iplDoGx, iplEdgeY);


두번째 인자 " void* storage" 는 탐지된 직선을 저장할 메모리. 이 함수의 아웃풋에 해당한다.

CvMemStorage

Growing memory storage.

typedef struct CvMemStorage
{
struct CvMemBlock* bottom;/* first allocated block */
struct CvMemBlock* top; /* the current memory block - top of the stack */
struct CvMemStorage* parent; /* borrows new blocks from */
int block\_size; /* block size */
int free\_space; /* free space in the \texttt{top} block (in bytes) */
} CvMemStorage;



CvMemStorage* cvCreateMemStorage(int blockSize=0)

Creates memory storage.

Parameter:blockSize – Size of the storage blocks in bytes. If it is 0, the block size is set to a default value - currently it is about 64K.


 그 아웃풋을 다음의 CvSeq 형태의 자료 구조체 안에 저장한다.

CvSeq

Growable sequence of elements.

#define CV_SEQUENCE\_FIELDS() \
int flags; /* micsellaneous flags */ \
int header_size; /* size of sequence header */ \
struct CvSeq* h_prev; /* previous sequence */ \
struct CvSeq* h_next; /* next sequence */ \
struct CvSeq* v_prev; /* 2nd previous sequence */ \
struct CvSeq* v_next; /* 2nd next sequence */ \
int total; /* total number of elements */ \
int elem_size;/* size of sequence element in bytes */ \
char* block_max;/* maximal bound of the last block */ \
char* ptr; /* current write pointer */ \
int delta_elems; /* how many elements allocated when the sequence grows
(sequence granularity) */ \
CvMemStorage* storage; /* where the seq is stored */ \
CvSeqBlock* free_blocks; /* free blocks list */ \
CvSeqBlock* first; /* pointer to the first sequence block */

typedef struct CvSeq
{
CV_SEQUENCE_FIELDS()
} CvSeq;

The structure CvSeq is a base for all of OpenCV dynamic data structures.


그 저장된 값을 읽는 함수

char* cvGetSeqElem(const CvSeq* seq, int index)

Returns a pointer to a sequence element according to its index.

#define CV_GET_SEQ_ELEM( TYPE, seq, index )  (TYPE*)cvGetSeqElem( (CvSeq*)(seq), (index) )
Parameters:
  • seq – Sequence
  • index – Index of element




accumulator value 란?







"detected edges" 이미지에 대해 Hough transform에 의한 line fitting 한 결과를 "input" 이미지에 그리고 있음




opencv/opencv/src/cv/cvhough.cpp 를 열면, 다음의 네 부분으로 나뉘어 정의되어 있다.
Classical Hough Transform
Multi-Scale variant of Classical Hough Transform 
Probabilistic Hough Transform      
Circle Detection

이 중 "Classical Hough Transform" 부분은 다음과 같음.
typedef struct CvLinePolar
{
    float rho;
    float angle;
}
CvLinePolar;
/*=====================================================================================*/

#define hough_cmp_gt(l1,l2) (aux[l1] > aux[l2])

static CV_IMPLEMENT_QSORT_EX( icvHoughSortDescent32s, int, hough_cmp_gt, const int* )

/*
Here image is an input raster;
step is it's step; size characterizes it's ROI;
rho and theta are discretization steps (in pixels and radians correspondingly).
threshold is the minimum number of pixels in the feature for it
to be a candidate for line. lines is the output
array of (rho, theta) pairs. linesMax is the buffer size (number of pairs).
Functions return the actual number of found lines.
*/
static void
icvHoughLinesStandard( const CvMat* img, float rho, float theta,
                       int threshold, CvSeq *lines, int linesMax )
{
    int *accum = 0;
    int *sort_buf=0;
    float *tabSin = 0;
    float *tabCos = 0;

    CV_FUNCNAME( "icvHoughLinesStandard" );

    __BEGIN__;

    const uchar* image;
    int step, width, height;
    int numangle, numrho;
    int total = 0;
    float ang;
    int r, n;
    int i, j;
    float irho = 1 / rho;
    double scale;

    CV_ASSERT( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 );

    image = img->data.ptr;
    step = img->step;
    width = img->cols;
    height = img->rows;

    numangle = cvRound(CV_PI / theta);
    numrho = cvRound(((width + height) * 2 + 1) / rho);

    CV_CALL( accum = (int*)cvAlloc( sizeof(accum[0]) * (numangle+2) * (numrho+2) ));
    CV_CALL( sort_buf = (int*)cvAlloc( sizeof(accum[0]) * numangle * numrho ));
    CV_CALL( tabSin = (float*)cvAlloc( sizeof(tabSin[0]) * numangle ));
    CV_CALL( tabCos = (float*)cvAlloc( sizeof(tabCos[0]) * numangle ));
    memset( accum, 0, sizeof(accum[0]) * (numangle+2) * (numrho+2) );

    for( ang = 0, n = 0; n < numangle; ang += theta, n++ )
    {
        tabSin[n] = (float)(sin(ang) * irho);
        tabCos[n] = (float)(cos(ang) * irho);
    }

    // stage 1. fill accumulator
    for( i = 0; i < height; i++ )
        for( j = 0; j < width; j++ )
        {
            if( image[i * step + j] != 0 )
                for( n = 0; n < numangle; n++ )
                {
                    r = cvRound( j * tabCos[n] + i * tabSin[n] );
                    r += (numrho - 1) / 2;
                    accum[(n+1) * (numrho+2) + r+1]++;
                }
        }

    // stage 2. find local maximums
    for( r = 0; r < numrho; r++ )
        for( n = 0; n < numangle; n++ )
        {
            int base = (n+1) * (numrho+2) + r+1;
            if( accum[base] > threshold &&
                accum[base] > accum[base - 1] && accum[base] >= accum[base + 1] &&
                accum[base] > accum[base - numrho - 2] && accum[base] >= accum[base + numrho + 2] )
                sort_buf[total++] = base;
        }

    // stage 3. sort the detected lines by accumulator value
    icvHoughSortDescent32s( sort_buf, total, accum );

    // stage 4. store the first min(total,linesMax) lines to the output buffer
    linesMax = MIN(linesMax, total);
    scale = 1./(numrho+2);
    for( i = 0; i < linesMax; i++ )
    {
        CvLinePolar line;
        int idx = sort_buf[i];
        int n = cvFloor(idx*scale) - 1;
        int r = idx - (n+1)*(numrho+2) - 1;
        line.rho = (r - (numrho - 1)*0.5f) * rho;
        line.angle = n * theta;
        cvSeqPush( lines, &line );
    }

    __END__;

    cvFree( &sort_buf );
    cvFree( &tabSin );
    cvFree( &tabCos );
    cvFree( &accum );
}






'Computer Vision' 카테고리의 다른 글

OpenCV 2.1 설치 on Mac OS X  (0) 2010.04.14
Hough transform  (0) 2010.04.12
OpenCV: cvFitLine() 연습 코드  (0) 2010.04.06
virtual studio 구현: line fitting test  (0) 2010.04.06
virtual studio 구현: gradient filtering  (0) 2010.04.04
posted by maetel
2010. 4. 6. 23:26 Computer Vision
overview:
렌즈의 왜곡 현상 때문에 이미지 상에 검출된 edge points들은 (직선에서 왜곡된) 2차 곡선을 그리게 된다. 이 곡선의 방정식을 먼저 구한 후에, 렌즈 왜곡 변수를 "0"으로 두고 나오는 직선들로부터 비로소 cross-ratio 값이 보존된다.

ref.  2010/02/10 - [Visual Information Processing Lab] - Seong-Woo Park & Yongduek Seo & Ki-Sang Hong

swPark_2000rti 440쪽: "The cross-ratio is not preserved for the (image) frame coordinate, positions of the feature points in an image, or for the distorted image coordinate. Cross-ratio is invariant only for the undistorted coordinate." (swPark_20

박승우_1999전자공학회지 96쪽: "이렇게 곡선으로 나타난 가로선과 세로선을 직선으로 피팅할 경우 cross-ratio는 왜곡 현상 때문에 이 선들에 대해서는 보존되지 않게 된다. 따라서 정확한 피팅을 위해서는 아래와 같이 렌즈의 왜곡변수(k1)를 고려한 이차곡선으로의 피팅이 필요하다.

Y = a*X + b/(1+k1*R^2) = a*X + b/(1+k1*(X^2+Y^2)) <--- 이 식은 영어 논문 (19)식과 한글 논문 (15)식을 조합, 수정한 식임. 확인 필요

이 식을 피팅해서 계수 a, b, k1를 구하고, 여기서 k1=0을 두면 왜곡이 보상된 점에 대한 직선식을 구할 수 있다. 이렇게 구해진 직선들을 패턴의 가로선들과 세로선들의 cross-ratio와 비교함으로써 영상에서 찾아진 선들을 인식할 수 있다. 또한 영상에서의 특징점은 이 식에 의해 피팅된 가로선들과 세로선들의 교점으로 정확하게 구할 수 있다."


그런데, 
현재 시험용 패턴과 코드로부터 촬영, 검출된 이미지 상의 점들은 거의 직선에 가깝다. 우선 OpenCV 라이브러리의 cvHoughLines2() 함수에 의한 직선 찾기를 해 보자.

2010/04/07 - [Visual Information Processing Lab] - OpenCV: cvHoughLines2() 연습 코드


1) 교점 구하기 테스트
line fitting을 통해 찾은 직선들로부터 패턴 격자의 corner points를 구하는 것을 시험해 본다.




실시간으로 산출하는 데 무리가 없음이 확인되었다.

2)
그러나, line fitting의 결과가 깔끔하지 않은 문제를 우선 해결해야 한다. (rho, theta, threshold 등의 함수 매개변수 값을 조정하는 것을 포함하여 사용 중인 웹캠에 적합한 데이터 처리가 필요하다.)

현재의 코드로부터 나오는 결과를 정리해 두면 아래와 같다.

NMS와 동시에 수평선 또는 수직선 위의 점들을 따로 추출한 결과 이미지 ("iplEdgeX"와  "iplEdgeY")를 cvHoughLines2() 함수의 입력으로 하고,
double rho = 1.0; // distance resolution in pixel-related units
double theta = 1.0; // angle resolution measured in radians
int threshold = 20; // (A line is returned by the function if the corresponding accumulator value is greater than threshold)
위와 같이 매개변수 값을 주면 검출된 직선들과 그로부터 계산한 교점들은 다음과 같이 나타난다.

수직선 상의 edges만 검출한 영상

수평선 상의 edges만 검출한 영상

Hough transform에 의한 line fitting 한 결과



(Non Maximal suppression (NMS)을 하기 전에) 1차 DoG 필터를 이미지 프레임의 x 방향, y 방향으로 적용한 결과 이미지 ("iplDoGx"와 "iplDoGy")를 cvHoughLines2() 함수의 입력으로 하고,
double rho = 1.0; // distance resolution in pixel-related units
double theta = 1.0; // angle resolution measured in radians
int threshold = 20; // (A line is returned by the function if the corresponding accumulator value is greater than threshold)
위와 같이 매개변수 값들을 주면 검출된 직선들과 그로부터 계산한 교점들은 다음과 같이 나타난다.

x방향으로 DoG 필터를 적용한 이미지

y방향으로 DoG 필터를 적용한 이미지

Hough transform에 의한 line fitting한 결과




그러니까... 실제로 한 직선 상의 점들로부터 여러 개의 직선을 찾게 되는 것은 edge points로 detection된 (흰색으로 보이는) 픽셀 부분의 세기값이 약하거나 일정하지 않기 때문인 것 같다. 입력 이미지를 binary로 바꾸고 cvHoughLines2()의 입력으로 accumulator value에 기준값을 주는 파라미터 threshold를 증가시키면 될 것 같다.



Try #1. 입력 이미지 이진화

NMS와 동시에 수평선 또는 수직선 위의 점들을 따로 추출한 결과 이미지 ("iplEdgeX"와  "iplEdgeY")를 이진화하고, 
double rho = 1.0; // distance resolution in pixel-related units
double theta = 1.0; // angle resolution measured in radians
int threshold = 40; // ("A line is returned by the function if the corresponding accumulator value is greater than threshold.")
위와 같이 매개변수 값들을 주면 검출된 직선들과 그로부터 계산한 교점들은 다음과 같이 나타난다.

수직선 상의 edges만 검출하여 이진화한 영상

수평선 상의 edges만 검출하여 이진화한 영상

Hough transform에 의한 line fitting한 결과


실제로 한 직선에 여러 개의 직선이 검출되는 빈도는 현저히 줄지만 대신 실제 직선 중에 검출되지 않는 것이 생긴다.


Try #2. line fitting의 입력 이미지 처리 & 매개변수 조정



Try #3. 실제로 하나인데 여러 개로 겹쳐서 나오는 직선들의 평균을 취해 하나로 합침

다음과 같은 입력 영상에 대해 탐지된 직선들의 방정식을 정의하는 매개변수 (rho와 theta) 값을 출력해 보면 아래와 같이 나온다.

# of found lines = 8 vertical   22 horizontal
vertical
rho = 172.6    theta = 0
rho = 133    theta = 0.139626
rho = -240.2    theta = 2.84489
rho = -209    theta = 2.98451
rho = 91.8    theta = 0.279253
rho = 173.8    theta = 0
rho = 52.6    theta = 0.401426
rho = 53.8    theta = 0.418879
horizontal
rho = 81    theta = 1.55334
rho = 53.4    theta = 1.55334
rho = 155    theta = 1.55334
rho = 114.6    theta = 1.55334
rho = 50.6    theta = 1.5708
rho = 29.8    theta = 1.55334
rho = 76.6    theta = 1.5708
rho = 112.6    theta = 1.5708
rho = 9.8    theta = 1.55334
rho = 152.6    theta = 1.5708
rho = 153.8    theta = 1.5708
rho = 150.6    theta = 1.5708
rho = 6.6    theta = 1.5708
rho = 78.6    theta = 1.5708
rho = 205.4    theta = 1.55334
rho = 27.8    theta = 1.5708
rho = 8.6    theta = 1.5708
rho = 201.8    theta = 1.5708
rho = 110.6    theta = 1.5708
rho = 49.8    theta = 1.5708
rho = 48.6    theta = 1.5708
rho = 111.8    theta = 1.5708





잠시 현재 상태 기록: cross ratios를 이용한 격자 무늬 패턴과 line detection 시험 + feature points matching을 위한 교점 찾기와 순번 부여 시험


to do next:
1) line detection의 error 교정
2) (rhoX, thetaX, rhoY, thetaY로 정의되는) 교점 indexing



'Computer Vision' 카테고리의 다른 글

OpenCV: cvHoughLines2() 연습 코드  (0) 2010.04.07
OpenCV: cvFitLine() 연습 코드  (0) 2010.04.06
virtual studio 구현: gradient filtering  (0) 2010.04.04
OpenCV: cvFilter2D() 연습 코드  (0) 2010.04.04
Image Filtering  (0) 2010.04.03
posted by maetel
2010. 3. 31. 20:44 Computer Vision
C. Harris and M.J. Stephens. A combined corner and edge detector. In Alvey Vision Conference, pages 147–152, 1988.



OpenCV: cvCornerHarris()

'Computer Vision' 카테고리의 다른 글

OpenCV: CV_IMAGE_ELEM  (0) 2010.04.02
OpenCV: cvFindContours  (0) 2010.04.02
OpenCV: cvCanny() 연습 코드  (0) 2010.03.31
Canny edge detection  (0) 2010.03.30
ARToolKit - simpleTest  (0) 2010.03.17
posted by maetel
2010. 3. 31. 16:58 Computer Vision
OpenCV 라이브러리의 Canny edge detection 함수

void cvCanny(const CvArr* image, CvArr* edges, double threshold1, double threshold2, int aperture_size=3)

Implements the Canny algorithm for edge detection.

Parameters:
  • image – Single-channel input image
  • edges – Single-channel image to store the edges found by the function
  • threshold1 – The first threshold
  • threshold2 – The second threshold
  • aperture_size – Aperture parameter for the Sobel operator (see Sobel)


cvCanny() 함수의 입출력 이미지는 단일 채널 (single channel)이어야 하므로,
비디오 입력에서 컬러 영상을 받은 경우 흑백 이미지(gray image)로 전환해 주어야 한다.

void cvCvtColor(const CvArr* src, CvArr* dst, int code)

Converts an image from one color space to another.

Parameters:
  • src – The source 8-bit (8u), 16-bit (16u) or single-precision floating-point (32f) image
  • dst – The destination image of the same data type as the source. The number of channels may be different
  • code – Color conversion operation that can be specifed using CV_ *src_color_space* 2 *dst_color_space* constants (see below)





입력 영상

흑백 영상

edge 검출 영상 (Canny 알고리즘)




cf.
2010/03/30 - [Visual Information Processing Lab] - Canny edge detection
cv. Image Processing and Computer Vision

'Computer Vision' 카테고리의 다른 글

OpenCV: cvFindContours  (0) 2010.04.02
Harris corner detector  (0) 2010.03.31
Canny edge detection  (0) 2010.03.30
ARToolKit - simpleTest  (0) 2010.03.17
Three-dimensional computer vision: a geometric viewpoint By Olivier Faugeras  (0) 2010.03.15
posted by maetel
2010. 3. 30. 21:05 Computer Vision
Canny algorithm for edge detection


Canny, J. 1986. A Computational Approach to Edge Detection. IEEE Transactions on Pattern Analysis and Machine Intelligence. 8(6).



The Hypermedia Image Processing Reference - Feature Detectors - Canny Edge Detector

OpenCV: cvCanny()

posted by maetel
2010. 3. 15. 15:56 Computer Vision
Three-dimensional computer vision: a geometric viewpoint 
By Olivier Faugeras

googleBooks
mitpress

'Computer Vision' 카테고리의 다른 글

Canny edge detection  (0) 2010.03.30
ARToolKit - simpleTest  (0) 2010.03.17
opencv: video capturing from a camera  (4) 2010.03.13
Leordeanu & Hebert, "Unsupervised learning for graph matching"  (0) 2010.03.04
ARToolKit test log  (0) 2010.03.03
posted by maetel
2010. 3. 3. 19:54 Computer Vision
http://www.hitl.washington.edu/artoolkit/

ARToolKit Patternmaker
Automatically create large numbers of target patterns for the ARToolKit, by the University of Utah.


ARToolKit-2.72.tgz 다운로드

http://www.openvrml.org/

DSVideoLib
A DirectShow wrapper supporting concurrent access to framebuffers from multiple threads. Useful for developing applications that require live video input from a variety of capture devices (frame grabbers, IEEE-1394 DV camcorders, USB webcams).


openvrml on macports
http://trac.macports.org/browser/trunk/dports/graphics/openvrml/Portfile


galaxy:~ lym$ port search openvrml
openvrml @0.17.12 (graphics, x11)
    a cross-platform VRML and X3D browser and C++ runtime library
galaxy:~ lym$ port info openvrml
openvrml @0.17.12 (graphics, x11)
Variants:    js_mozilla, mozilla_plugin, no_opengl, no_x11, player, universal,
             xembed

OpenVRML is a free cross-platform runtime for VRML and X3D available under the
GNU Lesser General Public License. The OpenVRML distribution includes libraries
you can use to add VRML/X3D support to an application. On platforms where GTK+
is available, OpenVRML also provides a plug-in to render VRML/X3D worlds in Web
browsers.
Homepage:    http://www.openvrml.org/

Build Dependencies:   pkgconfig
Library Dependencies: boost, libpng, jpeg, fontconfig, mesa, libsdl
Platforms:            darwin
Maintainers:          raphael@ira.uka.de openmaintainer@macports.org
galaxy:~ lym$ port deps openvrml
openvrml has build dependencies on:
    pkgconfig
openvrml has library dependencies on:
    boost
    libpng
    jpeg
    fontconfig
    mesa
    libsdl
galaxy:~ lym$ port variants openvrml
openvrml has the variants:
    js_mozilla: Enable support for JavaScript in the Script node with Mozilla
    no_opengl: Do not build the GL renderer
    xembed: Build the XEmbed control
    player: Build the GNOME openvrml-player
    mozilla_plugin: Build the Mozilla plug-in
    no_x11: Disable support for X11
    universal: Build for multiple architectures


openvrml 설치



ARToolKit-2.72.1 설치 후 테스트

graphicsTest on the bin directory
-> This test confirms that your camera support ARToolKit graphics module with OpenGL.

videoTest on the bin directory
-> This test confirms that your camera supports ARToolKit video module and ARToolKit graphics module.

simpleTest on the bin directory
-> You need to notice that better the format is similar to ARToolKit tracking format, faster is the acquisition (RGB more efficient).


"hiro" 패턴을 쓰지 않으면, 아래와 같은 에러가 난다.

/Users/lym/ARToolKit/build/ARToolKit.build/Development/simpleTest.build/Objects-normal/i386/simpleTest ; exit;
galaxy:~ lym$ /Users/lym/ARToolKit/build/ARToolKit.build/Development/simpleTest.build/Objects-normal/i386/simpleTest ; exit;
Using default video config.
Opening sequence grabber 1 of 1.
vid->milliSecPerFrame: 200 forcing timer period to 100ms
Video cType is raw , size is 320x240.
Image size (x,y) = (320,240)
Camera parameter load error !!
logout


Using default video config.
Opening sequence grabber 1 of 1.
vid->milliSecPerFrame: 200 forcing timer period to 100ms
Video cType is raw , size is 320x240.
Image size (x,y) = (320,240)
*** Camera Parameter ***
--------------------------------------
SIZE = 320, 240
Distortion factor = 159.250000 131.750000 104.800000 1.012757
350.47574 0.00000 158.25000 0.00000
0.00000 363.04709 120.75000 0.00000
0.00000 0.00000 1.00000 0.00000
--------------------------------------
Opening Data File Data/object_data2
About to load 2 Models
Read in No.1
Read in No.2
Objectfile num = 2


arGetTransMat() 안에서 다음과 같이 pattern의 transformation 값을 출력해 보면,
    // http://www.hitl.washington.edu/artoolkit/documentation/tutorialcamera.htm
    printf("camera transformation: %f  %f  %f\n",conv[0][3],conv[1][3],conv[2][3]);

결과:


Feature List     
* A simple framework for creating real-time augmented reality applications    
* A multiplatform library (Windows, Linux, Mac OS X, SGI)    
* Overlays 3D virtual objects on real markers ( based on computer vision algorithm)    
* A multi platform video library with:          
o multiple input sources (USB, Firewire, capture card) supported          
o multiple format (RGB/YUV420P, YUV) supported          
o multiple camera tracking supported          
o GUI initializing interface    
* A fast and cheap 6D marker tracking (real-time planar detection)    
* An extensible markers patterns approach (number of markers fct of efficency)    
* An easy calibration routine    
* A simple graphic library (based on GLUT)    
* A fast rendering based on OpenGL    
* A 3D VRML support    
* A simple and modular API (in C)    
* Other language supported (JAVA, Matlab)    
* A complete set of samples and utilities    
* A good solution for tangible interaction metaphor    
* OpenSource with GPL license for non-commercial usage


framework



"ARToolKit is able to perform this camera tracking in real time, ensuring that the virtual objects always appear overlaid on the tracking markers."

how to
1. 매 비디오 프레임 마다 사각형 모양을 찾기
2. 검은색 사각형에 대한 카메라의 상대적 위치를 계산
3. 그 위치로부터 컴퓨터 그래픽 모델이 어떻게 그려질지를 계산
4. 실제 영상의 마커 위에 모델을 그림

limitations
1. 추적하는 마커가 영상 안에 보일 때에만 가상 물체를 합성할 수 있음
2. 이 때문에 가상 물체들의 크기나 이동이 제한됨
3. 마커의 패턴의 일부가 가려지는 경우 가상 물체를 합성할 수 없음
4. range(거리)의 제한: 마커의 모양이 클수록 멀리 떨어진 패턴까지 감지할 수 있으므로 추적할 수 있는 volume(범위)이 더 커짐
(이때 거리는  pattern complexity (패턴의 복잡도)에 따라 달라짐: 패턴이 단순할수록 한계 거리가 길어짐)
5. 추적 성능이 카메라에 대한 마커의 상대적인 orientation(방향)에 따라 달라짐
: 마커가 많이 기울어 수평에 가까워질수록 보이는 패턴의 부분이 줄어들기 때문에 recognition(인식)이 잘 되지 않음(신뢰도가 떨어짐)
6. 추적 성능이 lighting conditions (조명 상태)에 따라 달라짐
: 조명에 의해 종이 마커 위에 reflection and glare spots (반사)가 생기면 마커의 사각형을 찾기가 어려워짐
: 종이 대신 반사도가 적은 재료를 쓸 수 있음


ARToolKit Vision Algorithm



Development
Initialization    
1. Initialize the video capture and read in the marker pattern files and camera parameters. -> init()
Main Loop    
2. Grab a video input frame. -> arVideoGetImage()
3. Detect the markers and recognized patterns in the video input frame. -> arDetectMarker()
4. Calculate the camera transformation relative to the detected patterns. -> arGetTransMat)
5. Draw the virtual objects on the detected patterns. -> draw()
Shutdown    
6. Close the video capture down. -> cleanup()

ref.
http://king8028.tistory.com/entry/ARToolkit-simpletestc-%EC%84%A4%EB%AA%8512
http://kougaku-navi.net/ARToolKit.html



ARToolKit video configuration



camera calibration

Default camera properties are contained in the camera parameter file camera_para.dat, that is read in each time an application is started.

The program calib_dist is used to measure the image center point and lens distortion, while calib_param produces the other camera properties. (Both of these programs can be found in the bin directory and their source is in the utils/calib_dist and utils/calib_cparam directories.)



ARToolKit gives the position of the marker in the camera coordinate system, and uses OpenGL matrix system for the position of the virtual object.


ARToolKit API Documentation
http://artoolkit.sourceforge.net/apidoc/


ARMarkerInfo Main structure for detected marker
ARMarkerInfo2 Internal structure use for marker detection
ARMat Matrix structure
ARMultiEachMarkerInfoT Multi-marker structure
ARMultiMarkerInfoT Global multi-marker structure
ARParam Camera intrinsic parameters
arPrevInfo Structure for temporal continuity of tracking
ARVec Vector structure


arVideoGetImage()

video.h
/**
 * \brief get the video image.
 *
 * This function returns a buffer with a captured video image.
 * The returned data consists of a tightly-packed array of
 * pixels, beginning with the first component of the leftmost
 * pixel of the topmost row, and continuing with the remaining
 * components of that pixel, followed by the remaining pixels
 * in the topmost row, followed by the leftmost pixel of the
 * second row, and so on.
 * The arrangement of components of the pixels in the buffer is
 * determined by the configuration string passed in to the driver
 * at the time the video stream was opened. If no pixel format
 * was specified in the configuration string, then an operating-
 * system dependent default, defined in <AR/config.h> is used.
 * The memory occupied by the pixel data is owned by the video
 * driver and should not be freed by your program.
 * The pixels in the buffer remain valid until the next call to
 * arVideoCapNext, or the next call to arVideoGetImage which
 * returns a non-NULL pointer, or any call to arVideoCapStop or
 * arVideoClose.
 * \return A pointer to the pixel data of the captured video frame,
 * or NULL if no new pixel data was available at the time of calling.
 */
AR_DLL_API  ARUint8*        arVideoGetImage(void);


ARParam

param.h
/** \struct ARParam
* \brief camera intrinsic parameters.
*
* This structure contains the main parameters for
* the intrinsic parameters of the camera
* representation. The camera used is a pinhole
* camera with standard parameters. User should
* consult a computer vision reference for more
* information. (e.g. Three-Dimensional Computer Vision
* (Artificial Intelligence) by Olivier Faugeras).
* \param xsize length of the image (in pixels).
* \param ysize height of the image (in pixels).
* \param mat perspective matrix (K).
* \param dist_factor radial distortions factor
*          dist_factor[0]=x center of distortion
*          dist_factor[1]=y center of distortion
*          dist_factor[2]=distortion factor
*          dist_factor[3]=scale factor
*/
typedef struct {
    int      xsize, ysize;
    double   mat[3][4];
    double   dist_factor[4];
} ARParam;

typedef struct {
    int      xsize, ysize;
    double   matL[3][4];
    double   matR[3][4];
    double   matL2R[3][4];
    double   dist_factorL[4];
    double   dist_factorR[4];
} ARSParam;




arDetectMarker()

ar.h 헤더 파일의 설명:
/**
* \brief main function to detect the square markers in the video input frame.
*
* This function proceeds to thresholding, labeling, contour extraction and line corner estimation
* (and maintains an history).
* It's one of the main function of the detection routine with arGetTransMat.
* \param dataPtr a pointer to the color image which is to be searched for square markers.
*                The pixel format depend of your architecture. Generally ABGR, but the images
*                are treated as a gray scale, so the order of BGR components does not matter.
*                However the ordering of the alpha comp, A, is important.
* \param thresh  specifies the threshold value (between 0-255) to be used to convert
*                the input image into a binary image.
* \param marker_info a pointer to an array of ARMarkerInfo structures returned
*                    which contain all the information about the detected squares in the image
* \param marker_num the number of detected markers in the image.
* \return 0 when the function completes normally, -1 otherwise
*/
int arDetectMarker( ARUint8 *dataPtr, int thresh,
                    ARMarkerInfo **marker_info, int *marker_num );


You need to notice that arGetTransMat give the position of the marker in the camera coordinate system (not the reverse). If you want the position of the camera in the marker coordinate system you need to inverse this transformation (arMatrixInverse()).



XXXBK: not be sure of this function: this function must just convert 3x4 matrix to classical perspective openGL matrix. But in the code, you used arParamDecompMat that seem decomposed K and R,t, aren't it ? why do this decomposition since we want just intrinsic parameters ? and if not what is arDecomp ?




double arGetTransMat()

ar.h 헤더 파일의 설명:
/**
* \brief compute camera position in function of detected markers.
*
* calculate the transformation between a detected marker and the real camera,
* i.e. the position and orientation of the camera relative to the tracking mark.
* \param marker_info the structure containing the parameters for the marker for
*                    which the camera position and orientation is to be found relative to.
*                    This structure is found using arDetectMarker.
* \param center the physical center of the marker. arGetTransMat assumes that the marker
*              is in x-y plane, and z axis is pointing downwards from marker plane.
*              So vertex positions can be represented in 2D coordinates by ignoring the
*              z axis information. The marker vertices are specified in order of clockwise.
* \param width the size of the marker (in mm).
* \param conv the transformation matrix from the marker coordinates to camera coordinate frame,
*             that is the relative position of real camera to the real marker
* \return always 0.
*/
double arGetTransMat( ARMarkerInfo *marker_info,
                      double center[2], double width, double conv[3][4] )



arUtilMatInv()

ar.h 헤더 파일의 설명:
/**
* \brief Inverse a non-square matrix.
*
* Inverse a matrix in a non homogeneous format. The matrix
* need to be euclidian.
* \param s matrix input   
* \param d resulted inverse matrix.
* \return 0 if the inversion success, -1 otherwise
* \remark input matrix can be also output matrix
*/
int    arUtilMatInv( double s[3][4], double d[3][4] );






posted by maetel
2010. 2. 10. 15:47 Computer Vision
Seong-Woo Park, Yongduek Seo, Ki-Sang Hong: Real-Time Camera Calibration for Virtual Studio. Real-Time Imaging 6(6): 433-448 (2000)
doi:10.1006/rtim.1999.0199

Seong-Woo Park, Yongduek Seo and Ki-Sang Hong1

Dept. of E.E. POSTECH, San 31, Hyojadong, Namku, Pohang, Kyungbuk, 790-784, Korea


Abstract

In this paper, we present an overall algorithm for real-time camera parameter extraction, which is one of the key elements in implementing virtual studio, and we also present a new method for calculating the lens distortion parameter in real time. In a virtual studio, the motion of a virtual camera generating a graphic studio must follow the motion of the real camera in order to generate a realistic video product. This requires the calculation of camera parameters in real-time by analyzing the positions of feature points in the input video. Towards this goal, we first design a special calibration pattern utilizing the concept of cross-ratio, which makes it easy to extract and identify feature points, so that we can calculate the camera parameters from the visible portion of the pattern in real-time. It is important to consider the lens distortion when zoom lenses are used because it causes nonnegligible errors in the computation of the camera parameters. However, the Tsai algorithm, adopted for camera calibration, calculates the lens distortion through nonlinear optimization in triple parameter space, which is inappropriate for our real-time system. Thus, we propose a new linear method by calculating the lens distortion parameter independently, which can be computed fast enough for our real-time application. We implement the whole algorithm using a Pentium PC and Matrox Genesis boards with five processing nodes in order to obtain the processing rate of 30 frames per second, which is the minimum requirement for TV broadcasting. Experimental results show this system can be used practically for realizing a virtual studio.


전자공학회논문지 제36권 S편 제7호, 1999. 7 
가상스튜디오 구현을 위한 실시간 카메라 추적 ( Real-Time Camera Tracking for Virtual Studio )   
박성우 · 서용덕 · 홍기상 저 pp. 90~103 (14 pages)
http://uci.or.kr/G300-j12265837.v36n07p90

서지링크     한국과학기술정보연구원
가상스튜디오의 구현을 위해서 카메라의 움직임을 실시간으로 알아내는 것이 필수적이다. 기존의 가상스튜디어 구현에 사용되는 기계적인 방법을 이용한 카메라의 움직임 추적하는 방법에서 나타나는 단점들을 해결하기 위해 본 논문에서는 카메라로부터 얻어진 영상을 이용해 컴퓨터비전 기술을 응용하여 실시간으로 카메라변수들을 알아내기 위한 전체적인 알고리듬을 제안하고 실제 구현을 위한 시스템의 구성 방법에 대해 다룬다. 본 연구에서는 실시간 카메라변수 추출을 위해 영상에서 특징점을 자동으로 추출하고 인식하기 위한 방법과, 카메라 캘리브레이션 과정에서 렌즈의 왜곡특성 계산에 따른 계산량 문제를 해결하기 위한 방법을 제안한다.



Practical ways to calculate camera lens distortion for real-time camera calibration
Pattern Recognition, Volume 34, Issue 6, June 2001, Pages 1199-1206
Seong-Woo Park, Ki-Sang Hong




generating virtual studio




Matrox Genesis boards
http://www.matrox.com/imaging/en/support/legacy/

http://en.wikipedia.org/wiki/Virtual_studio
http://en.wikipedia.org/wiki/Chroma_key

camera tracking system : electromechanical / optical
pattern recognition
2D-3D pattern matches
planar pattern


feature extraction -> image-model matching & identification -> camera calibration
: to design the pattern by applying the concept of cross-ratio and to identify the pattern automatically


영상에서 찾아진 특징점을 자동으로 인식하기 위해서는 공간 상의 점들과 영상에 나타난 그것들의 대응점에 대해서 같은 값을 갖는 성질이 필요한데 이것을 기하적 불변량 (Geometric Invariant)이라고 한다. 본 연구에서는 여러 불변량 가운데 cross-ratio를 이용하여 패턴을 제작하고, 영상에서 불변량의 성질을 이용하여 패턴을 자동으로 찾고 인식할 수 있게 하는 방법을 제안한다.


Tsai's algorithm
R. Y. Tsai, A Versatile Camera Calibration Technique for High Accuracy 3-D Maching Vision Metrology Using Off-the-shelf TV Cameras and Lenses. IEEE Journal of Robotics & Automation 3 (1987), pp. 323–344.

direct image mosaic method
Sawhney, H. S. and Kumar, R. 1999. True Multi-Image Alignment and Its Application to Mosaicing and Lens Distortion Correction. IEEE Trans. Pattern Anal. Mach. Intell. 21, 3 (Mar. 1999), 235-243. DOI= http://dx.doi.org/10.1109/34.754589

Lens distortion
Richard Szeliski, Computer Vision: Algorithms and Applications: 2.1.6 Lens distortions & 6.3.5 Radial distortion

radial alignment constraint
"If we presume that the lens has only radial distortion, the direction of a distorted point is the same as the direction of an undistorted point."

cross-ratio  http://en.wikipedia.org/wiki/Cross_ratio
: planar projective geometric invariance
 - "pencil of lines"
http://mathworld.wolfram.com/CrossRatio.html
http://homepages.inf.ed.ac.uk/rbf/CVonline/LOCAL_COPIES/MOHR_TRIGGS/node25.html
http://www.cut-the-knot.org/pythagoras/Cross-Ratio.shtml
http://web.science.mq.edu.au/~chris/geometry/


pattern identification

 카메라의 움직임을 알아내기 위해서는 공간상에 인식이 가능한 물체가 있어야 한다. 즉, 어느 위치에서 보더라도 영상에 나타난 특징점을 찾을 수 있고, 공간상의 어느 점에 대응되는 점인지를 알 수 있어야 한다.

패턴이 인식 가능하기 위해서는 카메라가 어느 위치, 어느 자세로 보던지 항상 같은 값을 갖는 기하적 불변량 (Geometric Invariant)이 필요하다.

Coelho, C., Heller, A., Mundy, J. L., Forsyth, D. A., and Zisserman, A.1992. An experimental evaluation of projective invariants. In Geometric invariance in Computer Vision, J. L. Mundy and A. Zisserman, Eds. Mit Press Series Of Artificial Intelligence Series. MIT Press, Cambridge, MA, 87-104.


> initial identification process
extracting the pattern in an image: chromakeying -> gradient filtering: a first-order derivative of Gaussian (DoG) -> line fitting: deriving a distorted line (that is actually a curve) equation -> feature point tracking (using intersection filter)


R1x = 0



http://en.wikipedia.org/wiki/Difference_of_Gaussians



real-time camera parameter extraction

이상적인 렌즈의 optical axis가 영상면에 수직이고 변하지 않는다고 할 때, 영상 중심은 카메라의 줌 동작 동안 고정된 값으로 계산된다. (그러나 실제 렌즈의 불완전한 특성 때문에 카메라의 줌 동작 동안 영상 중심 역시 변하게 되는데, 이 변화량은 적용 범위 이내에서 2픽셀 이하이다. 따라서 본 연구에서는 이러한 변화를 무시하고 이상적인 렌즈를 가정하여 줌동작에 의한 영상 중심을 구하게 된다.)

For zoom lenses, the image centers vary as the camera zooms because the zooming operation is executed by a composite combination of several lenses. However, when we examined the location of the image centers, its standard deviation was about 2 pixels; thus we ignored the effect of the image center change.


calculating lens distortion coefficient

Zoom lenses are zoomed by a complicated combination of several lenses so that the effective focal length and distortion coefficient vary during zooming operations.

When using the coplanar pattern with small depth variation, it turns out that focal length and z-translation cannot be separated exactly and reliably even with small noise.

카메라 변수 추출에 있어서 공간상의 특징점들이 모두 하나의 평면상에 존재할 때는 초점거리와 z 방향으로의 이동이 상호 연관 (coupling)되어 계산값의 안정성이 결여되기 쉽다.


collinearity

Collinearity represents a property when the line in the world coordinate is also shown as a line in the image. This property is not preserved when the lens has a distortion.


Once the lens distortion is calculated, we can execute camera calibration using linear methods.


filtering

가상 스튜디오 구현에 있어서는 시간 지연이 항상 같은 값을 가지게 하는 것이 필수적이므로, 실제 적용에서는 예측 (prediction)이 들어가는 필터링 방법(예를 들면, Kalman filter)은 사용할 수가 없었다.

averaging filter 평균 필터








Orad  http://www.orad.co.il

Evans & Sutherland http://www.es.com









posted by maetel
2010. 2. 9. 21:22 Computer Vision

Foundations and Trends® in
Computer Graphics and Vision

Volume 4 Issue 4

3D Reconstruction from Multiple Images: Part 1 Principles

Theo Moons
KU Brussel

Luc Van Gool
KU Leuven and ETH Zurich

Maarten Vergauwen
GeoAutomation

Abstract

The issue discusses methods to extract 3-dimensional (3D) models from plain images. In particular, the 3D information is obtained from images for which the camera parameters are unknown. The principles underlying such uncalibrated structure-from-motion methods are outlined. First, a short review of 3D acquisition technologies puts such methods in a wider context, and highlights their important advantages. Then, the actual theory behind this line of research is given. The authors have tried to keep the text maximally self-contained, therefore also avoiding to rely on an extensive knowledge of the projective concepts that usually appear in texts about self-calibration 3D methods. Rather, mathematical explanations that are more amenable to intuition are given. The explanation of the theory includes the stratification of reconstructions obtained from image pairs as well as metric reconstruction on the basis of more than 2 images combined with some additional knowledge about the cameras used. Readers who want to obtain more practical information about how to implement such uncalibrated structure-from-motion pipelines may be interested in two more Foundations and Trends issues written by the same authors. Together with this issue they can be read as a single tutorial on the subject.

posted by maetel