<html>
<body>
<canvas id="canvas" width="600" height="450" style="float:left"></canvas>
<canvas id="out" width="600" height="450" style="float:left"></canvas>
<script>
let img = new Image();
img.src = 'lines1.png';
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let out = document.getElementById('out');
let ctxOut = out.getContext('2d');
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
let start = new Date();
drawRanges();
let end = new Date();
console.log('time', end.getTime() - start.getTime());
};
function rangeLen(range) {
return Math.sqrt(
(range.x2 - range.x1) * (range.x2 - range.x1) +
(range.y2 - range.y1) * (range.y2 - range.y1)
);
};
let unique = (array) => {
return Array.from(new Set(array));
};
let merge = (arrays) => {
return [].concat.apply([], arrays);
};
let rangeOverlap = (min1, max1, min2, max2) => {
if (min1 > max1 || min2 > max2) {
throw new Error("Invalid range");
}
if (max2 <= min1 || min2 >= max1) {
return 0;
}
if (min1 <= min2 && max1 >= max2) {
return max2 - min2;
}
if (min1 >= min2 && max1 <= max2) {
return max1 - min1;
}
if (min1 >= min2 && max1 >= max2 && max2 >= min1) {
return max2 - min1;
}
if (min1 <= min2 && max1 >= min2 && max2 >= max1) {
return max1 - min2;
}
return 0;
};
let rangeCollidesWithRanges = (range, ranges) => {
let results = [];
for (var i = 0; i < ranges.length; i++) {
let overlap = rangeOverlap(range.x1, range.x2, ranges[i].x1, ranges[i].x2);
if (overlap > 0) {
results.push(ranges[i]);
}
}
return results;
};
function getRanges(data, width, height) {
let inRange = false;
let ranges = [];
let range = null;
let prevRowRanges = [];
let rowRanges = [];
let bodies = [];
let cnt = 0;
let startRange = (x, y) => {
return {
x1: x,
y1: y,
x2: 0,
y2: 0
};
};
let endRange = (range, x, y) => {
range.x2 = x;
range.y2 = y;
ranges.push(range);
rowRanges.push(range);
let cols = rangeCollidesWithRanges(range, prevRowRanges);
if (cols.length == 0) {
range.bodies = [cnt];
bodies.push(cnt);
cnt += 1;
} else {
range.bodies = unique(merge(cols.map((col) => col.bodies)));
}
return null;
};
let doPixel = (x, y, r, g, b, a) => {
// pixel filter here
inRange = r < 200;
if (inRange) {
if (!range) {
range = startRange(x, y);
}
} else {
if (range) {
range = endRange(range, x, y);
}
}
if (y + 1 == height) {
if (range) {
range = endRange(range, x, y);
}
}
};
for (let y = 0; y < height; y += 1) {
prevRowRanges = rowRanges;
rowRanges = [];
for (let x = 0; x < width; x += 1) {
let p = (y * width * 4) + (x * 4);
doPixel(x, y, data[p], data[p + 1], data[p + 2], data[p + 3]);
}
}
return {
ranges: ranges,
bodies: bodies
};
}
function drawRange(ctx, range) {
ctx.beginPath();
ctx.moveTo(range.x1, range.y1);
ctx.lineTo(range.x2, range.y2);
ctx.stroke();
}
function circle(ctx, x,y,r)
{
ctxOut.beginPath();
ctxOut.strokeStyle = 'black';
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctxOut.stroke();
}
function drawRanges() {
let width = canvas.width;
let height = canvas.height;
let data = ctx.getImageData(0, 0, width, height);
let rangesAndBodies = getRanges(data.data, data.width, data.height);
let ranges = rangesAndBodies.ranges;
let bodies = rangesAndBodies.bodies;
let colors = ['red', 'yellow', 'green', 'magenta', 'teal', 'purple', 'blue', 'navy', 'orange'];
//console.log('ranges', rangesAndBodies);
ctxOut.lineWidth = 1;
for (var i = 0; i < bodies.length; i++) {
var b = bodies[i];
let bodyRanges = ranges.filter((range) => {
return range.bodies.indexOf(b) >= 0;
});
ctxOut.strokeStyle = colors[i % colors.length];
bodyRanges.forEach(function(range, i) {
drawRange(ctxOut, range);
});
let minXy = bodyRanges.reduce(function(r1, r2) {
return (r1.x1 < r2.x1 ? r1 : r2);
});
let minYx = bodyRanges.reduce(function(r1, r2) {
return (r1.y1 < r2.y1 ? r1 : r2);
});
let maxXy = bodyRanges.reduce(function(r1, r2) {
return (r1.x2 > r2.x2 ? r1 : r2);
});
let maxYx = bodyRanges.reduce(function(r1, r2) {
return (r1.y2 > r2.y2 ? r1 : r2);
});
circle(ctxOut, minXy.x1,minXy.y1, 3);
circle(ctxOut, minYx.x1,minYx.y1, 3);
circle(ctxOut, maxXy.x2,maxXy.y2, 3);
circle(ctxOut, maxYx.x2,maxYx.y2, 3);
//console.log('rect', minX,minY,maxX-minX,maxY-minY);
ctxOut.beginPath();
ctxOut.strokeStyle = colors[(i + 2) % colors.length];
ctxOut.rect(minXy.x1, minYx.y1, maxXy.x2 - minXy.x1, maxYx.y2 - minYx.y1);
ctxOut.stroke();
}
}
</script>
</body>
</html>
75000cookie-checkBasic Image recognition (Javascript)