|
|
@ -65,7 +65,8 @@ CVUtils.computeIntegralImage2 = function(imageWrapper, integralWrapper) {
|
|
|
|
posC = y * width;
|
|
|
|
posC = y * width;
|
|
|
|
posD = (y - 1) * width;
|
|
|
|
posD = (y - 1) * width;
|
|
|
|
for ( x = 1; x < width; x++) {
|
|
|
|
for ( x = 1; x < width; x++) {
|
|
|
|
integralImageData[posA] += imageData[posA] + integralImageData[posB] + integralImageData[posC] - integralImageData[posD];
|
|
|
|
integralImageData[posA] +=
|
|
|
|
|
|
|
|
imageData[posA] + integralImageData[posB] + integralImageData[posC] - integralImageData[posD];
|
|
|
|
posA++;
|
|
|
|
posA++;
|
|
|
|
posB++;
|
|
|
|
posB++;
|
|
|
|
posC++;
|
|
|
|
posC++;
|
|
|
@ -247,12 +248,12 @@ CVUtils.cluster = function(points, threshold, property) {
|
|
|
|
property = "rad";
|
|
|
|
property = "rad";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function addToCluster(point) {
|
|
|
|
function addToCluster(newPoint) {
|
|
|
|
var found = false;
|
|
|
|
var found = false;
|
|
|
|
for ( k = 0; k < clusters.length; k++) {
|
|
|
|
for ( k = 0; k < clusters.length; k++) {
|
|
|
|
cluster = clusters[k];
|
|
|
|
cluster = clusters[k];
|
|
|
|
if (cluster.fits(point)) {
|
|
|
|
if (cluster.fits(newPoint)) {
|
|
|
|
cluster.add(point);
|
|
|
|
cluster.add(newPoint);
|
|
|
|
found = true;
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -266,9 +267,7 @@ CVUtils.cluster = function(points, threshold, property) {
|
|
|
|
clusters.push(Cluster2.create(point, threshold));
|
|
|
|
clusters.push(Cluster2.create(point, threshold));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return clusters;
|
|
|
|
return clusters;
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
CVUtils.Tracer = {
|
|
|
|
CVUtils.Tracer = {
|
|
|
@ -279,7 +278,10 @@ CVUtils.Tracer = {
|
|
|
|
var from, to, toIdx, predictedPos, thresholdX = 1, thresholdY = Math.abs(vec[1] / 10), found = false;
|
|
|
|
var from, to, toIdx, predictedPos, thresholdX = 1, thresholdY = Math.abs(vec[1] / 10), found = false;
|
|
|
|
|
|
|
|
|
|
|
|
function match(pos, predicted) {
|
|
|
|
function match(pos, predicted) {
|
|
|
|
if (pos.x > (predicted.x - thresholdX) && pos.x < (predicted.x + thresholdX) && pos.y > (predicted.y - thresholdY) && pos.y < (predicted.y + thresholdY)) {
|
|
|
|
if (pos.x > (predicted.x - thresholdX)
|
|
|
|
|
|
|
|
&& pos.x < (predicted.x + thresholdX)
|
|
|
|
|
|
|
|
&& pos.y > (predicted.y - thresholdY)
|
|
|
|
|
|
|
|
&& pos.y < (predicted.y + thresholdY)) {
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
@ -334,9 +336,7 @@ CVUtils.Tracer = {
|
|
|
|
result = top;
|
|
|
|
result = top;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
@ -344,7 +344,17 @@ CVUtils.DILATE = 1;
|
|
|
|
CVUtils.ERODE = 2;
|
|
|
|
CVUtils.ERODE = 2;
|
|
|
|
|
|
|
|
|
|
|
|
CVUtils.dilate = function(inImageWrapper, outImageWrapper) {
|
|
|
|
CVUtils.dilate = function(inImageWrapper, outImageWrapper) {
|
|
|
|
var v, u, inImageData = inImageWrapper.data, outImageData = outImageWrapper.data, height = inImageWrapper.size.y, width = inImageWrapper.size.x, sum, yStart1, yStart2, xStart1, xStart2;
|
|
|
|
var v,
|
|
|
|
|
|
|
|
u,
|
|
|
|
|
|
|
|
inImageData = inImageWrapper.data,
|
|
|
|
|
|
|
|
outImageData = outImageWrapper.data,
|
|
|
|
|
|
|
|
height = inImageWrapper.size.y,
|
|
|
|
|
|
|
|
width = inImageWrapper.size.x,
|
|
|
|
|
|
|
|
sum,
|
|
|
|
|
|
|
|
yStart1,
|
|
|
|
|
|
|
|
yStart2,
|
|
|
|
|
|
|
|
xStart1,
|
|
|
|
|
|
|
|
xStart2;
|
|
|
|
|
|
|
|
|
|
|
|
for ( v = 1; v < height - 1; v++) {
|
|
|
|
for ( v = 1; v < height - 1; v++) {
|
|
|
|
for ( u = 1; u < width - 1; u++) {
|
|
|
|
for ( u = 1; u < width - 1; u++) {
|
|
|
@ -352,17 +362,26 @@ CVUtils.dilate = function(inImageWrapper, outImageWrapper) {
|
|
|
|
yStart2 = v + 1;
|
|
|
|
yStart2 = v + 1;
|
|
|
|
xStart1 = u - 1;
|
|
|
|
xStart1 = u - 1;
|
|
|
|
xStart2 = u + 1;
|
|
|
|
xStart2 = u + 1;
|
|
|
|
sum = inImageData[yStart1 * width + xStart1]/* + inImageData[yStart1*width+u] */ + inImageData[yStart1 * width + xStart2] +
|
|
|
|
sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] +
|
|
|
|
/* inImageData[v*width+xStart1] + */
|
|
|
|
inImageData[v * width + u] +
|
|
|
|
inImageData[v * width + u] + /* inImageData[v*width+xStart2] +*/
|
|
|
|
inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2];
|
|
|
|
inImageData[yStart2 * width + xStart1]/* + inImageData[yStart2*width+u]*/ + inImageData[yStart2 * width + xStart2];
|
|
|
|
|
|
|
|
outImageData[v * width + u] = sum > 0 ? 1 : 0;
|
|
|
|
outImageData[v * width + u] = sum > 0 ? 1 : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
CVUtils.erode = function(inImageWrapper, outImageWrapper) {
|
|
|
|
CVUtils.erode = function(inImageWrapper, outImageWrapper) {
|
|
|
|
var v, u, inImageData = inImageWrapper.data, outImageData = outImageWrapper.data, height = inImageWrapper.size.y, width = inImageWrapper.size.x, sum, yStart1, yStart2, xStart1, xStart2;
|
|
|
|
var v,
|
|
|
|
|
|
|
|
u,
|
|
|
|
|
|
|
|
inImageData = inImageWrapper.data,
|
|
|
|
|
|
|
|
outImageData = outImageWrapper.data,
|
|
|
|
|
|
|
|
height = inImageWrapper.size.y,
|
|
|
|
|
|
|
|
width = inImageWrapper.size.x,
|
|
|
|
|
|
|
|
sum,
|
|
|
|
|
|
|
|
yStart1,
|
|
|
|
|
|
|
|
yStart2,
|
|
|
|
|
|
|
|
xStart1,
|
|
|
|
|
|
|
|
xStart2;
|
|
|
|
|
|
|
|
|
|
|
|
for ( v = 1; v < height - 1; v++) {
|
|
|
|
for ( v = 1; v < height - 1; v++) {
|
|
|
|
for ( u = 1; u < width - 1; u++) {
|
|
|
|
for ( u = 1; u < width - 1; u++) {
|
|
|
@ -370,10 +389,9 @@ CVUtils.erode = function(inImageWrapper, outImageWrapper) {
|
|
|
|
yStart2 = v + 1;
|
|
|
|
yStart2 = v + 1;
|
|
|
|
xStart1 = u - 1;
|
|
|
|
xStart1 = u - 1;
|
|
|
|
xStart2 = u + 1;
|
|
|
|
xStart2 = u + 1;
|
|
|
|
sum = inImageData[yStart1 * width + xStart1]/* + inImageData[yStart1*width+u] */ + inImageData[yStart1 * width + xStart2] +
|
|
|
|
sum = inImageData[yStart1 * width + xStart1] + inImageData[yStart1 * width + xStart2] +
|
|
|
|
/* inImageData[v*width+xStart1] + */
|
|
|
|
inImageData[v * width + u] +
|
|
|
|
inImageData[v * width + u] + /* inImageData[v*width+xStart2] +*/
|
|
|
|
inImageData[yStart2 * width + xStart1] + inImageData[yStart2 * width + xStart2];
|
|
|
|
inImageData[yStart2 * width + xStart1]/* + inImageData[yStart2*width+u]*/ + inImageData[yStart2 * width + xStart2];
|
|
|
|
|
|
|
|
outImageData[v * width + u] = sum === 5 ? 1 : 0;
|
|
|
|
outImageData[v * width + u] = sum === 5 ? 1 : 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -383,7 +401,10 @@ CVUtils.subtract = function(aImageWrapper, bImageWrapper, resultImageWrapper) {
|
|
|
|
if (!resultImageWrapper) {
|
|
|
|
if (!resultImageWrapper) {
|
|
|
|
resultImageWrapper = aImageWrapper;
|
|
|
|
resultImageWrapper = aImageWrapper;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var length = aImageWrapper.data.length, aImageData = aImageWrapper.data, bImageData = bImageWrapper.data, cImageData = resultImageWrapper.data;
|
|
|
|
var length = aImageWrapper.data.length,
|
|
|
|
|
|
|
|
aImageData = aImageWrapper.data,
|
|
|
|
|
|
|
|
bImageData = bImageWrapper.data,
|
|
|
|
|
|
|
|
cImageData = resultImageWrapper.data;
|
|
|
|
|
|
|
|
|
|
|
|
while (length--) {
|
|
|
|
while (length--) {
|
|
|
|
cImageData[length] = aImageData[length] - bImageData[length];
|
|
|
|
cImageData[length] = aImageData[length] - bImageData[length];
|
|
|
@ -394,7 +415,10 @@ CVUtils.bitwiseOr = function(aImageWrapper, bImageWrapper, resultImageWrapper) {
|
|
|
|
if (!resultImageWrapper) {
|
|
|
|
if (!resultImageWrapper) {
|
|
|
|
resultImageWrapper = aImageWrapper;
|
|
|
|
resultImageWrapper = aImageWrapper;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var length = aImageWrapper.data.length, aImageData = aImageWrapper.data, bImageData = bImageWrapper.data, cImageData = resultImageWrapper.data;
|
|
|
|
var length = aImageWrapper.data.length,
|
|
|
|
|
|
|
|
aImageData = aImageWrapper.data,
|
|
|
|
|
|
|
|
bImageData = bImageWrapper.data,
|
|
|
|
|
|
|
|
cImageData = resultImageWrapper.data;
|
|
|
|
|
|
|
|
|
|
|
|
while (length--) {
|
|
|
|
while (length--) {
|
|
|
|
cImageData[length] = aImageData[length] || bImageData[length];
|
|
|
|
cImageData[length] = aImageData[length] || bImageData[length];
|
|
|
@ -461,7 +485,19 @@ CVUtils.grayAndHalfSampleFromCanvasData = function(canvasData, size, outArray) {
|
|
|
|
|
|
|
|
|
|
|
|
while (bottomRowIdx < endIdx) {
|
|
|
|
while (bottomRowIdx < endIdx) {
|
|
|
|
for ( i = 0; i < outWidth; i++) {
|
|
|
|
for ( i = 0; i < outWidth; i++) {
|
|
|
|
outArray[outImgIdx] = Math.floor(((0.299 * canvasData[topRowIdx * 4 + 0] + 0.587 * canvasData[topRowIdx * 4 + 1] + 0.114 * canvasData[topRowIdx * 4 + 2]) + (0.299 * canvasData[(topRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(topRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(topRowIdx + 1) * 4 + 2]) + (0.299 * canvasData[(bottomRowIdx) * 4 + 0] + 0.587 * canvasData[(bottomRowIdx) * 4 + 1] + 0.114 * canvasData[(bottomRowIdx) * 4 + 2]) + (0.299 * canvasData[(bottomRowIdx + 1) * 4 + 0] + 0.587 * canvasData[(bottomRowIdx + 1) * 4 + 1] + 0.114 * canvasData[(bottomRowIdx + 1) * 4 + 2])) / 4);
|
|
|
|
outArray[outImgIdx] = Math.floor((
|
|
|
|
|
|
|
|
(0.299 * canvasData[topRowIdx * 4 + 0] +
|
|
|
|
|
|
|
|
0.587 * canvasData[topRowIdx * 4 + 1] +
|
|
|
|
|
|
|
|
0.114 * canvasData[topRowIdx * 4 + 2]) +
|
|
|
|
|
|
|
|
(0.299 * canvasData[(topRowIdx + 1) * 4 + 0] +
|
|
|
|
|
|
|
|
0.587 * canvasData[(topRowIdx + 1) * 4 + 1] +
|
|
|
|
|
|
|
|
0.114 * canvasData[(topRowIdx + 1) * 4 + 2]) +
|
|
|
|
|
|
|
|
(0.299 * canvasData[(bottomRowIdx) * 4 + 0] +
|
|
|
|
|
|
|
|
0.587 * canvasData[(bottomRowIdx) * 4 + 1] +
|
|
|
|
|
|
|
|
0.114 * canvasData[(bottomRowIdx) * 4 + 2]) +
|
|
|
|
|
|
|
|
(0.299 * canvasData[(bottomRowIdx + 1) * 4 + 0] +
|
|
|
|
|
|
|
|
0.587 * canvasData[(bottomRowIdx + 1) * 4 + 1] +
|
|
|
|
|
|
|
|
0.114 * canvasData[(bottomRowIdx + 1) * 4 + 2])) / 4);
|
|
|
|
outImgIdx++;
|
|
|
|
outImgIdx++;
|
|
|
|
topRowIdx = topRowIdx + 2;
|
|
|
|
topRowIdx = topRowIdx + 2;
|
|
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
|
@ -469,7 +505,6 @@ CVUtils.grayAndHalfSampleFromCanvasData = function(canvasData, size, outArray) {
|
|
|
|
topRowIdx = topRowIdx + inWidth;
|
|
|
|
topRowIdx = topRowIdx + inWidth;
|
|
|
|
bottomRowIdx = bottomRowIdx + inWidth;
|
|
|
|
bottomRowIdx = bottomRowIdx + inWidth;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
CVUtils.computeGray = function(imageData, outArray, config) {
|
|
|
|
CVUtils.computeGray = function(imageData, outArray, config) {
|
|
|
@ -483,14 +518,16 @@ CVUtils.computeGray = function(imageData, outArray, config) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
for (i = 0; i < l; i++) {
|
|
|
|
for (i = 0; i < l; i++) {
|
|
|
|
outArray[i] = Math.floor(0.299 * imageData[i * 4 + 0] + 0.587 * imageData[i * 4 + 1] + 0.114 * imageData[i * 4 + 2]);
|
|
|
|
outArray[i] = Math.floor(
|
|
|
|
|
|
|
|
0.299 * imageData[i * 4 + 0] + 0.587 * imageData[i * 4 + 1] + 0.114 * imageData[i * 4 + 2]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
CVUtils.loadImageArray = function(src, callback, canvas) {
|
|
|
|
CVUtils.loadImageArray = function(src, callback, canvas) {
|
|
|
|
if (!canvas)
|
|
|
|
if (!canvas) {
|
|
|
|
canvas = document.createElement('canvas');
|
|
|
|
canvas = document.createElement('canvas');
|
|
|
|
|
|
|
|
}
|
|
|
|
var img = new Image();
|
|
|
|
var img = new Image();
|
|
|
|
img.callback = callback;
|
|
|
|
img.callback = callback;
|
|
|
|
img.onload = function() {
|
|
|
|
img.onload = function() {
|
|
|
@ -525,7 +562,8 @@ CVUtils.halfSample = function(inImgWrapper, outImgWrapper) {
|
|
|
|
var outImgIdx = 0;
|
|
|
|
var outImgIdx = 0;
|
|
|
|
while (bottomRowIdx < endIdx) {
|
|
|
|
while (bottomRowIdx < endIdx) {
|
|
|
|
for (var i = 0; i < outWidth; i++) {
|
|
|
|
for (var i = 0; i < outWidth; i++) {
|
|
|
|
outImg[outImgIdx] = Math.floor((inImg[topRowIdx] + inImg[topRowIdx + 1] + inImg[bottomRowIdx] + inImg[bottomRowIdx + 1]) / 4);
|
|
|
|
outImg[outImgIdx] = Math.floor(
|
|
|
|
|
|
|
|
(inImg[topRowIdx] + inImg[topRowIdx + 1] + inImg[bottomRowIdx] + inImg[bottomRowIdx + 1]) / 4);
|
|
|
|
outImgIdx++;
|
|
|
|
outImgIdx++;
|
|
|
|
topRowIdx = topRowIdx + 2;
|
|
|
|
topRowIdx = topRowIdx + 2;
|
|
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
|
|
bottomRowIdx = bottomRowIdx + 2;
|
|
|
@ -536,7 +574,16 @@ CVUtils.halfSample = function(inImgWrapper, outImgWrapper) {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
CVUtils.hsv2rgb = function(hsv, rgb) {
|
|
|
|
CVUtils.hsv2rgb = function(hsv, rgb) {
|
|
|
|
var h = hsv[0], s = hsv[1], v = hsv[2], c = v * s, x = c * (1 - Math.abs((h / 60) % 2 - 1)), m = v - c, r = 0, g = 0, b = 0;
|
|
|
|
var h = hsv[0],
|
|
|
|
|
|
|
|
s = hsv[1],
|
|
|
|
|
|
|
|
v = hsv[2],
|
|
|
|
|
|
|
|
c = v * s,
|
|
|
|
|
|
|
|
x = c * (1 - Math.abs((h / 60) % 2 - 1)),
|
|
|
|
|
|
|
|
m = v - c,
|
|
|
|
|
|
|
|
r = 0,
|
|
|
|
|
|
|
|
g = 0,
|
|
|
|
|
|
|
|
b = 0;
|
|
|
|
|
|
|
|
|
|
|
|
rgb = rgb || [0, 0, 0];
|
|
|
|
rgb = rgb || [0, 0, 0];
|
|
|
|
|
|
|
|
|
|
|
|
if (h < 60) {
|
|
|
|
if (h < 60) {
|
|
|
|