2016-05-02 9 views
1

私はスタンドアロンモード(私のラップトップのシングルノード)でスパークをセットアップし、opencvを統合してディレクトリから画像セットを読み込み、それぞれの顔を検出しようとしました画像。私はネイティブの依存関係がexecutor jvmにどのように配送されているのか理解しようとしていますが、以下のプログラムではSystem.loadLibrary関数がドライバjvmの一部として実行され、executor jvmは無名関数がネイティブライブラリを見つける。しかし、私の理解に反して、プログラムは正常に動作します。誰かがこれがどのように動作し、どのコードの一部がドライバからエグゼキュータに送られるかを説明できますか?スタンドアロンモードでのドライバ/エグゼキュータのコードフロー

public static void main(String[] args) 
{ 
    SparkConf conf = new SparkConf().setMaster("spark://localhost:7077").setAppName("Image detect App"); 
    JavaSparkContext sc = new JavaSparkContext(conf); 
    System.loadLibrary(Core.NATIVE_LIBRARY_NAME); 

    CascadeClassifier faceDetector = new CascadeClassifier("/home/xx/Project/opencv-3.1.0/data/haarcascades_cuda/haarcascade_frontalface_alt.xml"); 

    File tempDir = new File("/home/xx/images/new"); 
    String tempDirName = tempDir.getAbsolutePath(); 

    JavaPairRDD<String, PortableDataStream> readRDD = sc.binaryFiles(tempDirName,3); 
    List<Tuple2<String, PortableDataStream>> result = readRDD.collect(); 
    for (Tuple2<String, PortableDataStream> res : result) 
    { 
     Mat image = Imgcodecs 
       .imread(res._1().replace("file:","")); 

     MatOfRect faceDetections = new MatOfRect(); 
     faceDetector.detectMultiScale(image, faceDetections); 

     for (Rect rect : faceDetections.toArray()) { 
      Imgproc.rectangle(image, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height), 
        new Scalar(0, 255, 0)); 
     } 
     String filename = res._1().replace("file:","") + "_out"; 
     Imgcodecs.imwrite(filename, image); 
    } 

} は、上記のプログラムとのjarファイルを作成し、次の火花は予想通り、それは正常に動作し、コマンドを発行走っています。

./bin/spark-submit --verbose - マスターspark:// localhost:7077 --num-executor 2 --class com.xxx.MainSparkImage --jars/home/xx/Project/opencv- 3.1.0/release/bin/opencv-310.jar - ドライバライブラリパス/home/xx/Project/opencv-3.1.0/release/lib/home/xx/ImageProcess.jar

ありがとう Srivatsan

+0

spark.driver.extraClassPath spark.executor.extraClassPathスパーク送信中にこれらを試しましたか? –

+0

spark.executor.extraClassPathは、その名前になっていますが、エグゼキュータに依存関係を送信する必要があります。どうもありがとう。 –

答えて

4
List<Tuple2<String, PortableDataStream>> result = readRDD.collect(); 

この行によって、RDDはローカルコレクションとしてドライバに収集されます。残りのコード(forループ)はドライバ内でローカルに実行されます。したがって、エグゼキュータ上のネイティブライブラリが見つからないというエラーは表示されません。

+0

Ooops ...それを見つけていただきありがとうございます: - )...私は収集を使用しないで、代わりに無名関数を使用しようとします。今回エラーが発生するかどうかを確認します –

+0

はいPranavが正しく検出されました –

+0

あなたは歓迎です:-) –

関連する問題