diff --git a/src/graphics/image/findContours.js b/src/graphics/image/findContours.js index 928b6a4..cda19b9 100644 --- a/src/graphics/image/findContours.js +++ b/src/graphics/image/findContours.js @@ -6,6 +6,66 @@ define( function (require) { + + // 查找的8个方向 + var DIRECTION = [ + [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1], [0, 1], [1, 1] + ]; + + + /** + * 查找轮廓边缘点 + * + * @param {Object} imageData 图像数据 + * @param {Object} startPoint 起始点 + * @param {boolean} isInContour 是否在轮廓内 + * + * @return {Array} 找到的轮廓点集 + */ + function findContour(imageData, startPoint, isInContour) { + var data = imageData.data; + var width = imageData.width; + var height = imageData.height; + var index = 0; // 当前方向 + var startIndex; // 当前起始方向 + var startX = startPoint.x; + var startY = startPoint.y; + var x = startX; + var y = startY; + var dx; + var dy; + var contour = [startPoint]; + var finded; + do { + startIndex = index + 3 + 8; + finded = false; + for (var i = 0; i < 7; i++) { + index = (startIndex - i) % 8; + dx = x + DIRECTION[index][0]; + dy = y + DIRECTION[index][1]; + // 找到轮廓点 + if (!!data[dx + dy * width] === isInContour) { + x = dx; + y = dy; + finded = true; + contour.push({ + x: dx, + y: dy + }); + break; + } + } + + if (!finded) { + throw 'cant\'t find next contour point!'; + } + } + while (x !== startX || y !== startY); + + return contour; + } + + /** * 查找二值图像轮廓 * @@ -19,50 +79,51 @@ define( var x; var y; var line; + var prevLine; var isInContour = false; - var curLineArray = []; - var prevLineArray = []; // 记录Y轴有轮廓的起始坐标 var startPointArray = []; // 记录起始节点 var point; - // 查找轮廓坐标 + + // 查找外轮廓坐标 for (y = 0; y < height; y ++) { line = y * width; isInContour = false; - curLineArray = []; for (x = 0; x < width; x++) { + // 外轮廓起始点 if (!isInContour && data[line + x]) { - if (!point || (point.x !== x - 1)) { - isInContour = true; - point = { + isInContour = true; + + prevLine = (y - 1) * width; + if ( + // 右侧和上侧无像素 + (!data[line + x + 1] && !data[prevLine + x]) + // 上一个点 + || (!data[prevLine + x] && !data[prevLine + x + 1]) + ) { + startPointArray.push({ x: x, - y: y, - isIn: true - }; - curLineArray.push(point); + y: y + }); } } else if (isInContour && !data[line + x]) { - if (!point || (point.x !== x - 1)) { - isInContour = false; - point = { - x: x, - y: y, - isIn: false - }; - curLineArray.push(point); - } + isInContour = false; } - - prevLineArray = curLineArray; - - } - } + var contours = []; + if (!startPointArray) { + return contours; + } + else { + startPointArray.forEach(function (p) { + contours.push(findContour(imageData, p, true)); + }); + } - return pointArray; + return contours; } return findContours;