首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >查找黑色轮廓之间的区域

问查找黑色轮廓之间的区域
EN

Stack Overflow用户
提问于 2020-12-06 15:16:45
回答 1查看 87关注 0票数 1

我有一个白色的轮廓,里面和周围都是黑色的。我需要找到最大的圆,里面只有白色区域,没有洞,并且不包含轮廓外部的黑色区域。现在,我找不到好的方法来做到这一点。我在Python语言中使用openCv和Numpy。当然,如果需要任何其他库,我很乐意听到。

##Update##

一开始,我试着使用这段代码,但它给了我一个最大的圆圈,没有考虑其中的漏洞:

代码语言:javascript
复制
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。代码是:

代码语言:javascript
复制
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()

​

​

EN

回答 1

Stack Overflow用户

发布于 2020-12-07 02:17:15

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

反转图片,使条纹为白色(真),中心为黑色(假)。你可能需要对你的图像进行阈值处理,也许可以去掉中间的污点。

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

找到最高峰(minMaxLoc)。

最高峰是你的圆心,它的值是半径。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65165632

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档