Draw blob edges that are on edge of sketch

edited January 2017 in Library Questions

Hi, I've been working at making contour maps using the blobDetection library; everything has gone fine till here, I can get the contours and everything.

Now I am exporting each layer as an SVG and I see that the four edges of the sketch are always blank. In other words, I want blobs that go over the edge of the sketch to have strokes joining both sides of that blob, instead of having sort of an "incomplete blob".

Here is the code:

import processing.svg.*;

import blobDetection.*;
import peasy.*;
import processing.pdf.*;
PeasyCam cam;

PImage img;

float levels = 3;
//float factor = 1;      //Scale factor, not used.
//float elevation = 50;  //Not used.

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("map1.gif");
  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");
    }

  }


}

void drawContours(int i) {
  Blob b;
  EdgeVertex eA, eB;
  for (int n=0; n<contours[i].getBlobNb(); n++) {
    b=contours[i].getBlob(n);

    if (n==0){
      b2 = b;
    }
    else {
      b2 = contours[i].getBlob(n-1);
    }

    //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);

          if (eA !=null && eB !=null)
           line(
           eA.x*img.width, eA.y*img.height, 
           eB.x*img.width, eB.y*img.height 
           );

           // // // // // //

           /*
           *Here is where I attempt to test if an EdgeVertex is touching any border of the sketch
           *Note: x and y are properties of the blob object and are scaled from 0 to 1. So I test
           *if x or y equal 0 or 1.
           *Note: For testing simplicity, I check only for x=0 in this code
           */

           if (b.getEdgeVertexA(m).x == 0 && b.getEdgeVertexB(b.getEdgeNb()).x == 0){

                 line(  eA.x*img.width, eA.y*img.height, 
                        eB.x*img.width, eB.y*img.height   );

                 println("////");
                 println("making line");
                 println("////");
           }

           // // // // // //

        }

        //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));

        }
    }
  }
}

Just to reemphasize what I write as a comment in the code: I am trying to check if any vertex of the blob has coordinates that touch the borders of the sketch. Ideally, if that condition is met, the program should draw lines that would join each edge of the blob. I am not there yet... so if you have any suggestions, comments on my code, etc. I'd be glad to hear.

Thanks

Answers

  • The problem of blob over the edges is how to join them? Clockwise or counterclockwise? How would an algorithm know?

    Since a blob at the edge wouldn't know how to connect two points, I suggest joining them on both directions. In other words, creating an edge at the border of your image.

    Add the following code at line 26 and see if that could do the trick:

      PGraphics pg = createGraphics(img.width, img.height);
      pg.beginDraw();
      pg.image(img,0,0);
      pg.stroke(0);
      pg.strokeWeight(2);
      pg.noFill();
      pg.rect(1,1,img.width-1, img.height-1);
      pg.endDraw();
      img=pg.get();
    

    I also typed the Ring class as it was missing in your code:

    class Ring {
      String id; 
      int lvl;
      double x;
      double y;
    
      Ring(String _id, int _lvl, double _x, double _y) {
        id=_id;
        lvl=_lvl;
        x=_x;
        y=_y;
      }
    
      String getId(){
        return id;
      }
    
      int getLvl() {
        return lvl;
      }
      double getX() {
        return x;
      }
      double getY() {
        return y;
      }
    }
    

    Last, blob b2 was not define in your code. I added the following code at line 15: Blob b2;

    I hope this idea helps.

    Kf

Sign In or Register to comment.