封闭图像中的开放边界

时间:2019-08-16 16:06:35

标签: python opencv

我已经写了这个算法。它的主要思想是封闭二进制/灰度图像中的开放边界。但是,我遇到了这些错误,并且不知道为什么会出现。我想画一个包围输入点周围的开放轮廓的边界。

该算法的主要思想是,它围绕该点在周围360度内发出光线,并估计其在边界上遇到的每个点与输入图像之间的距离。

enter image description here    这就是预期的结果
enter image description here

 import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    from shapely.geometry import polygon,point
    import math
    import statistics

def dot(out,point,raduis,color=128):
    x= point[0]
    y= point[1]
    if raduis == 0:
        out[x,y]=color
    else:
        im = out.shape[0]
        jm = out.shape[1]
        i1 = (x + raduis)
        i2 = (x - raduis)
        j1 = (y + raduis)
        j2 = (y - raduis)
        i1 = i1 if i1 > 0 else 0
        i2 = i2 if i2 > 0 else 0
        j1 = j1 if j1 > 0 else 0
        j2 = j2 if j2 > 0 else 0

        i1 = i1 if i1 < im else im
        i2 = i2 if i2 < im else im
        j1 = j1 if j1 < jm else jm
        j2 = j2 if j2 < jm else jm
        out[i1:i2,j1:j2] = color
#=============================================================
def sin(ang):
    return math.sin(math.radians(ang))
def ray(img,point,ang):
    di = math.sin(math.radians(ang))
    dj = math.cos(math.radians(ang))
    c = 0
    i = point[0]
    j = point[1]
    im = img.shape[0]
    jm = img.shape[1]
    while(1):
        i = round(point[0]+c*di)
        j = round(point[1]+c*dj)
        c+=1
        if 0 > i or i >= im or 0 > j or j >= jm:
            return [*point,0]
        if img[i,j] == 255:
            print((i,j))
            cv2.line(img,point,(i,j),200)
            return [i,j,1]
#---------------------------------------------------------
def raypoly(img,point):
    rr=[]
    for a in range(0,360,10):
        r = ray(img,point,a)
        if r[2] == 1:
            rr.append([r[0],r[1]])
    return rr
#----------------------------------------------------------
def distance(a,b):
    return ((b[0]-a[0])**2+(b[1]-a[1])**2)**0.5
def metrics(point,poly):
    sz = len(poly)
    dav = 0
    dmin = 999999999
    dmax = -1
    dv =[]
    for p in range(sz):
        d = distance(point,poly[p])
        dv.append(d)
        if dmin > d:
            dmin = d
        if dmax < d:
            dmax = d
    return [statistics.mean(dv),statistics.median(dv),dmin,dmax]
#=================================================================
def projectpoint(point,angle,d):
    return [round(point[0]+d*math.cos(math.radians(angle))),round(point[1]+d*math.sin(math.radians(angle)))]
def raypolylimit(img,point,stats):
    u =[]
    med = stats[1]
    mn = stats[2]
    dmin = mn
    do = dmin
    dmax = med +(med-mn)
    sv =[]
    for a in range(0,360,10):
        r = ray(img,point,a)
        q = [r[0],r[1]]
        if r[2] == 1:
            d = distance(point,q)
            if d >= dmin and d >= dmax:
                do = d
                u.append([r[0],r[1]])
                sv.append(d)
            elif d > dmax:
                d = do
                sv.append(d)
                t = projectpoint(point,a,d)
                u.append(t)
            elif d < dmin:
                d = dmin
        else:
            d = do
            sv.append(d)
            t = projectpoint(point,a,d)
            u.append(t)
    return u
#=======================================================
def plotline(a,b,img,color=255):
    di = (a[0]-b[0])
    dj = (a[1]-b[1])
    for k in range(0,500,1):
        i=round(a[0]+di*k/500)
        j=round(a[1]+dj*k/500)
        dot(img,(i,j),0,color)
    return
#--------------------------------------------------------
def plotpoly(poly,img):
    sz =len(poly)
    for i in range(0,sz-1,1):
        p = poly[i]
        q = poly[i+1]
        plotline(p,q,img)
    p = poly[sz-1]
    q = poly[0]
    plotline(p,q,img)
#=======================================================
print(distance((4,4),(7,8)))
img = cv2.imread('imj.jpg')
cv2.imwrite('image.jpg',img)
imo = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imo,100,255,cv2.THRESH_BINARY)
# cv2.imshow('frame',imo)
# cv2.waitKey(0)
p = (100,100)
poly = raypoly(thresh,p)
stats = metrics(p,poly)
polyc =raypolylimit(thresh,p,stats)
plotpoly(polyc,thresh)
print('Distances for the boundaries = ',polyc)
print('number of points = ',len(poly))
for p in poly:
    dot(img,p,0,color=150)
h ,w =img.shape[:2]
m= 0
for x in range(h):
    for y in range(w):
        if np.all(img[x, y] == 150, axis=-1):  # (img[x, y]==150).all(axis=-1)
        # count = np.count_nonzero((img == [150, 150, 150]).all(axis=2))
            m = m + 1
print('No. of points in original image =' ,m)
plt.subplot(1,2,1),plt.imshow(img)
plt.subplot(1,2,2),plt.imshow(thresh)
plt.show()

但是我得到这个错误:

Traceback (most recent call last):
(25, 163)
  File "D:/My work/MASTERS WORK/FUNCTIONS.py", line 140, in <module>
    plotpoly(polyc,thresh)
(100, 211)
(119, 205)
(136, 199)
  File "D:/My work/MASTERS WORK/FUNCTIONS.py", line 124, in plotpoly
(165, 177)
    plotline(p,q,img)
  File "D:/My work/MASTERS WORK/FUNCTIONS.py", line 116, in plotline
(178, 145)
    dot(img,(i,j),0,color)
(190, 116)
  File "D:/My work/MASTERS WORK/FUNCTIONS.py", line 12, in dot
(180, 86)
    out[x,y]=color
(170, 74)
IndexError: index 226 is out of bounds for axis 1 with size 226

0 个答案:

没有答案