在python opencv中查找骨架化图像的交点
我有一个骨骼化的图像(如下所示) 我想知道两条线的交点。我尝试了以下方法,在python opencv中查找骨架化图像的交点,python,opencv,image-processing,opencv-contour,line-intersection,Python,Opencv,Image Processing,Opencv Contour,Line Intersection,我有一个骨骼化的图像(如下所示) 我想知道两条线的交点。我尝试了以下方法,skeleton是一个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
skeleton
是一个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
还有更多的例子。是否有其他方法可以检测交叉口。感谢所有的意见和建议 我不确定OpenCV的特性,但您可能应该尝试使用上面描述的命中和未命中形态学 阅读在线连接,并查看需要测试的12个模板:
如果在计算给定像素时,不计算8个邻居(=连接为8的邻居)的总数,而是计算彼此不是4个邻居的8个邻居的数量,则可能会有所帮助 所以在你的假阳性例子中
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”的像素)
如果你只考虑其中的一个(而不是现在在你的代码中),你确实只有2个新定义的“邻居”,并且考虑的点不被认为是交叉点。 其他“真正的十字路口”仍将保留,如下所示
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个新定义的邻居
我还没有检查你的图像是否工作正常,但我不久前就为这个问题实现了类似的功能…我最近收到一封电子邮件,要求最终解决这个问题。它张贴在下面,以便通知其他人。我并没有说这段代码特别快或稳定——只是说它对我来说很有用!该功能还包括对检测到的重叠和交叉点进行过滤,表明它们不是真实的交叉点,而是骨架化过程中引入的噪声
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;
def邻居(x,y,图像):
“”“以顺时针顺序返回像点P1(x,y)的8个相邻点”“”
img=图像
x_1,y_1,x1,y1=x-1,y-1,x+1,y+1;
返回[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(骨架):
“”“给定骨架化图像,它将给出骨架交点的坐标。
关键字参数:
骨架——用于检测交叉点的骨架化图像
返回:
包含交点坐标的2元组(x,y)列表
"""
#有效交叉口的BIIIIG列表2 3 4
#它们的格式如右图1 C 5所示
# 8 7 6
有效区间=[[0,1,0,1,0,0,1,0],[0,0,1,0,1,0,0,1],[1,0,0,1,0,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;
交叉点=列表();
对于范围内的x(1,透镜(图像)-1):
对于范围(1,len(图像[x])-1)内的y:
#如果我们有一个白色像素
如果图像[x][y]==1:
邻居=邻居(x,y,图像);
有效=真;
如果邻居在有效区间:
附加((y,x));
#过滤交叉点以确保我们不会计算两次或非常接近的交叉点
对于交点中的点1:
对于交点中的点2:
如果(((点1[0]-点2[0])**2+(点1[1]-点2[1])**2)<10**2)和(点1!=点2):
删除(点2);
#删除重复项
交叉点=列表(设置(交叉点));
返回交叉口;
这也可以在上找到。这是我的解决方案:
#生成曲线交点核的函数
def生成非相邻组合(输入列表,取n):
"""
它在没有相邻n的时间生成m和n的组合。
输入:
input_list=(iterable)要提取组合的元素列表
take_n=(整数)在中一次要获取的元素数
每种组合
输出:
all_comb=(np.array)和所有组合
"""
all_comb=[]
对于itertools.组合中的梳(输入列表,取):
comb=np.数组(comb)
d=np.差异(梳)
fd=np.diff(np.flip(comb))
如果len(d[d==1])==0和comb[-1]-comb[0]!=7:
全部梳。追加(梳)
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;