Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python opencv中查找骨架化图像的交点_Python_Opencv_Image Processing_Opencv Contour_Line Intersection - Fatal编程技术网

在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;