2017-01-10 57 views
1

我正在使用blobDetection library处理从高度图制作等高线图。我的最终目标是激光切割斑点以制作某种建筑景观maquettes。识别处理中的特定Blob

enter image description here

目前我能获得的轮廓和出口等值线图的SVG这是伟大的,但我希望能够找出每个斑(或轮廓,或环),并随后能够操纵每个轮廓分开。也就是说,我想将它们重新放置在窗口上,这样它们就不会彼此重叠,也不会重叠。我也想给每个blob分配坐标,这样他们就很容易知道激光切割后每个blob的位置。

下面是代码(由作者v3ga提供一个例子):

import processing.svg.*; 
import blobDetection.*; 
import peasy.*; 
import processing.pdf.*; 

PeasyCam cam; 
PImage img; 

float levels = 10; 
float factor = 10; 
float elevation = 125; 

float colorStart = 0; 
float colorRange = 160; 

BlobDetection[] contours = new BlobDetection[int(levels)]; 

boolean recording = false; 
void keyPressed(){ 
    if (key == 'r' || key == 'R'){ 
    recording = !recording; 
    } 
} 

void setup() { 

    size(1000,800,P3D); 
    surface.setResizable(true); 

    img = loadImage("map1.gif"); 
    surface.setSize(img.width, img.height); 

    cam = new PeasyCam(this, img.width, img.height, 0, 500); 
    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); 
    } 

} 

void draw(){ 

    if (recording){ 
    beginRecord(SVG, "frame_####.svg"); 
    } 

    for (int i=0; i<levels; i++){ 
    drawContours(i); 
    } 

    if (recording) { 
    endRecord(); 
    recording = false; 
    } 

} 

void drawContours(int i) { 
    Blob b; 
    EdgeVertex eA,eB; 
    for (int n=0 ; n<contours[i].getBlobNb() ; n++) { 
    b=contours[i].getBlob(n); 
    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 
      ); 
     } 
    } 
    } 
} 

测试的几件事情后,我认为最好是创建并包含信息为每个斑点的对象的阵列(x和y坐标,水平)并在drawContours方法中填充该数组。然而,我很难获得正确的信息来存储在这个数组中。

所以我的问题是:

  • 如何确定X,复杂形状的y坐标,例如这些斑点
  • 如何重新定位斑点一旦我有他们的信息储存在一个数组

任何建议,即使使用其他技术(即不处理)将不胜感激。

+0

你想要看到他们堆叠在3D中? blob对象具有可以访问的x和y属性,我可以想象这个级别只会等于数组中的blob索引。 –

回答

0

要显示的斑点在3D顶部添加height_scale常数和修改drawContours功能如下:

final int HEIGHT_SCALE = 10; // amount of z space between each blob 

void drawContours(int i) { 
    Blob b; 
    EdgeVertex eA,eB; 
    for (int n=0 ; n<contours[i].getBlobNb() ; n++) { 
    b=contours[i].getBlob(n); 
    if (b!=null) { 
     stroke(250,75,90); 
     beginShape(); 
     for (int m=0;m<b.getEdgeNb();m++) { 
     eA = b.getEdgeVertexA(m); 
     eB = b.getEdgeVertexB(m); 
     if (eA !=null && eB !=null) 
      vertex(eA.x*img.width, eA.y*img.height, i*HEIGHT_SCALE); 
      vertex(eB.x*img.width, eB.y*img.height, i*HEIGHT_SCALE); 
     } 
     endShape(CLOSE); 
    } 
    } 
} 

记住我还没有运行该代码,我没有用过你使用的框架,然而beginShape(),vertex()和endShape()函数应该允许你在边之间创建相同的线,并且我向顶点添加了z坐标,以便它们在高度上分开。

刚刚意识到你也可以只用下面的,因为线(X1,Y1,X2,Y2)也可以采取线(X1,Y1,Z1,X2,Y2,Z2)去:

final int HEIGHT_SCALE = 10; // amount of z space between each blob 

void drawContours(int i) { 
    Blob b; 
    EdgeVertex eA,eB; 
    for (int n=0 ; n<contours[i].getBlobNb() ; n++) { 
    b=contours[i].getBlob(n); 
    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, i*HEIGHT_SCALE, eB.x*img.width, eB.y*img.height, i*HEIGHT_SCALE); 
     } 
    } 
    } 
} 
+0

我省略了原始示例的某些部分,因为我不需要它们用于此项目,但是可以通过翻译等高线“translate(0,0,高程/等级)”来呈现3D地图;“in调用'drawContours()'的循环(使用在程序开始处声明的变量)。 – LaVielle

+0

所以你只是想知道如何创建一个自定义对象来保存你的blob?并将它们存储在数组中? –

+0

是的。我在创建对象时没有问题,但是我可以通过获取正确的数据来为对象提供属性。我想获得的属性是blob的x和y坐标,最重要的是,然后是它的级别,就像它的高度相对于maquette的总高度一样。 – LaVielle