Skip to content

Commit

Permalink
feat: Add segment by rect
Browse files Browse the repository at this point in the history
  • Loading branch information
lixinghua123 committed Aug 3, 2022
1 parent 85c82a2 commit c4ae195
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 38 deletions.
4 changes: 2 additions & 2 deletions packages/lb-annotation/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

import { EToolName } from '@/constant/tool';
import { getConfig, styleDefaultConfig } from '@/constant/defaultConfig';
import CommonToolUtils from '@/utils/tool/CommonToolUtils';
import { IPolygonData } from '@/types/tool/polygon';
import { ELang } from '@/constant/annotation';
import { getCurrentOperation } from '../utils/tool/CurrentOperation';

interface IProps {
container: HTMLElement;
Expand Down Expand Up @@ -125,7 +125,7 @@ export default class AnnotationEngine {
this.toolInstance.destroy();
}

const ToolOperation: any = CommonToolUtils.getCurrentOperation(this.toolName);
const ToolOperation: any = getCurrentOperation(this.toolName);
if (!ToolOperation) {
return;
}
Expand Down
180 changes: 180 additions & 0 deletions packages/lb-annotation/src/core/toolOperation/segmentByRect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
import AxisUtils from '@/utils/tool/AxisUtils';
import { i18n } from '@labelbee/lb-utils';
import { RectOperation } from './rectOperation';
import type { IRectOperationProps } from './rectOperation';
import EKeyCode from '../../constant/keyCode';

interface ISegmentByRectProps extends IRectOperationProps {
runPrediction: any;
}

class SegmentByRect extends RectOperation {
public isRunSegment: boolean; // 是否进行算法预算

public runPrediction: Function; // 分割方法

constructor(props: ISegmentByRectProps) {
super(props);
this.isRunSegment = false;
this.runPrediction = props.runPrediction;
}

public eventBinding() {
document.addEventListener('keydown', (e) => this.onKeydown(e));
super.eventBinding();
}

public onKeydown = (e: KeyboardEvent) => {
switch (e.keyCode) {
case EKeyCode.Esc:
e.preventDefault();
e.stopPropagation();
this.clearPredictionInfo();
break;

case EKeyCode.Z:
if (e.ctrlKey) {
e.preventDefault();
e.stopPropagation();
this.rectList = [];
this.render();
}
break;
default:
break;
}
};

public clearPredictionInfo() {
this.rectList = [];
this.isShowCursor = false; // 开启光标
this.coord = { x: -1, y: -1 };
this.drawingRect = undefined;
this.isRunSegment = false;
this.clearCanvas();
this.render();
}

public onMouseUp(e: MouseEvent) {
if (this.isRunSegment) {
return;
}

// 进行分割操作
if (e.button === 0 && this.rectList.length === 1 && !this.isRunSegment) {
e.stopPropagation();
this.segmentPrediction(e);
return;
}

super.onMouseUp(e);

return undefined;
}

public onMouseDown(e: MouseEvent) {
if (this.isRunSegment) {
return;
}
super.onMouseDown(e);
return undefined;
}

public renderCursorLine() {
if (!this.ctx) {
return;
}

const { ctx } = this;
const padding = 10; // 框的边界
const lineWidth = 1;
const { x, y } = this.coord;
ctx.save();
ctx.strokeStyle = 'white';
ctx.setLineDash([6]);
ctx.lineWidth = lineWidth;
ctx.strokeRect(x - padding, y - padding, padding * 2, padding * 2);
ctx.restore();

// 提示编写
let text = `① ${i18n.t('FramingOfObjectToBeDivided')}`;
const isEn = i18n.language === 'en';
let rectWidth = isEn ? 326 : 186;

if (this.rectList?.length === 1) {
text = `② ${i18n.t('ClickOnTarget')}`;
rectWidth = isEn ? 232 : 142;
const radius = 2;
ctx.save();
ctx.strokeStyle = 'white';
const margin = lineWidth + padding;

ctx.beginPath();
ctx.moveTo(x + margin + radius * 2, y + margin + radius);
ctx.arc(x + margin + radius, y + margin + radius, radius, 0, Math.PI * 2, true);
ctx.stroke();
ctx.restore();
}

if (this.isRunSegment) {
// 进行算法中
rectWidth = isEn ? 252 : 136;
text = i18n.t('SplittingAlgorithmPrediction');
}

ctx.save();
ctx.fillStyle = this.style.strokeColor;
ctx.fillRect(x + padding, y - padding * 4 - 1, rectWidth, 32);
ctx.restore();
ctx.save();
ctx.font = '14px Source Han Sans CN';
ctx.fillStyle = 'white';
ctx.fillText(text, x + padding + 14, y - padding * 2);
ctx.restore();
super.renderCursorLine();
}

public renderDrawingRect(rect: IRect, zoom: number, isZoom = false) {
if (this.ctx && rect) {
const transformRect = AxisUtils.changeRectByZoom(rect, isZoom ? zoom : this.zoom, this.currentPos);
const { x, y, width, height } = transformRect;

this.ctx.save();
this.ctx.lineCap = 'butt';
this.ctx.lineWidth = this.style.strokeWidth;

this.ctx.strokeStyle = 'white';
this.ctx.strokeRect(x, y, width, height); // 白底

this.ctx.strokeStyle = this.style.strokeColor;
this.ctx.setLineDash([6]);
this.ctx.strokeRect(x, y, width, height); // 线段

this.ctx.restore();
}
}

public renderTextAttribute() {}

public renderSelectedRect() {}

public segmentPrediction = async (e: MouseEvent) => {
const coord = this.getCoordinateUnderZoom(e);
this.isRunSegment = true;
this.render();

const res = await this.runPrediction({
point: coord,
rect: {
x: this.rectList[0].x,
y: this.rectList[0].y,
w: this.rectList[0].width,
h: this.rectList[0].height,
},
});
if (res) {
this.clearPredictionInfo();
}
};
}
export default SegmentByRect;
34 changes: 0 additions & 34 deletions packages/lb-annotation/src/utils/tool/CommonToolUtils.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import { isObject } from 'lodash';
import { ECheckModel, EToolName } from '@/constant/tool';
import { IPolygonPoint } from '../../types/tool/polygon';
import { ESortDirection, EStepType } from '../../constant/annotation';
import CheckOperation from '../../core/toolOperation/checkOperation';
import PolygonOperation from '../../core/toolOperation/polygonOperation';
import RectOperationAsNewName from '../../core/toolOperation/rectOperation';
import TagOperation from '../../core/toolOperation/tagOperation';
import LineToolOperation from '../../core/toolOperation/LineToolOperation';
import PointOperation from '../../core/toolOperation/pointOperation';
import TextToolOperation from '../../core/toolOperation/TextToolOperation';

type point = {
id: string;
Expand Down Expand Up @@ -109,32 +101,6 @@ export default class CommonToolUtils {
return flag;
}

/**
* 筛选当前的步骤配置
* @param toolName
*/
public static getCurrentOperation(toolName: EToolName | ECheckModel) {
switch (toolName) {
case EToolName.Rect:
case EToolName.RectTrack:
return RectOperationAsNewName;
case EToolName.Tag:
return TagOperation;
case EToolName.Polygon:
return PolygonOperation;
case ECheckModel.Check:
return CheckOperation;
case EToolName.Line:
return LineToolOperation;
case EToolName.Point:
return PointOperation;
case EToolName.Text:
return TextToolOperation;
default:
throw new Error('not match tool');
}
}

public static getNextSelectedRectID(
rectList: point[],
sort: ESortDirection = ESortDirection.ascend,
Expand Down
36 changes: 36 additions & 0 deletions packages/lb-annotation/src/utils/tool/CurrentOperation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* 筛选当前的步骤配置
* @param toolName
*/
import { ECheckModel, EToolName } from '@/constant/tool';
import CheckOperation from '../../core/toolOperation/checkOperation';
import PolygonOperation from '../../core/toolOperation/polygonOperation';
import RectOperationAsNewName from '../../core/toolOperation/rectOperation';
import TagOperation from '../../core/toolOperation/tagOperation';
import LineToolOperation from '../../core/toolOperation/LineToolOperation';
import PointOperation from '../../core/toolOperation/pointOperation';
import TextToolOperation from '../../core/toolOperation/TextToolOperation';

const getCurrentOperation = (toolName: EToolName | ECheckModel) => {
switch (toolName) {
case EToolName.Rect:
case EToolName.RectTrack:
return RectOperationAsNewName;

case EToolName.Tag:
return TagOperation;
case EToolName.Polygon:
return PolygonOperation;
case ECheckModel.Check:
return CheckOperation;
case EToolName.Line:
return LineToolOperation;
case EToolName.Point:
return PointOperation;
case EToolName.Text:
return TextToolOperation;
default:
throw new Error('not match tool');
}
};
export { getCurrentOperation };
10 changes: 8 additions & 2 deletions packages/lb-utils/src/i18n/resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@
"NoDependency": "This image does not need to be labeled",
"TextCheckNumberOnly": "Please enter the number",
"TextCheckEnglishOnly": "Please enter English",
"TextCheckCustomFormat": "Please enter data in custom format"
"TextCheckCustomFormat": "Please enter data in custom format",
"FramingOfObjectToBeDivided": "Please frame the object to be divided first",
"ClickOnTarget": "Please click on target object",
"SplittingAlgorithmPrediction": "Splitting algorithm prediction in..."
},
"cn": {
"TextInput": "文本输入",
Expand Down Expand Up @@ -249,6 +252,9 @@
"NoDependency": "该图片无需标注",
"TextCheckNumberOnly": "请按仅数字的格式输入",
"TextCheckEnglishOnly": "请按仅英文的格式输入",
"TextCheckCustomFormat": "请按要求的格式输入"
"TextCheckCustomFormat": "请按要求的格式输入",
"FramingOfObjectToBeDivided" : "请先框出需分割的物体",
"ClickOnTarget" : "请单击目标物体",
"SplittingAlgorithmPrediction" : "分割算法预测中..."
}
}

0 comments on commit c4ae195

Please sign in to comment.