1

我有一个画布,我在上面画了 4 条线。然后,我需要将这些线的准确性与 4 条预定义线的坐标进行比较。我可以用画布做到这一点吗?

谢谢。

4

2 回答 2

0

正如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 

如果你不知道绕线的方向,你可以交换起点和终点并取最小距离。

于 2013-05-16T11:07:44.533 回答
0

好吧,您可以在 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 truereturn i也会给你与你想要检查的像素的距离。如果您将两个循环组合成一个 i 和一个 j 值,返回 sqrt(i^2+j^2) 并将所有检查相加,您可以得到一个指标,您的线有多准确。

要实现 sqareroot-error,只需比较 y 距离并总结平方距离 i^2 就足够了。

请注意,这些程序是建议,可能存在更好的实现,我的代码仍然可能包含错误。

于 2013-05-16T11:13:50.630 回答