我有一个框架图像(如下所示)。
我想要得到这些线的交叉点。我尝试了下面的方法:
是一个openCV图像,并且该算法返回一个坐标列表:
def getSkeletonIntersection(skeleton):
image = skeleton.copy();
image = image/255;
intersections = list();
for y in range(1,len(image)-1):
for x in range(1,len(image[y])-1):
if image[y][x] == 1:
neighbourCount = 0;
neighbours = neighbourCoords(x,y);
for n in neighbours:
if (image[n[1]][n[0]] == 1):
neighbourCount += 1;
if(neighbourCount > 2):
print(neighbourCount,x,y);
intersections.append((x,y));
return intersections;
它找到存在两个以上相邻像素的白色像素的坐标。我认为这只会返回角点,但它没有-它返回更多的点。
这是在图像上标记了它检测到的点的输出。这是因为它检测到下面所示的一些示例不是交叉点。
0 0 0 1 1 0 0 1 1
1 1 1 0 1 0 1 1 0
0 0 1 0 0 1 0 0 0
还有更多的例子。有没有另一种我应该看看的方法来检测交叉口。感谢所有的意见和想法,谢谢。
发布于 2017-01-18 06:48:08
我不确定
OpenCV
特性,但您可能应该尝试使用
命中和未命中
所描述的形态学
这里
..。
阅读
线条交汇点
并查看您需要测试的12个模板:
发布于 2017-07-22 20:30:06
我最近收到了一封电子邮件,询问我对这个问题的最终解决方案。它被张贴在下面,以便它可以通知其他人。我并不是说这段代码特别快或者特别稳定--只是说它对我来说是有效的!该功能还包括过滤过近检测到的重复和交叉点,这表明它们不是真正的交叉点,而是从骨架过程中引入的噪声。
def neighbours(x,y,image):
"""Return 8-neighbours of image point P1(x,y), in a clockwise order"""
img = image
x_1, y_1, x1, y1 = x-1, y-1, x+1, y+1;
return [ img[x_1][y], img[x_1][y1], img[x][y1], img[x1][y1], img[x1][y], img[x1][y_1], img[x][y_1], img[x_1][y_1] ]
def getSkeletonIntersection(skeleton):
""" Given a skeletonised image, it will give the coordinates of the intersections of the skeleton.
Keyword arguments:
skeleton -- the skeletonised image to detect the intersections of
Returns:
List of 2-tuples (x,y) containing the intersection coordinates
"""
# A biiiiiig list of valid intersections 2 3 4
# These are in the format shown to the right 1 C 5
# 8 7 6
validIntersection = [[0,1,0,1,0,0,1,0],[0,0,1,0,1,0,0,1],[1,0,0,1,0,1,0,0],
[0,1,0,0,1,0,1,0],[0,0,1,0,0,1,0,1],[1,0,0,1,0,0,1,0],
[0,1,0,0,1,0,0,1],[1,0,1,0,0,1,0,0],[0,1,0,0,0,1,0,1],
[0,1,0,1,0,0,0,1],[0,1,0,1,0,1,0,0],[0,0,0,1,0,1,0,1],
[1,0,1,0,0,0,1,0],[1,0,1,0,1,0,0,0],[0,0,1,0,1,0,1,0],
[1,0,0,0,1,0,1,0],[1,0,0,1,1,1,0,0],[0,0,1,0,0,1,1,1],
[1,1,0,0,1,0,0,1],[0,1,1,1,0,0,1,0],[1,0,1,1,0,0,1,0],
[1,0,1,0,0,1,1,0],[1,0,1,1,0,1,1,0],[0,1,1,0,1,0,1,1],
[1,1,0,1,1,0,1,0],[1,1,0,0,1,0,1,0],[0,1,1,0,1,0,1,0],
[0,0,1,0,1,0,1,1],[1,0,0,1,1,0,1,0],[1,0,1,0,1,1,0,1],
[1,0,1,0,1,1,0,0],[1,0,1,0,1,0,0,1],[0,1,0,0,1,0,1,1],
[0,1,1,0,1,0,0,1],[1,1,0,1,0,0,1,0],[0,1,0,1,1,0,1,0],
[0,0,1,0,1,1,0,1],[1,0,1,0,0,1,0,1],[1,0,0,1,0,1,1,0],
[1,0,1,1,0,1,0,0]];
image = skeleton.copy();
image = image/255;
intersections = list();
for x in range(1,len(image)-1):
for y in range(1,len(image[x])-1):
# If we have a white pixel
if image[x][y] == 1:
neighbours = neighbours(x,y,image);
valid = True;
if neighbours in validIntersection:
intersections.append((y,x));
# Filter intersections to make sure we don't count them twice or ones that are very close together
for point1 in intersections:
for point2 in intersections:
if (((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2) < 10**2) and (point1 != point2):
intersections.remove(point2);
# Remove duplicates
intersections = list(set(intersections));
return intersections;
这也可以在
github这里
..。
发布于 2017-01-18 16:44:30
对于给定的像素,如果不计算总的8个邻域(=连通性为8的邻域),而是计算8个邻域的数量,这可能会有所帮助
它们彼此之间不是4个邻居
所以在你的假阳性例子中
0 0 0 1 1 0 0 1 1
1 1 1 0 1 0 1 1 0
0 0 1 0 0 1 0 0 0
对于每种情况,您都有3个邻居,但每次都有2个邻居是4-连接的。(下一个代码段中标记为"2“的像素)
0 0 0 2 2 0 0 2 2
1 1 2 0 1 0 1 1 0
0 0 2 0 0 1 0 0 0
如果您只考虑其中一个作为计数(而不是现在代码中的两个),那么您实际上只有两个新定义的“邻居”,并且考虑的点不被认为是交叉点。其他“真正的交叉点”仍将保留,如下所示
0 1 0 0 1 0 0 1 0
1 1 1 0 1 0 1 1 0
0 0 0 1 0 1 0 0 1
仍然有3个新定义的邻居。
我还没有检查你的映像是否完美工作,但我之前已经为这个问题实现了类似的东西……
https://stackoverflow.com/questions/41705405
复制相似问题