Python 查找黑色轮廓之间的区域

Python 查找黑色轮廓之间的区域,python,numpy,opencv,Python,Numpy,Opencv,我有一个白色的轮廓,里面和周围都是黑色的。 我需要找到一个最大的圆,里面只有白色的区域,没有洞,并且不包含轮廓外部的黑色区域。就目前而言,我找不到这样做的好方法。 我在Python中使用openCv和Numpy。当然,如果有任何其他图书馆是必要的,我想听听 ##更新## 起初,我试图用这个代码,但它给了我最大的圆圈而不考虑其中的漏洞: def get_biggest_area_inside_contour(self,image,index): image_bin=cv2.cvtColor(im

我有一个白色的轮廓,里面和周围都是黑色的。 我需要找到一个最大的圆,里面只有白色的区域,没有洞,并且不包含轮廓外部的黑色区域。就目前而言,我找不到这样做的好方法。 我在Python中使用openCv和Numpy。当然,如果有任何其他图书馆是必要的,我想听听

##更新##

起初,我试图用这个代码,但它给了我最大的圆圈而不考虑其中的漏洞:

def get_biggest_area_inside_contour(self,image,index):

image_bin=cv2.cvtColor(image,cv2.COLOR_RGB2GRAY) 
retval,image_bin=cv2.threshold(image_bin,biggest_circle_thresh,255,cv2.THRESH_BINARY) 
contours, hierarchy = cv2.findContours(image_bin.copy(),cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE) 
image_with_contour=np.zeros(image.shape, np.uint8) 
dist=np.zeros((image.shape[0],image.shape[1])) 
for ind_y in range(image.shape[0]): 
    for ind_x in range(image.shape[1]): 
        dist[ind_y,ind_x] = cv2.pointPolygonTest(max_contour,(ind_x,ind_y),True)
正如我所回答的,这个问题有一个解决办法。 问题是我没有设法将代码从MATLAB传递到python。 代码是:

def get_biggest_area_inside_contour(self,image,index):

    image_bin=cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
    _,image_bin=cv2.threshold(image_bin,biggest_circle_thresh,255,cv2.THRESH_BINARY)
    contours, _ = cv2.findContours(image_bin.copy(),cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
    max_contour=contours[0]
    max_area=cv2.contourArea(contours[0])
    #Find the biggest white contour, some times can be little white surrond by black area
    for _cnt in contours:
        _area = cv2.contourArea(_cnt)
        if _area>max_area:
            max_area=_area
            max_contour=_cnt 
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    _blurred = cv2.GaussianBlur(gray, (5, 5), 0)
    _threshold = cv2.threshold(_blurred, biggest_circle_thresh, 255, cv2.THRESH_BINARY)[1]
    result_img=cv2.drawContours(_threshold,max_contour,-1,(255,255,255),1)
    contours, _ = cv2.findContours(result_img.copy(),cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
    #cv2.namedWindow('img {}'.format(index), cv2.WINDOW_NORMAL)
    #cv2.imshow('img {}'.format(index), result_img)

    apdp = cv2.approxPolyDP(max_contour,1,True)
    ap = [(a[0][0],a[0][1]) for a in apdp]
    vor_ap = Voronoi(ap,incremental=True)
    spined = []
    for ridge in contours:
        x, y, w, h = cv2.boundingRect(ridge)
        if cv2.pointPolygonTest(max_contour,(x,y),True) < 0.0 or cv2.pointPolygonTest(max_contour,(x+w,y+h),True) < 0.0:
            continue
        else:
            if tuple((x,y)) not in spined:
                spined.append([tuple((x,y))])
            if tuple((x+w,y)) not in spined:
                spined.append([tuple((x+w,y))])
            if tuple((x,y+h)) not in spined:
                spined.append([tuple((x,y+h))])  
            if tuple((x+w,y+h)) not in spined:
                spined.append([tuple((x+w,y+h))])                                 
    if len(spined)>0:
        for index in range(0,len(spined)):
            vor_ap.add_points(spined[index])
    fig=plt.figure(index)
    ax = fig.add_subplot(111)        
    voronoi_plot_2d(vor_ap, point_size=5, ax=ax)
    plt.scatter([s[0][0] for s in spined],[s[0][1] for s in spined])
    plt.plot([a[1] for a in ap],[a[0] for a in ap])
    if len(spined)>0:
        borders_and_holes=ap
        for i in range (0,len(spined)):
            borders_and_holes.append(spined[i])
        points=np.vstack(borders_and_holes)
        dt = Delaunay(points)
        ##cc = compute_triangle_circumcenters(dt.points, dt.simplices) Not sure how to do this
        #plt.plot(cc[:, 0], cc[:, 1], ".k")
    plt.show()
def获取轮廓内的最大面积(self、image、index):
image\u bin=cv2.cvt颜色(image,cv2.COLOR\u RGB2GRAY)
_,image_-bin=cv2.阈值(image_-bin,最大圆_-thresh,255,cv2.thresh\u二进制)
轮廓,u=cv2.findContours(image\u bin.copy(),cv2.RETR\u CCOMP,cv2.CHAIN\u近似\u简单)
最大轮廓=轮廓[0]
最大面积=cv2。轮廓面积(轮廓[0])
#找到最大的白色轮廓,有时会被黑色区域包围
对于轮廓中的_cnt:
_面积=cv2。轮廓面积(_cnt)
如果面积>最大面积:
最大面积=\u面积
最大轮廓=\u cnt
灰色=cv2.CVT颜色(图像,cv2.COLOR\u BGR2GRAY)
_模糊=cv2.高斯模糊(灰色,(5,5,0)
_threshold=cv2.threshold(_模糊,最大_圆_阈值,255,cv2.thresh_二进制)[1]
结果\u img=cv2.绘制轮廓线(\u阈值,最大\u轮廓线,-1,(255255),1)
等高线,u=cv2.findContours(result\u img.copy()、cv2.RETR\u CCOMP、cv2.CHAIN\u近似\u SIMPLE)
#cv2.namedWindow('img{}'。格式(索引),cv2.WINDOW_NORMAL)
#imshow('img{}'。格式(索引),结果(img)
apdp=cv2。近似聚合DP(最大轮廓,1,真)
ap=[(a[0][0],a[0][1])表示apdp中的a]
vor_ap=Voronoi(ap,增量=真)
有刺=[]
对于等高线中的脊线:
x、 y,w,h=cv2.boundingRect(脊线)
如果cv2.PointPolyContest(最大轮廓,(x,y),真)小于0.0或cv2.PointPolyContest(最大轮廓,(x+w,y+h),真)小于0.0:
持续
其他:
如果元组((x,y))不在脊椎中:
spined.append([tuple((x,y))]))
如果元组((x+w,y))不在脊椎中:
spined.append([tuple((x+w,y))]))
如果元组((x,y+h))不在脊椎中:
spined.append([元组((x,y+h))]))
如果元组((x+w,y+h))不在脊椎中:
spined.append([元组((x+w,y+h)))
如果len(带刺)>0:
对于范围(0,len(spined))中的索引:
vor\u ap.添加点(带尖刺的[索引])
图=plt.图(索引)
ax=图添加_子批次(111)
voronoi图2d(vor图ap,点大小=5,ax=ax)
plt.散射([s[0][0]表示有刺的s],[s[0][1]表示有刺的s])
plt.plot([a[1]表示ap中的a],[a[0]表示ap中的a])
如果len(带刺)>0:
边界和孔洞=ap
对于范围(0,len(spined))中的i:
borders_和_holes.append(带尖刺的[i])
点=np.vstack(边界和孔)
dt=Delaunay(点)
##cc=计算三角形外圆心(dt点,dt单纯形)不确定如何进行此操作
#plt.绘图(cc[:,0],cc[:,1],“.k”)
plt.show()

您可以进行距离变换(在OpenCV中)

反转图片,使边缘为白色(真),中心为黑色(假)。你可能需要对图像进行阈值处理,或者去除中间的污点。

使用L2距离(欧几里德)应用距离变换

查找最高峰值(
minMaxLoc


最高峰值是圆心,其值是半径。

可以进行距离变换(在OpenCV中)

反转图片,使边缘为白色(真),中心为黑色(假)。你可能需要对图像进行阈值处理,或者去除中间的污点。

使用L2距离(欧几里德)应用距离变换

查找最高峰值(
minMaxLoc


最高峰是圆心,其值是半径。

这是否回答了您的问题?你认为有一种方法可以在python中使用它吗,或者我需要使用matlab?你可以查找Voronoi图这是否回答了你的问题?你认为有一种方法可以在python中使用它吗,或者我需要使用matlab?你可以查找Voronoi Diagrammage_bin=cv2.cvtColor(image,cv2.COLOR\u RGB2GRAY)retval,image_bin=cv2.threshold(image_bin,magnizer_circle\u thresh,255,cv2.thresh_BINARY)轮廓,hierarchy=cv2.findContours(image_bin.copy(),cv2.RETR\u CCOMP,cv2.CHAIN\u APPROX\u SIMPLE)image\u with\u contour=np.zero(image.shape,np.uint8)dist=np.zero((image.shape[0],image.shape[1])用于范围内的ind y(image.shape[0]):用于范围内的ind x(image.shape[1]):dist[ind ind y,ind x]=cv2.pointpolyContest(max\u contour,(ind x,ind y),True)这就是我所做的,它给了我内在的漏洞。@AlonH请在你的问题中发布更新和澄清,让每个人都看到。特别是代码,以便正确格式化。@Christoph Rackwitz我更新了问题。image\u bin=cv2.cvtColor(image,cv2.COLOR\u RGB2GRAY)retval,image\u bin=cv2.threshold(image\u bin,magnize\u circle\u thresh,255,cv2.thresh\u BINARY)轮廓,hierarchy=cv2.findContours(image\u bin.copy(),cv2.RETR\u CCOMP,cv2.CHAIN\u-SIMPLE)对于范围内的ind_y(image.shape[0],image.shape[1]):对于范围内的ind_x(image.shape[1]):dist[ind_y,ind_x]=cv2.pointPolygonTest(max_contour,(ind_x,ind_y),True)这就是我所做的,它给了我内在的漏洞。@AlonH请在你的问题中发布更新和澄清,让每个人都看到。特别是代码,这样您就可以正确地格式化它了。@Christoph Rackwitz我更新了这个问题。