2017-01-17 13 views
2

私はblobDetection libraryで処理中で、高さマップから等高線マップを作成しています。 私は現在、各レイヤーをレーザーカットのSVGとしてエクスポートしていますが、スケッチの端にあるブロブは完全ではなく、エッジの頂点は描画されません。ここ処理でスケッチの端にあるBlobのエッジを描画する

が簡単な例である:

  1. Iで始まる画像は、白領域がブロブ

enter image description here

なろう
  • SVG出力、エッジを欠いている。
  • import processing.svg.*; 
    import blobDetection.*; 
    import peasy.*; 
    import processing.pdf.*; 
    PeasyCam cam; 
    
    PImage img; 
    
    float levels = 10; 
    
    BlobDetection[] contours = new BlobDetection[int(levels)]; 
    
    //Creating array to store the blob objects 
    ArrayList<Ring> rings = new ArrayList<Ring>(); 
    
    void setup() { 
    
        size(480, 360, P3D); 
        surface.setResizable(true); 
    
        img = loadImage("maptest2.jpg"); 
        surface.setSize(img.width, img.height); 
    
        cam = new PeasyCam(this, img.width, img.height, 0, 1500); 
        colorMode(HSB, 360, 100, 100); 
    
        for (int i=0; i<levels; i++) { 
        contours[i] = new BlobDetection(img.width, img.height); 
        contours[i].setThreshold(i/levels); 
        contours[i].computeBlobs(img.pixels); 
        } 
    
        for (int i = 0; i < rings.size(); i++) { 
        System.out.println("id: " + rings.get(i).getId()); 
        System.out.println("lvl: " + rings.get(i).getLvl()); 
        System.out.println("x: " + rings.get(i).getX()); 
        System.out.println("y: " + rings.get(i).getY()); 
        System.out.println(); 
        } 
    
        noLoop(); 
    } 
    
    
    void draw() { 
    
        for (int i=0; i<levels; i++) { 
    
        beginRecord(SVG, "level-"+i+".svg"); 
    
        drawContours(i); 
        println("drew level " + i); 
    
        println("saved as: level-"+i+".svg"); 
        endRecord(); 
        println(); 
    
        if(i == levels-1){ 
         println("finished"); 
        } 
    
        } 
    
        System.out.println("Number of blobs (rings.size()): " + rings.size()); 
        println(); 
    
        for (int i = 0; i < rings.size(); i++){ 
        System.out.println("id: " + rings.get(i).getId()); 
        System.out.println("lvl: " + rings.get(i).getLvl()); 
        System.out.println("x: " + rings.get(i).getX()); 
        System.out.println("y: " + rings.get(i).getY()); 
        System.out.println(); 
        } 
    
    } 
    
    void drawContours(int i) { 
        Blob b; 
        EdgeVertex eA, eB; 
        for (int n=0; n<contours[i].getBlobNb(); n++) { 
        b=contours[i].getBlob(n); 
    
        //Condition for drawing only blobs bigger than 5% of width and 5% of height 
        if(b.w*width>.05*width && b.h*height>.05*height){ 
    
         if (b!=null) { 
         stroke(250, 75, 90); 
    
         for (int m=0; m<b.getEdgeNb(); m++) { 
          eA = b.getEdgeVertexA(m); 
          eB = b.getEdgeVertexB(m); 
    
          //This part draws the blobs. 
    
          if (eA !=null && eB !=null) 
          line(
          eA.x*img.width, eA.y*img.height, 
          eB.x*img.width, eB.y*img.height 
          ); 
    
          println("eA.x: " + eA.x); 
          println("eA.y: " + eA.y); 
          println("eB.x: " + eB.x); 
          println("eB.y: " + eB.y); 
          println(); 
    
          //////////// 
          //Here are my various attempts at drawing these rogue edges! 
          //I commented them out 
    
          /*  
          //Checking if vertex has a point at x=0 
          if (b.getEdgeVertexA(m).x == 0 && b.getEdgeVertexB(b.getEdgeNb()).x == 0){ 
    
    
           line( b.getEdgeVertexA(0).x*img.width, b.getEdgeVertexA(0).y*img.height, 
             b.getEdgeVertexA(m).x*img.width, b.getEdgeVertexA(m).y*img.height ); 
    
           println("////"); 
           println("x making line (scaled 0-1): "); 
           //println(eA.x, eA.y, eB.x, eB.y); 
           println( b.getEdgeVertexA(0).x, b.getEdgeVertexA(0).y, 
              b.getEdgeVertexA(m).x, b.getEdgeVertexA(m).y ); 
    
           println("////"); 
          } 
    
          //Checking if vertex has a point at y=0 
          if (b.getEdgeVertexA(m).y == 0 && b.getEdgeVertexB(b.getEdgeNb()).y == 0){ 
    
          line( b.getEdgeVertexA(0).x*img.width, b.getEdgeVertexA(0).y*img.height, 
            b.getEdgeVertexA(m).x*img.width, b.getEdgeVertexA(m).y*img.height ); 
    
           println("////"); 
           println("y making line (scaled 0-1): "); 
           //println(eA.x, eA.y, eB.x, eB.y); 
           println( b.getEdgeVertexA(0).x, b.getEdgeVertexA(0).y, 
              b.getEdgeVertexA(m).x, b.getEdgeVertexA(m).y ); 
    
           println("////"); 
    
          } 
    
          if (b.getEdgeVertexA(m).x == 0 && b.getEdgeVertexB(b.getEdgeNb()).y == 0){ 
    
          line( b.getEdgeVertexA(0).x*img.width, b.getEdgeVertexA(0).y*img.height, 0, 0 ); 
          println("drew to 0,0"); 
          } 
    
          if (b.getEdgeVertexA(m).y == 0 && b.getEdgeVertexB(b.getEdgeNb()).x == 0){ 
    
          line( b.getEdgeVertexA(m).x*img.width, b.getEdgeVertexA(m).y*img.height, 0, 0 ); 
          println("drew to 0,0"); 
          } 
          */ 
          //////////// 
    
         } 
    
         //Adding objects to the rings ArrayList 
         rings.add(new Ring(String.valueOf(rings.size()+1), (int) i, (double) b.x*100, (double) b.y*100)); 
         } 
        } 
        } 
    } 
    
    は今、私は私のコードは、これらのエッジを描画するために任意のコードが含まれていません知っている知っているので、彼らは本当に欠落していないが、私は一種の適切これらを描画するために開始する場所へと失われています。

    私は約考えている:任意のブロブを構成する頂点の座標かどうかをチェック

    • は海峡を描く0(最小幅または高さ)または1(最大幅または高さ)
    • に等しいです。

    誰でも持っている...スケッチの左上隅にブロブ四肢からのラインがあれば、たとえばブロブは

  • 他の多くの条件というコーナーをオーバーラップされたが、そう多くは、私は混乱していますどのように条件を注文するか、または問題にアプローチする方法のアイデア。 大いに助けてください!

  • 答えて

    0

    私の同僚は、この問題のスマートな解決策に遭遇しました。これは、元の画像のサイズを両側に1ピクセルずつ増やし、これらのピクセルを黒くすることです。 画像が100x100pxの場合、102x102pxになります。私たちの場合は黒のピクセルを追加しますが、これを行う最も良い方法は、ブロブを描画するかどうかを決定するカットオフカラーを計算し、これらの新しいボーダーピクセルを色をわずかに、またはその下/上に割り当てることです(必要に応じて)。

    enter image description here:所望の外枠線と、得られたSVG出力

    PImage ref; 
    PImage output; 
    String filename = "maptest2.jpg"; 
    
    // // // 
    
    //Here I skip some parts that are unchanged 
    
    // // // 
    
    void setup() { 
    
        size(480, 360, P3D); 
        surface.setResizable(true); 
    
        ref = loadImage(filename); 
    
        // create a copy of reference image with a black border 
        output = createImage(ref.width+2, ref.height+2, RGB); 
    
        for(int i=0; i < output.pixels.length; i++){ 
        output.pixels[i] = color(0); 
        } 
    
        output.updatePixels(); 
        output.set(1, 1, ref); 
    
        surface.setSize(output.width, output.height); 
    
        cam = new PeasyCam(this, output.width, output.height, 0, 1500); 
    

    コードは、主に、我々はインポートした画像を修正する部分を除いて私の元の質問と同じです

    これは私がこの質問をしたときに期待していた解決策ではありませんが、かなりうまく機能します。それは確かに少し完成しましたが、私が作業している他の高さマップでそれをテストしたところ、結果は一貫して満足できるものでした。

    希望すると便利です。

    0

    私は、ウィンドウの境界内に私の描画を制限する処理でよく使う方法は、最小と最大の関数です。私が書いた文であれば、不等式の数を減らすことができます。

    は、私は、私はそれはあなたに必要な出力を与える願っていますが、それはちょうどあなたの画像のエッジに沿ったエッジを描く必要があるので、それをテストしていない、あなたのループでこれを試してみてください。次のように

      eA = b.getEdgeVertexA(m); 
          eB = b.getEdgeVertexB(m); 
    
          //This part draws the blobs. 
         if (eA !=null && eB !=null){ 
          float x1 = eA.x*img.width; 
          float y1 = eA.y*img.height; 
          float x2 = eB.x*img.width; 
          float y2 = eB.y*img.height; 
    
          x1 = min(max(0,x1),WIDTH); 
          y1 = min(max(0,y1),HEIGHT); 
          x2 = min(max(0,x2),WIDTH); 
          y2 = min(max(0,y2),HEIGHT); 
    
    
          line(x1, y1, x2, y2); 
    
          println("eA.x: " + eA.x + " x1: " + x1); 
          println("eA.y: " + eA.y + " y1: " + y1); 
          println("eB.x: " + eB.x + " x2: " + x2); 
          println("eB.y: " + eB.y + " y2: " + y2); 
          println(); 
         } 
    

    ロジックは次のとおりです。min(max(0,x1),WIDTH)

    まず我々はmax(0,x1)はそう、我々はそれが0

    への負の設定をされている場合は、私たちが取る、x1が0より大きいことを確認作っている見つけます前回の演算の結果とそのmin(result,WIDTH)を次のようにしますが、我々は結果が> = 0であることを知って、両者の間の最小数を見つけようとしている、と数がより大きいので、もしウィンドウの幅は、> = 1でありますウィンドウの幅は、ウィンドウの幅に制限されます。

    0WIDTHの間の数値になります。元の値がすでにその制約内にあった場合、修正されません。これは、ウィンドウの外側に描画されるエッジを描画します。試してみて、それが動作すれば教えてください!

    +0

    コードをそのまま試してみましたが、うまくいきませんでした。少し修正してもう一度試してみますが、私は本当に必要なものではないと思います。私が理解するところでは、コードがスケッチの端を越えているかどうかをチェックしますが、高さマップイメージファイルから始めるので、境界線はイメージであり、ブロブは想像力の中でしかエッジを超えません。したがって、実際には、ブロブが完全(閉じていない)かどうかをチェックし、スケッチの端に沿って閉じる必要があります。 – LaVielle

    関連する問題