2013-06-28 93 views
5

我一直在努力在我的Android應用程序中實現一個四核到四核系統。其目的是讓用戶拍攝一張照片,添加4個角點,並將該四邊形從圖像中提取爲矩形。無法讓OpenCV的warpPerspective在Android上工作

我看了一下this methodthis question爲此使用OpenCV。生成的代碼是這樣的:

public static Bitmap warp(Bitmap image, MyPoint p1, MyPoint p2, MyPoint p3, MyPoint p4) { 
    int resultWidth = 500; 
    int resultHeight = 500; 

    Mat inputMat = new Mat(image.getHeight(), image.getHeight(), CvType.CV_8UC4); 
    Utils.bitmapToMat(image, inputMat); 
    Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC4); 

    Point ocvPIn1 = new Point(p1.getX(), p1.getY()); 
    Point ocvPIn2 = new Point(p2.getX(), p2.getY()); 
    Point ocvPIn3 = new Point(p3.getX(), p3.getY()); 
    Point ocvPIn4 = new Point(p4.getX(), p4.getY()); 
    List<Point> source = new ArrayList<Point>(); 
    source.add(ocvPIn1); 
    source.add(ocvPIn2); 
    source.add(ocvPIn3); 
    source.add(ocvPIn4); 
    Mat startM = Converters.vector_Point2f_to_Mat(source); 

    Point ocvPOut1 = new Point(0, 0); 
    Point ocvPOut2 = new Point(0, resultHeight); 
    Point ocvPOut3 = new Point(resultWidth, resultHeight); 
    Point ocvPOut4 = new Point(resultWidth, 0); 
    List<Point> dest = new ArrayList<Point>(); 
    dest.add(ocvPOut1); 
    dest.add(ocvPOut2); 
    dest.add(ocvPOut3); 
    dest.add(ocvPOut4); 
    Mat endM = Converters.vector_Point2f_to_Mat(dest);  

    Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1); 
    Core.perspectiveTransform(startM, endM, perspectiveTransform); 

    Imgproc.warpPerspective(inputMat, 
          outputMat, 
          perspectiveTransform, 
          new Size(resultWidth, resultHeight), 
          Imgproc.INTER_CUBIC); 

    Bitmap output = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.RGB_565); 
    Utils.matToBitmap(outputMat, output); 
    return output; 
} 

測試時,我確保了角點的順序是左上,左下,右下,右上。

奇怪的是,結果並不總是相同的。大多數時候,它顯示一個單一的顏色的平方,有時是一個黑色的正方形,有時是一個不同顏色的對角線。即使試驗startM = endM也會導致非確定性行爲。

我在這裏錯過了什麼?

+0

這工作一些如何,但有時它會給m錯誤和/或最終位圖的旋轉副本。 ?這是渴望出來 –

回答

5

找到了,問題是,這些行:

Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1); 
Core.perspectiveTransform(startM, endM, perspectiveTransform); 

,應由此來代替:

Mat perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM); 
+1

謝謝@Aegoins你省了很多我的努力。 – DearDhruv

+0

你好,我跟你一樣,但我得到一個奇怪的輸出。其實我的輸入是一張名片,並使用透視變換,我想從圖像中提取出卡片。我得到的輸出圖像只是一張空白的彩色圖像,它具有卡片中某種顏色的顏色。 – Manpreet

+0

@Aegonis這可以工作一些,但有些時候它會提供最終位圖的鏡像副本。 ?這是需要出來 –

1

我有一些問題,你的代碼,所以我所做的更改,直到我得到一個工作版本,這裏是我的代碼,如果有人有問題的代碼的問題:

Bitmap warp(Bitmap image, Point topLeft, Point topRight, Point bottomLeft, Point bottomRight) { 
    int resultWidth = (int)(topRight.x - topLeft.x); 
    int bottomWidth = (int)(bottomRight.x - bottomLeft.x); 
    if(bottomWidth > resultWidth) 
     resultWidth = bottomWidth; 

    int resultHeight = (int)(bottomLeft.y - topLeft.y); 
    int bottomHeight = (int)(bottomRight.y - topRight.y); 
    if(bottomHeight > resultHeight) 
     resultHeight = bottomHeight; 

    Mat inputMat = new Mat(image.getHeight(), image.getHeight(), CvType.CV_8UC1); 
    Utils.bitmapToMat(image, inputMat); 
    Mat outputMat = new Mat(resultWidth, resultHeight, CvType.CV_8UC1); 

    List<Point> source = new ArrayList<>(); 
    source.add(topLeft); 
    source.add(topRight); 
    source.add(bottomLeft); 
    source.add(bottomRight); 
    Mat startM = Converters.vector_Point2f_to_Mat(source); 

    Point ocvPOut1 = new Point(0, 0); 
    Point ocvPOut2 = new Point(resultWidth, 0); 
    Point ocvPOut3 = new Point(0, resultHeight); 
    Point ocvPOut4 = new Point(resultWidth, resultHeight); 
    List<Point> dest = new ArrayList<>(); 
    dest.add(ocvPOut1); 
    dest.add(ocvPOut2); 
    dest.add(ocvPOut3); 
    dest.add(ocvPOut4); 
    Mat endM = Converters.vector_Point2f_to_Mat(dest); 

    Mat perspectiveTransform = Imgproc.getPerspectiveTransform(startM, endM); 

    Imgproc.warpPerspective(inputMat, outputMat, perspectiveTransform, new Size(resultWidth, resultHeight)); 

    Bitmap output = Bitmap.createBitmap(resultWidth, resultHeight, Bitmap.Config.ARGB_8888); 
    Utils.matToBitmap(outputMat, output); 
    return output; 
} 
+0

這段代碼是否正常工作,請不要爲我工作 – Ata

+0

@Ata你的問題是什麼? – jonathanrz