2017-03-22 23 views
11

我試着翻譯下面的Python功能,應用於口罩,圖像,到Java:翻譯Python函數來敷面膜圖像轉換成Java

# Applies an image mask. 
def region_of_interest(img, vertices): 
    #defining a blank mask to start with 
    mask = np.zeros_like(img) 

    #defining a 3 channel or 1 channel color to fill the mask with depending on the input image 
    if len(img.shape) > 2: 
     channel_count = img.shape[2] # i.e. 3 or 4 depending on your image 
     ignore_mask_color = (255,) * channel_count 
    else: 
     ignore_mask_color = 255 

    #filling pixels inside the polygon defined by "vertices" with the fill color  
    cv2.fillPoly(mask, vertices, ignore_mask_color) 

    #returning the image only where mask pixels are nonzero 
    masked_image = cv2.bitwise_and(img, mask) 
    return masked_image 

到目前爲止,這是我」 ve得到了:

public static opencv_core.Mat applyMask(opencv_core.Mat image, opencv_core.MatVector vertices) { 
    opencv_core.Mat mask = opencv_core.Mat.zeros(image.size(), opencv_core.CV_8U).asMat(); 

    opencv_core.Scalar color = new opencv_core.Scalar(image.channels()); // 3 
    double[] colors = new double[] { 
    255.0, 255.0, 255.0, 255.0, 
    255.0, 255.0, 255.0, 255.0, 
    255.0, 255.0, 255.0, 255.0}; 
    color.put(colors, 0, colors.length); 

    opencv_imgproc.fillPoly(mask, vertices, color); 

    opencv_core.Mat dst = new opencv_core.Mat(); 
    opencv_core.bitwise_and(image, mask, dst); 
    return dst; 
} 

但是,它不工作。當我嘗試在下面的示例中調用此方法,如:

opencv_core.MatVector points = new opencv_core.MatVector(
    new opencv_core.Mat(2, 3, opencv_core.CV_32F, new IntPointer(1, 2, 3, 4, 5, 6)) 
); 

opencv_core.MatVector vertices = new opencv_core.MatVector(points); 
opencv_core.Mat masked = LaneManager.applyMask(src, vertices); 

(我假設這是建立三個點的2x3矩陣,兩個座標每個(1,2)(3, 4)(5,6)正道)

我得到一個異常:

java.lang.RuntimeException: std::bad_alloc 
at org.bytedeco.javacpp.opencv_imgproc.fillPoly(Native Method) 

我使用的OpenCV作爲Maven的通過由中央提供org.bytedeco.javacpp-presets:opencv-platform:3.2.0-1.3

我必須承認我在這裏感到茫然:與上面的Python函數做同樣事情的慣用Java方法是什麼?

+0

我認爲你在找什麼是與這個其他stackoverflow帖子http:// stackoverflow。COM /問題/ 221830 /設置的BufferedImage-α-面具式的Java。希望這可以幫助。 –

+0

你是如何初始化你發送到applyMask的src變量的? – Daedalus

+0

一個可疑的事情是,你顯然正在爲12通道色彩分量的3通道圖像定義顏色。這是不對的。 – Dave

回答

1

也許一些高手有完整的答案。這裏是深思:

  1. Java的API是CPP API直接拷貝:http://opencv.org/opencv-java-api.html
  2. 錯誤std::bad_alloc當你無法分配所需的存儲空間出現。 (http://answers.opencv.org/question/28959/cascade-training-killed-and-bad_alloc/

  3. 有兩種CPP方法:
  4. 你並不需要從Mat轉換爲InputArray,但您可以(也應該)只通過一個Mat對象,其中InputArray請求(https://stackoverflow.com/a/32976883/1587329

+0

謝謝您關注此問題,但這無濟於事。在Java端暴露的'fillPoly'方法都沒有使用'InputArray'。他們要麼採取「墊子」或「UMat」。我認爲我的問題更多的是沒有正確定義點的列表。例如,如果你能給我一個例子,說明如何用4個點的列表創建點參數,每個點有2個座標。 – zugaldia

+0

@ zugaldia:感謝您的反饋。你是否嘗試過內存選項來增加堆大小,如f.ex. '-Xmx512m'? –

+0

是的。我認爲他們的問題是我想使用'public static native fillPoly(Mat blackImg,MatVector points,Scalar whiteColor);'但我沒有正確定義MatVector points。我如何爲這個用例創建一個新的'MatVector'? – zugaldia

1

好吧,我終於想通了。如果你定義座標:

int[] points = new int[] {x1, y1, x2, y2, ...}; 

然後,你可以簡單地敷個面膜用下面的代碼:

opencv_core.Mat mask = new opencv_core.Mat(image.size(), image.type()); 

// Array of polygons where each polygon is represented as an array of points 
opencv_core.Point polygon = new opencv_core.Point(); 
polygon.put(points, 0, points.length); 
opencv_imgproc.fillPoly(mask, polygon, new int[] {points.length/2}, 1, new opencv_core.Scalar(255, 255, 255, 0)); 

opencv_core.Mat masked = new opencv_core.Mat(image.size(), image.type()); 
opencv_core.bitwise_and(image, mask, masked); 

哪裏image是原始圖像,並且masked是屏蔽後的結果。

問題是沒有正確定義原始點列表。