我有一个画布,我在上面画了 4 条线。然后,我需要将这些线的准确性与 4 条预定义线的坐标进行比较。我可以用画布做到这一点吗?
谢谢。
正如JJPA所说,试一试!
您可以采取的一种方法是存储绘制线和预期线的坐标。每条线形成一个向量。您可以使用简单的公式计算线之间的欧几里得距离。距离越近,线条越准确。
我刚写了这个。
var expected = {from: {x:10, y:10}, to:{x:20, y:20}}
var identical = {from: {x:10, y:10}, to:{x:20, y:20}}
var close = {from: {x:9, y:9}, to:{x:21, y:21}}
var lessClose = {from: {x:8, y:13}, to:{x:25, y:15}}
var distance = function(a, b) {
return Math.sqrt(Math.pow(a.from.x - b.from.y, 2) +
Math.pow(a.to.x - b.to.y, 2))
}
console.log("identical", distance(expected, identical))
console.log("close", distance(expected, close))
console.log("lessclose", distance(expected, lessClose))
给
identical 0
close 1.4142135623730951
lessclose 5.830951894845301
如果你不知道绕线的方向,你可以交换起点和终点并取最小距离。
好吧,您可以在 javascript 的 rgb 数组中获取画布的像素:
var pixelarray= canvas.getImageData(x, y, width, height).data;
然后pixelarray[0]
整数是第一个像素pixelarray[3]
的红色值,第二个像素的红色值,依此类推。在 100px 宽度的画布中(第一行中的像素索引 0 到 299),pixelarray[299]
将是第一行中最后一个像素的蓝色值和pixelarray[300]
第二行中第一个像素的红色值。
然后你可以得到代表你想要比较的 4 行的函数并执行类似的操作
function isblack(x,y,width,height){
return pixelarray[(y*width+x)*3]==255&&pixelarray[(y*width+x)*3+1]==255&&pixelarray[(y*width+x)*3+2]==255||x<0||x>width||y<0||y>height;
}
function f(x){return a*x+b;}
var lineblackness=0;
for(var x=0;x<picturewidth;x++)if(isblack(x,f(x),picturewidth,pictureheight))lineblackness++;
if(lineblackness==picturewidth)line_is_drawn();
其中 fx(x) 将代表线...
好吧,如果您使用图片或坐标作为线条,它可能会变得更容易:
getcoord(data){
var ar=new array();
for(var i=0;i<data.length/3;i++)if(data[i*3]==255)ar.push(i);
return ar;
}
var comparecoords=getcoord(comparecanvas.getImageData(x, y, width, height).data);
var thisdata=canvas.getImageData(x, y, width, height).data;
var linehits=0;
for(var i=0;i<comparecoords.length;i++){if(thisdata[comparecoords[i]*3]==255)linehits++;}
if(comparecoords.length==linehits)all_coords_are_hit();
这里我只比较了红色值,假设你有一个黑白图像。
如果您想比较不完全适合的行,您可以更改 ==255 并添加一些额外的 if,例如
function isblack(x,y,width,height,blurr,treshhold){
for(var i=-blurr;i<blurr;i++)if(x-i>0&&x+i<width&&pixelarray[(y*width+(x+i))*3]>=treshhold)return true;
for(var i=-blurr;i<blurr;i++)if(y-i>0&&y+i<height&&pixelarray[((y+i)*width+(x))*3]>=treshhold)return true;
return false;
}
此函数也只使用红色,但使用阈值让灰色也有效。它还接受一个模糊值,用于在像素之前/之后检查 x 方向,然后再检查 y 方向。
您还可以结合两个循环来检查像素周围的矩形。
改变return true
成return i
也会给你与你想要检查的像素的距离。如果您将两个循环组合成一个 i 和一个 j 值,返回 sqrt(i^2+j^2) 并将所有检查相加,您可以得到一个指标,您的线有多准确。
要实现 sqareroot-error,只需比较 y 距离并总结平方距离 i^2 就足够了。
请注意,这些程序是建议,可能存在更好的实现,我的代码仍然可能包含错误。