问题:在样本标注系统中,标注的小图标/样本要如何固定在图像上(无论标注人员如何平移缩放,画的样本都能随着图像变化)?
解决思路:将标注放在与图像的同一坐标系上 ----- 以图像为坐标系,求出标注在图像坐标中的横纵坐标 * 图像的缩放比。图像在画布中平移的时候,marker计算的相对于图片的坐标,xy并没有改变;图像在画布中缩放的本质是xy的放缩,我们乘以图像的缩放比就能够保持marker在图像中的相对位置。
部分相关代码:
// 添加标注小图标
function canvas_add_img (){
const rect = canvas.getBoundingClientRect(); // 获取画布在页面中的相对位置
// event.clientX:鼠标在浏览器中的坐标 rect.left:画布在页面中的水平距离
const x = Math.floor(event.clientX - rect.left - smallImageswidth / 2); // 小图标注在画布中的位置, X 坐标
const y = Math.floor(event.clientY - rect.top - smallImagesheight); // 小图标注在画布中的位置, Y 坐标
// 小图标注相对于图像中的信息
const smallImage = {
// annotate.x: 图像在画布内的横坐标 annotate.scale:图像的缩放比
x: Math.floor((x - annotate.x) / annotate.scale), // 小图标注在图像中位置,X坐标
y: Math.floor((y - annotate.y) / annotate.scale), // 小图标注在图像中位置,Y坐标
width: smallImageswidth,
height: smallImagesheight,
url: iconUrl
};
smallImages.push(smallImage); // 将小图标注的位置信息存储
// 绘制小图标到画布上
drawSmallImage(smallImage);
}
// 绘制小图标的函数
function drawSmallImage(smallImage) {
const img = new Image(); // 创建一个新的Image对象,用于加载小图标
img.src = smallImage.url; // 设置小图的URL
img.onload = function () { // 当图片加载完成后,执行
// 绘制小图标注到画布上
ctx.drawImage(
img,
smallImage.x * annotate.scale + annotate.x, // 小图标注在画布中的X坐标位置
smallImage.y * annotate.scale + annotate.y, // 小图标注在画布中的Y坐标位置
// 小图标注的宽度和高度
smallImageswidth,
smallImagesheight
);
};
}
// 修改 UpdateCanvas 方法,更新画布数据时重新绘制小图标注
const originalUpdateCanvas = annotate.UpdateCanvas.bind(annotate); // 保存原始的 UpdateCanvas 方法,用于重写后调用
annotate.UpdateCanvas = function() {
// 图片缩放时重新绘制图像和标注
originalUpdateCanvas();
// 重新绘制所有的小图标注
smallImages.forEach(smallImage => {
drawSmallImage(smallImage);
});
};
// test
canvas.addEventListener('mousedown', function (event) {
// 鼠标左键添加标注
if (event.button === 0) {
canvas_add_img ()
}
console.log(smallImages);
});