Box to Polygon (Using GrabCut)

Grabcut

Learn more from OpenCV and JS specific.

Video

Correction Example

Video Use Case Combination Example

Examples

Draw a box - get the specific polygon:

377377 311311 286286

Code - Search Box to Polygon to use this in Diffgram.

The example is already loaded. Search Box to Polygon

855855

We are aware that the first instance created in a new file sometimes fails.

Feel free to adjust the epsilon multiplier to get more/less polygon points.

create_instance: function (data){
  let ghost_canvas = diffgram.get_new_canvas()
  let instance = {...data[0]}

  let roi_canvas = diffgram.get_roi_canvas_from_instance(
    instance,
    ghost_canvas)
    
    let src = cv.imread(roi_canvas);
  
    cv.cvtColor(src, src, cv.COLOR_RGBA2RGB, 0);
    let mask = new cv.Mat();
    let bgdModel = new cv.Mat();
    let fgdModel = new cv.Mat();

    let rect = new cv.Rect(1, 1, 
                           instance.width - 2, 
                           instance.height -2 );    // must be smaller then canvas

    cv.grabCut(src, 
               mask, 
               rect, bgdModel, 
               fgdModel, 
               5,
               cv.GC_INIT_WITH_RECT);

    // convert to binary where 0 is bad and 1 is good
    // 0 is already good, otherwise we go through here
    for (let i = 0; i < src.rows; i++) {
        for (let j = 0; j < src.cols; j++) {
            if (mask.ucharPtr(i, j)[0] == 2) {
              mask.ucharPtr(i, j)[0] = 0
            }
        }
    }

    var hierarchy = new cv.Mat()
    var contours = new cv.MatVector()
    cv.findContours(mask, contours, hierarchy, 
                    cv.RETR_CCOMP, 
                    cv.CHAIN_APPROX_SIMPLE);

    let contour = contours.get(0)
    if (!contour) { return }

    let epsilon = 0.005 * cv.arcLength(contour,true)
    let tmp = new cv.Mat();

    cv.approxPolyDP(contour, tmp, epsilon, true);
    polypoints = tmp.data32S
    
    let offset_x = instance.x_min
    let offset_y = instance.y_min

    let points_list = []
    for (let i = 0; i < polypoints.length; i++) {
      if (i % 2 != 0) {continue}
      let x = polypoints[i] + offset_x
      let y = polypoints[i + 1] + offset_y
      points_list.push({'x' : x, 'y' : y})
    }
    diffgram.create_polygon(points_list)
    // https://github.com/opencv/opencv/issues/16162
    
}

NPM Requires

https://cdn.jsdelivr.net/npm/@tensorflow/[email protected]/dist/tf.min.js
https://docs.opencv.org/master/opencv.js