2013-01-16 21 views
5

Po prostu chcę odtworzyć wynik jako opublikowany here.Jak włączyć funkcję PerspectiveTransform?

Przepisuję źródło na formularz EmguCV.

Image<Bgr, byte> image = new Image<Bgr, byte>(@"B:\perspective.png"); 

    CvInvoke.cvShowImage("Hello World!", image); 

    float[,] scrp = { { 43, 18 }, { 280,40}, {19,223 }, { 304,200} }; 
    float[,] dstp = { { 0,0}, { 320,0}, { 0,240 }, { 320,240 } }; 
    float[,] homog = new float[3, 3]; 


    Matrix<float> c1 = new Matrix<float>(scrp); 
    Matrix<float> c2 = new Matrix<float>(dstp); 
    Matrix<float> homogm = new Matrix<float>(homog); 


    CvInvoke.cvFindHomography(c1.Ptr, c2.Ptr, homogm.Ptr, Emgu.CV.CvEnum.HOMOGRAPHY_METHOD.DEFAULT, 0, IntPtr.Zero); 
    CvInvoke.cvGetPerspectiveTransform(c1, c2, homogm); 

    Image<Bgr, byte> newImage = image.WarpPerspective(homogm, Emgu.CV.CvEnum.INTER.CV_INTER_CUBIC, Emgu.CV.CvEnum.WARP.CV_WARP_DEFAULT, new Bgr(0, 0, 0)); 

    CvInvoke.cvShowImage("newImage", newImage); 

To jest obraz testowy. enter image description here

Nowy obraz jest zawsze pustym obrazem.

Czy ktoś może mi pomóc, aby mój kod źródłowy działał ???

Odpowiedz

4

Mam nadzieję, że znalazłem odpowiedź sam.

Przepisałem źródło na niewłaściwą formę. Powinienem użyć Point [] i istnieje funkcja CameraCalibration.GetPerspectiveTransform do użycia.

PointF[] srcs = new PointF[4]; 
    srcs[0] = new PointF(253, 211); 
    srcs[1] = new PointF(563, 211); 
    srcs[2] = new PointF(563, 519); 
    srcs[3] = new PointF(253, 519); 


    PointF[] dsts = new PointF[4]; 
    dsts[0] = new PointF(234, 197); 
    dsts[1] = new PointF(520, 169); 
    dsts[2] = new PointF(715, 483); 
    dsts[3] = new PointF(81, 472); 

    HomographyMatrix mywarpmat = CameraCalibration.GetPerspectiveTransform(srcs, dsts); 
    Image<Bgr, byte> newImage = image.WarpPerspective(mywarpmat, Emgu.CV.CvEnum.INTER.CV_INTER_NN, Emgu.CV.CvEnum.WARP.CV_WARP_FILL_OUTLIERS, new Bgr(0, 0, 0)); 
+0

cool, tnx! Czy masz pomysł, w jaki sposób mogę uzyskać stosunek krawędzi, jeśli mam jakiś obraz z prostokątnym obiektem? – Michael

+1

Co masz na myśli przez "stosunek krawędzi"? Jeśli masz na myśli wartości takie jak 253, 211, musisz ręcznie zmierzyć obrazy w programie Paint lub innych podobnych programach. – Gqqnbig

1

Oto metoda rozszerzenie dla EmguCV wersji 3 (które mają wiele funkcji przestarzałe):

public static Image<TColor, TDepth> GetAxisAlignedImagePart<TColor, TDepth>(
    this Image<TColor, TDepth> input, 
    Quadrilateral rectSrc, 
    Quadrilateral rectDst, 
    Size targetImageSize) 
    where TColor : struct, IColor 
    where TDepth : new() 
{ 
    var src = new[] { rectSrc.P0, rectSrc.P1, rectSrc.P2, rectSrc.P3 }; 
    var dst = new[] { rectDst.P0, rectDst.P1, rectDst.P2, rectDst.P3 }; 

    using (var matrix = CvInvoke.GetPerspectiveTransform(src, dst)) 
    { 
     using (var cutImagePortion = new Mat()) 
     { 
      CvInvoke.WarpPerspective(input, cutImagePortion, matrix, targetImageSize, Inter.Cubic); 
      return cutImagePortion.ToImage<TColor, TDepth>(); 
     } 
    } 
}