查找轮廓
This commit is contained in:
@@ -14,15 +14,15 @@ define(
|
||||
|
||||
|
||||
/**
|
||||
* 查找轮廓边缘点
|
||||
* 顺时针查找轮廓边缘点
|
||||
*
|
||||
* @param {Object} imageData 图像数据
|
||||
* @param {Object} startPoint 起始点
|
||||
* @param {boolean} isInContour 是否在轮廓内
|
||||
*
|
||||
* @param {boolean} isClockwise 是否顺时针
|
||||
* @return {Array} 找到的轮廓点集
|
||||
*/
|
||||
function findContour(imageData, startPoint, isInContour) {
|
||||
function findContour(imageData, startPoint, isInContour, isClockwise) {
|
||||
var data = imageData.data;
|
||||
var width = imageData.width;
|
||||
var height = imageData.height;
|
||||
@@ -37,10 +37,10 @@ define(
|
||||
var contour = [startPoint];
|
||||
var finded;
|
||||
do {
|
||||
startIndex = index + 3 + 8;
|
||||
startIndex = index + 8 + (isClockwise ? 3 : 7);
|
||||
finded = false;
|
||||
for (var i = 0; i < 7; i++) {
|
||||
index = (startIndex - i) % 8;
|
||||
index = (startIndex + (isClockwise ? - i : i )) % 8;
|
||||
dx = x + DIRECTION[index][0];
|
||||
dy = y + DIRECTION[index][1];
|
||||
// 找到轮廓点
|
||||
@@ -57,7 +57,59 @@ define(
|
||||
}
|
||||
|
||||
if (!finded) {
|
||||
throw 'cant\'t find next contour point!';
|
||||
return null;
|
||||
}
|
||||
}
|
||||
while (x !== startX || y !== startY);
|
||||
|
||||
return contour;
|
||||
}
|
||||
|
||||
/**
|
||||
* 逆时针查找轮廓边缘点
|
||||
*
|
||||
* @param {Object} imageData 图像数据
|
||||
* @param {Object} startPoint 起始点
|
||||
* @param {boolean} isInContour 是否在轮廓内
|
||||
*
|
||||
* @return {Array} 找到的轮廓点集
|
||||
*/
|
||||
function findContourAntiClockWise(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 + 7 + 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) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
while (x !== startX || y !== startY);
|
||||
@@ -81,7 +133,12 @@ define(
|
||||
var line;
|
||||
var prevLine;
|
||||
var isInContour = false;
|
||||
var startPointArray = []; // 记录起始节点
|
||||
var startPointArray = []; // 记录外轮廓起始节点
|
||||
var startInCurvePointArray = []; // 记录内轮廓起始节点
|
||||
var currentLineArray = []; // 记录当前点集合
|
||||
var prevLineEmpty = true; // 上一行是否空行
|
||||
var startPoint;
|
||||
var endPoint;
|
||||
var point;
|
||||
|
||||
|
||||
@@ -89,28 +146,73 @@ define(
|
||||
for (y = 0; y < height; y ++) {
|
||||
line = y * width;
|
||||
isInContour = false;
|
||||
currentLineArray = [];
|
||||
for (x = 0; x < width; x++) {
|
||||
// 外轮廓起始点
|
||||
if (!isInContour && data[line + x]) {
|
||||
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
|
||||
});
|
||||
}
|
||||
currentLineArray.push({
|
||||
x: x,
|
||||
y: y,
|
||||
isInContour: true
|
||||
});
|
||||
}
|
||||
else if (isInContour && !data[line + x]) {
|
||||
isInContour = false;
|
||||
currentLineArray.push({
|
||||
x: x,
|
||||
y: y,
|
||||
isInContour: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!currentLineArray.length) {
|
||||
prevLineEmpty = true;
|
||||
}
|
||||
else {
|
||||
|
||||
// 轮廓顶部
|
||||
if (prevLineEmpty) {
|
||||
currentLineArray.forEach(function (p) {
|
||||
if (p.isInContour) {
|
||||
startPointArray.push(p);
|
||||
}
|
||||
})
|
||||
}
|
||||
else {
|
||||
prevLine = (y - 1) * width;
|
||||
for (var i = 0, l = currentLineArray.length - 1; i < l; i++) {
|
||||
// 在曲线内的线段,判断上一条线全为白点,则为新contour的起始点
|
||||
if (currentLineArray[i].isInContour) {
|
||||
var isAllWhite = true;
|
||||
for (var j = currentLineArray[i].x, je = currentLineArray[i + 1].x - 1; j < je; j++) {
|
||||
if (data[prevLine + j]) {
|
||||
isAllWhite = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAllWhite) {
|
||||
startPointArray.push(currentLineArray[i]);
|
||||
}
|
||||
}
|
||||
else if (!currentLineArray[i].isInContour) {
|
||||
var isAllBlack = true;
|
||||
for (var j = currentLineArray[i].x, je = currentLineArray[i + 1].x - 1; j < je; j++) {
|
||||
if (!data[prevLine + j]) {
|
||||
isAllBlack = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isAllBlack) {
|
||||
startInCurvePointArray.push(currentLineArray[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prevLineEmpty = false;
|
||||
}
|
||||
}
|
||||
|
||||
var contours = [];
|
||||
@@ -119,7 +221,16 @@ define(
|
||||
}
|
||||
else {
|
||||
startPointArray.forEach(function (p) {
|
||||
contours.push(findContour(imageData, p, true));
|
||||
var contour = findContour(imageData, p, true, true);
|
||||
if (contour) {
|
||||
contours.push(contour);
|
||||
}
|
||||
});
|
||||
startInCurvePointArray.forEach(function (p) {
|
||||
var contour = findContour(imageData, p, false, false);
|
||||
if (contour) {
|
||||
contours.push(contour);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user