algorithm - Binary Image "Lines-of-Sight" Edge Detection -


consider binary image: enter image description here

a normal edge detection algorithm (like canny) takes binary image input , results contour shown in red. need algorithm takes point "p" second piece of input data. "p" black point in previous image. algorithm should result blue contour. blue contours represents point "p" lines-of-sight edge of binary image.

i searched lot of image processing algorithm achieve this, didn't find any. tried think new one, still have lot of difficulties.

since you've got bitmap, use bitmap algorithm.

here's working example (in jsfiddle or see below). (firefox, chrome, not ie)

pseudocode:

// part 1: occlusion mark pixels 'outside' each pixel on edge of image     draw line source pixel edge pixel ,     each pixel on line starting source , ending edge         if pixel gray mark 'inside'         otherwise stop drawing line  // part 2: edge finding each pixel in image     if pixel not marked 'inside' skip pixel     if pixel has neighbor outside mark pixel 'edge'  // part 3: draw edges highlight edges 

at first sounds pretty terrible... really, it's o(p) p number of pixels in image.

full code here, works best full page:

var c = document.getelementbyid('c');  c.width = c.height = 500;  var x = c.getcontext("2d");    //////////// draw "interesting" stuff ////////////  function drawscene() {      x.beginpath();      x.rect(0, 0, c.width, c.height);      x.fillstyle = '#fff';      x.fill();        x.beginpath();      x.rect(c.width * 0.1, c.height * 0.1, c.width * 0.8, c.height * 0.8);      x.fillstyle = '#000';      x.fill();            x.beginpath();      x.rect(c.width * 0.25, c.height * 0.02 , c.width * 0.5, c.height * 0.05);      x.fillstyle = '#000';      x.fill();        x.beginpath();      x.rect(c.width * 0.3, c.height * 0.2, c.width * 0.03, c.height * 0.4);      x.fillstyle = '#fff';      x.fill();        x.beginpath();      var maxang = 2.0;      function sc(t) { return t * 0.3 + 0.5; }      function sc2(t) { return t * 0.35 + 0.5; }      (var = 0; < maxang; += 0.1)          x.lineto(sc(math.cos(i)) * c.width, sc(math.sin(i)) * c.height);      (var = maxang; >= 0; -= 0.1)          x.lineto(sc2(math.cos(i)) * c.width, sc2(math.sin(i)) * c.height);      x.closepath();      x.fill();        x.beginpath();      x.moveto(0.2 * c.width, 0.03 * c.height);      x.lineto(c.width * 0.9, c.height * 0.8);      x.lineto(c.width * 0.8, c.height * 0.8);      x.lineto(c.width * 0.1, 0.03 * c.height);      x.closepath();      x.fillstyle = '#000';      x.fill();  }    //////////// pick point start our operations: ////////////  var v_x = math.round(c.width * 0.5);  var v_y = math.round(c.height * 0.5);    function update() {      if (navigator.appname == 'microsoft internet explorer'          ||  !!(navigator.useragent.match(/trident/)          || navigator.useragent.match(/rv 11/))          || $.browser.msie == 1)      {          document.getelementbyid("d").innerhtml = "does not work in ie.";          return;      }            drawscene();        //////////// make our image binary (white , gray) ////////////      var id = x.getimagedata(0, 0, c.width, c.height);      (var = 0; < id.width * id.height * 4; += 4) {          id.data[i + 0] = id.data[i + 0] > 128 ? 255 : 64;          id.data[i + 1] = id.data[i + 1] > 128 ? 255 : 64;          id.data[i + 2] = id.data[i + 2] > 128 ? 255 : 64;      }        // adapted http://rosettacode.org/wiki/bitmap/bresenham's_line_algorithm#javascript      function line(x1, y1) {          var x0 = v_x;          var y0 = v_y;          var dx = math.abs(x1 - x0), sx = x0 < x1 ? 1 : -1;          var dy = math.abs(y1 - y0), sy = y0 < y1 ? 1 : -1;           var err = (dx>dy ? dx : -dy)/2;            while (true) {              var d = (y0 * c.height + x0) * 4;              if (id.data[d] === 255) break;              id.data[d] = 128;              id.data[d + 1] = 128;              id.data[d + 2] = 128;                if (x0 === x1 && y0 === y1) break;              var e2 = err;              if (e2 > -dx) { err -= dy; x0 += sx; }              if (e2 < dy) { err += dx; y0 += sy; }          }      }        (var = 0; < c.width; i++) line(i, 0);      (var = 0; < c.width; i++) line(i, c.height - 1);      (var = 0; < c.height; i++) line(0, i);      (var = 0; < c.height; i++) line(c.width - 1, i);            // outline-finding algorithm      function gb(x, y) {          var v = id.data[(y * id.height + x) * 4];          return v !== 128 && v !== 0;      }      (var y = 0; y < id.height; y++) {          var py = math.max(y - 1, 0);          var ny = math.min(y + 1, id.height - 1);                      console.log(y);            (var z = 0; z < id.width; z++) {              var d = (y * id.height + z) * 4;              if (id.data[d] !== 128) continue;              var pz = math.max(z - 1, 0);              var nz = math.min(z + 1, id.width - 1);              if (gb(pz, py) || gb(z, py) || gb(nz, py) ||                  gb(pz, y) || gb(z, y) || gb(nz, y) ||                  gb(pz, ny) || gb(z, ny) || gb(nz, ny)) {                  id.data[d + 0] = 0;                  id.data[d + 1] = 0;                  id.data[d + 2] = 255;              }          }      }        x.putimagedata(id, 0, 0);        // draw starting point      x.beginpath();      x.arc(v_x, v_y, c.width * 0.01, 0, 2 * math.pi, false);      x.fillstyle = '#800';      x.fill();  }    update();    c.addeventlistener('click', function(evt) {      var x = evt.pagex - c.offsetleft,          y = evt.pagey - c.offsettop;      v_x = x;      v_y = y;      update();  }, false);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>  <center><div id="d">click on image change point</div>  <canvas id="c"></canvas></center>


Comments

Popular posts from this blog

c# - Validate object ID from GET to POST -

node.js - Custom Model Validator SailsJS -

php - Find a regex to take part of Email -