python – numpy二进制光栅图像到多边形变换
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了python – numpy二进制光栅图像到多边形变换,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5322字,纯文字阅读大概需要8分钟。
内容图文
![python – numpy二进制光栅图像到多边形变换](/upload/InfoBanner/zyjiaocheng/823/652be65932244525842bce1d8666a069.jpg)
我想将2d numpy数组转换为多边形.性能对我来说非常重要,但我想避免进行C扩展.
可以通过侵蚀来制作二进制轮廓图像.然后我找到了this.它太慢了,并没有应对有时侵蚀造成的尖峰.
尖峰:
000100
000100
000100
111011
我的第一次尝试:
mat = mat.copy() != 0
mat = mat - scipy.ndimage.binary_erosion(mat)
vertices = np.argwhere(mat)
minx = vertices.min(axis=0)[0]
maxx = vertices.max(axis=0)[0]
vertices_sorted = {}
for x in xrange(minx - 1, maxx + 2):
vertices_sorted[x] = []
for vertex in vertices:
vertices_sorted[vertex[0]].append(vertex[1])
vertex_loop = [(minx, vertices_sorted[minx][0])]
while True:
x, y = vertex_loop[-1]
for column, row in ((x, y + 1), (x, y - 1),
(x + 1, y), (x + 1, y + 1), (x + 1, y - 1),
(x - 1, y), (x - 1, y + 1), (x - 1, y - 1)):
if row in vertices_sorted[column]:
vertices_sorted[column].remove(row)
vertex_loop.append((column, row))
break
else:
vertex_loop.pop()
if vertex_loop[-1] == vertex_loop[0]:
break
return vertex_loop[:-1]
它大部分时间都有效,但速度不够快.
我的第二个代码很少工作,但我没有修复它,因为它比第一个代码慢很多倍:
mat = mat.copy() != 0
mat = mat - scipy.ndimage.binary_erosion(mat)
xs, ys = np.nonzero(mat)
ys = np.ma.array(ys)
vertex_loop = [(xs[0], ys[0])]
ys[0] = np.ma.masked
while True:
x, y = vertex_loop[-1]
start = np.searchsorted(xs, x-1, side="left")
end = np.searchsorted(xs, x+1, side="right")
for i in xrange(start, end):
if ys[i] == y or ys[i] == y + 1 or ys[i] == y - 1:
vertex_loop.append((xs[i], ys[i]))
ys[i] = np.ma.masked
break
else:
if np.all(ys.mask):
break
else:
vertex_loop.pop()
return vertex_loop
如何进一步提高速度?
编辑:似乎numpy蒙面数组非常慢.这个实现几乎和第一个一样快:
#import time
#t1 = time.time()
mat = mat.copy() != 0
mat = mat - scipy.ndimage.binary_erosion(mat)
xs, ys = np.nonzero(mat)
#t2 = time.time()
minx = xs[0]
maxx = xs[-1]
# Ketju pakosti k?y l?pi kaikki rivit minx:n ja maxx:n v?liss?, sill? se ON KETJU
xlist = range(minx - 1, maxx + 2)
# starts ja ends ovat dictit jotka kertovat miss? slicess? x == key
tmp = np.searchsorted(xs, xlist, side="left")
starts = dict(zip(xlist, tmp))
tmp = np.searchsorted(xs, xlist, side="right")
ends = dict(zip(xlist, tmp))
unused = np.ones(len(xs), dtype=np.bool)
#t3 = time.time()
vertex_loop = [(xs[0], ys[0])]
unused[0] = 0
count = 0
while True:
count += 1
x, y = vertex_loop[-1]
for i in xrange(starts[x - 1], ends[x + 1]):
row = ys[i]
if unused[i] and (row == y or row == y + 1 or row == y - 1):
vertex_loop.append((xs[i], row))
unused[i] = 0
break
else:
if abs(x - xs[0]) <= 1 and abs(y - ys[0]) <= 1:
break
else:
vertex_loop.pop()
#t4 = time.time()
#print abs(t1-t2)*1000, abs(t2-t3)*1000, abs(t3-t4)*1000
return vertex_loop
我想知道是否有一种简单的方法可以用scipy做到这一点我没有偶然发现.
EDIT2:在pygame中有一个掩码对象,它在0.025毫秒内完成了我所需要的,而我的解决方案需要35毫秒,而我在互联网上找到的find_contours在4-5毫秒内完成.我将修改pygame.mask.outline的源代码以使用numpy数组并在此处发布.
解决方法:
这是:获取二进制numpy数组轮廓的极快方法.
outline.py:
from scipy.weave import inline, converters
_code = open("outline.c", "r").read()
def outline(data, every):
width, height = data.shape
return inline(_code, ['data', 'width', 'height', 'every'], type_converters=converters.blitz)
outline.c:
/*
Modifioitu pygame.mask.Mask.outline
Input: data, width, height, every
*/
PyObject *plist, *value;
int x, y, e, firstx, firsty, secx, secy, currx, curry, nextx, nexty, n;
int a[14], b[14];
a[0] = a[1] = a[7] = a[8] = a[9] = b[1] = b[2] = b[3] = b[9] = b[10] = b[11]= 1;
a[2] = a[6] = a[10] = b[4] = b[0] = b[12] = b[8] = 0;
a[3] = a[4] = a[5] = a[11] = a[12] = a[13] = b[5] = b[6] = b[7] = b[13] = -1;
plist = NULL;
plist = PyList_New (0);
/*if (!plist) En ymm?rr? mihin t?t? tarvii
return NULL;*/
every = 1;
n = firstx = firsty = secx = x = 0;
/*if(!PyArg_ParseTuple(args, "|i", &every)) {
return NULL;
}
by copying to a new, larger mask, we avoid having to check if we are at
a border pixel every time.
bitmask_draw(m, c, 1, 1); */
e = every;
/* find the first set pixel in the mask */
for (y = 1; y < height-1; y++) {
for (x = 1; x < width-1; x++) {
if (data(x, y)) {
firstx = x;
firsty = y;
value = Py_BuildValue("(ii)", x-1, y-1);
PyList_Append(plist, value);
Py_DECREF(value);
break;
}
}
if (data(x, y))
break;
}
/* covers the mask having zero pixels or only the final pixel
Pikseleit? on ainakin kymmenen
if ((x == width-1) && (y == height-1)) {
return plist;
} */
/* check just the first pixel for neighbors */
for (n = 0;n < 8;n++) {
if (data(x+a[n], y+b[n])) {
currx = secx = x+a[n];
curry = secy = y+b[n];
e--;
if (!e) {
e = every;
value = Py_BuildValue("(ii)", secx-1, secy-1);
PyList_Append(plist, value);
Py_DECREF(value);
}
break;
}
}
/* if there are no neighbors, return
Pikseleit? on ainakin kymmenen
if (!secx) {
return plist;
}*/
/* the outline tracing loop */
for (;;) {
/* look around the pixel, it has to have a neighbor */
for (n = (n + 6) & 7;;n++) {
if (data(currx+a[n], curry+b[n])) {
nextx = currx+a[n];
nexty = curry+b[n];
e--;
if (!e) {
e = every;
if ((curry == firsty && currx == firstx) && (secx == nextx && secy == nexty)) {
break;
}
value = Py_BuildValue("(ii)", nextx-1, nexty-1);
PyList_Append(plist, value);
Py_DECREF(value);
}
break;
}
}
/* if we are back at the first pixel, and the next one will be the
second one we visited, we are done */
if ((curry == firsty && currx == firstx) && (secx == nextx && secy == nexty)) {
break;
}
curry = nexty;
currx = nextx;
}
return_val = plist;
内容总结
以上是互联网集市为您收集整理的python – numpy二进制光栅图像到多边形变换全部内容,希望文章能够帮你解决python – numpy二进制光栅图像到多边形变换所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。