图形测试实现的正确性

时间:2012-11-25 12:42:42

标签: python

我正在测试algorithm的实现,计算两个省略号的重叠区域。

测试的想法是检查直观是否正确计算了椭圆的交点(如果有的话)。如果不是这种情况,则计算出的区域可能不正确。

编辑:我的实现的输出是一个带有交叉点的文件。我绘制椭圆和交点,并savefig。在视觉上,我检查结果,并说服自己交叉点是否正确。

以下是一个例子:

enter image description here

我的问题只是这种视觉方法无法随着测试数量的增加而扩展(比方说1000例)。

有关如何自动化此测试的任何想法?

3 个答案:

答案 0 :(得分:1)

所以我做了一些研究,这就是我的建议。你可以做的是使用另一个python库来计算两个省略号的交点,然后比较你的实现返回的那两个。这两个应该是相同的,如果不是你可以让测试失败并调查哪一个是错误的。 sympy库可以计算多个支持的实体Ellipse,Circle,Polygon,RegularPolygon,Triangle之间的交叉点。我建议使用标准库的unittest来执行实际测试。然后你可以运行一个测试运行,创建几千个随机椭圆,并检查每个椭圆的交叉点。

您可以查看包含交叉计算的此example code in their docs。他们在他们的文档中有这个惊人的功能,你可以点击示例旁边的SymPy Live链接中的运行代码块,它将在你的浏览器中打开一个python会话,并在他们的谷歌应用引擎服务器上运行该示例。这使您可以将其库用于测试驱动器,而无需将其安装在您的计算机上。看看他们的web-based interactive python shell它真的很整洁。

答案 1 :(得分:1)

<强>方法

由于我采取了一种全新的方法,因此决定将此作为另一个答案发布。我使用Python Imaging Library在不同的图像上绘制两个椭圆,颜色为红色和绿色。然后我混合了两个图像并计算了图像中黄色像素的数量,黄色是绿色和红色的合成,并将成为交叉区域的颜色。第一个椭圆将为红色,第二个为绿色,其交叉点为黄色。出于演示目的,我将第二个椭圆设为圆形并使其完全包含在第一个椭圆中,以便可以显示它的区域应该是大小的圆形区域。由于像素被计数,因此无法得到精确的答案,但在此示例中,分辨率为500x500,像素计数区域与正确值相差0.42%。当然,如果你提高分辨率,你可以期望获得更高的精度,但出于测试目的,我只接受+/- 1%的容差。您可以注释保存的行并显示我刚刚包含它们的图像,以帮助进行初始调试。

<强>性能

我运行了1000次调用该函数的测试运行,并在13.4秒内完成。因此,创建三个图像需要大约13毫秒,并且像素计数对于手头的任务来说是一个不错的性能。

<强>代码

from PIL import Image, ImageDraw
from math import pi

RED, GREEN, YELLOW = (255, 0, 0), (0, 255, 0), (127, 127, 0)
SIZE = (500, 500)

def overlap(ellipse1, ellipse2):
    im1 = Image.new("RGB", SIZE)
    ImageDraw.Draw(im1).ellipse(ellipse1, fill=RED)
    im2 = Image.new("RGB", SIZE)
    ImageDraw.Draw(im2).ellipse(ellipse2, fill=GREEN)
    im3 = Image.blend(im1, im2, 0.5)
    im3.show()
    im3.save('test.png', "png")
    return [count for count, color in im3.getcolors() if color == YELLOW][0]

area1 = overlap((0, 50, 500, 450), (50, 50, 450, 450))
area2 = pi * (200**2)
print "overlap calc:" , area1
print "exact area:  " , area2
print "percent diff:" , ((area1 - area2)/area2)*100

<强>输出

overlap calc: 126196
exact area:   125663.706144
percent diff: 0.423585992124

图片

ellipse with intersection

答案 2 :(得分:0)

编辑:抱歉,我想我误解了这个问题。 要做到这一点,你需要找到2 elipse函数之间的交叉点 或者您可以使用sympy http://docs.sympy.org/dev/modules/geometry.html