参考链接:https://blog.csdn.net/qq_36614557/article/details/115315449
def findpoint(x_arr, y_arr, x_next, y_next):
n = len(x_arr)
f = 1
for i in range(n):
if x_arr[i] == x_next and y_arr[i] == y_next:
f = 0
break
return f
# 依次获取边缘轮廓上的点
def getAllPoint(img, img_c3):
_, bw_img = cv2.threshold(img, 0, 1, cv2.THRESH_BINARY)
thin_img = morphology.skeletonize(bw_img)
thin_img = thin_img.astype(np.uint8) * 255
x = []
y = []
sx, sy = np.where(thin_img==255)
sx_first = sx[0]
sy_first = sy[0]
x.append(sx_first)
y.append(sy_first)
dir=[[-1,-1],[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1]]
while True:
f = 0
for i in range(8):
if thin_img[sx_first + dir[i][0]][sy_first + dir[i][1]] == 255 and findpoint(x, y, (sx_first + dir[i][0]), (sy_first + dir[i][1])):
sx_first += dir[i][0]
sy_first += dir[i][1]
f = 1
break
if f == 0:
break
if sx_first == x[0] and sy_first == y[0]:
break
x.append(sx_first)
y.append(sy_first)
# for i in range(len(x)):
# cv2.circle(img_c3, (y[i], x[i]), 1, (0, 0, 255), -1)
# cv2.imshow('img', img_c3)
# cv2.waitKey(0)
return x, y
参考:https://zhuanlan.zhihu.com/p/72083902
def PJcurvature(x,y):
"""
input : the coordinate of the three point
output : the curvature and norm direction
refer to https://github.com/Pjer-zhang/PJCurvature for detail
"""
t_a = LA.norm([x[1]-x[0],y[1]-y[0]])
t_b = LA.norm([x[2]-x[1],y[2]-y[1]])
M = np.array([
[1, -t_a, t_a**2],
[1, 0, 0 ],
[1, t_b, t_b**2]
])
a = np.matmul(LA.inv(M),x)
b = np.matmul(LA.inv(M),y)
kappa = 2*(a[2]*b[1]-b[2]*a[1])/(a[1]**2.+b[1]**2.)**(1.5)
norm_direction = [b[1],-a[1]]/np.sqrt(a[1]**2.+b[1]**2.)
return kappa, norm_direction
img = cv2.imread("ES_img2.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
LV_img = copy.deepcopy(gray)
LV_img[LV_img != 255] = 0
LV_img_Gaussian = cv2.GaussianBlur(LV_img, (3, 3), 1)
LV_img_Gaussian[LV_img_Gaussian > 0] = 255
LV_img_uint8 = LV_img_Gaussian.astype("uint8")
LV_edge = cv2.Canny(LV_img_uint8, 1, 1)
# cv2.imwrite("ED.png", LV_edge)
img_c3 = np.zeros_like(img)
img_c3[:, :, 0] = LV_edge
img_c3[:, :, 1] = LV_edge
img_c3[:, :, 2] = LV_edge
# # 计算曲率
arr_x, arr_y = getAllPoint(LV_edge, img_c3)
step_point = 8
j = 0
p = step_point
ka = []
no = []
po = []
for i in range(len(arr_x)):
if i < step_point:
input_x = None
input_y = None
idx_first = len(arr_x) - p
idx_cur = i
idx_next = i + step_point
input_x = [arr_x[idx_first], arr_x[idx_cur], arr_x[idx_next]]
input_y = [arr_y[idx_first], arr_y[idx_cur], arr_y[idx_next]]
p -= 1
if i < len(arr_x) - step_point and i >= step_point:
input_x = None
input_y = None
idx_first = i - step_point
idx_cur = i
idx_next = i + step_point
input_x = [arr_x[idx_first], arr_x[idx_cur], arr_x[idx_next]]
input_y = [arr_y[idx_first], arr_y[idx_cur], arr_y[idx_next]]
if i >= len(arr_x) - step_point:
idx_first = i - step_point
idx_cur = i
idx_next = j
input_x = [arr_x[idx_first], arr_x[idx_cur], arr_x[idx_next]]
input_y = [arr_y[idx_first], arr_y[idx_cur], arr_y[idx_next]]
j += 1
kappa, norm_direction = PJcurvature(input_x, input_y)
if kappa > 0.1:
po.append([arr_x[idx_cur], arr_y[idx_cur]])
ka.append(kappa)
no.append(norm_direction)
# cv2.circle(img_c3, (arr_y[idx_cur], arr_x[idx_cur]), 1, (0, 0, 255), -1)
# 显示曲率方向
# po = np.array(po)
# no = np.array(no)
# ka = np.array(ka)
# plt.imshow(img_c3)
# plt.quiver(po[:,1], po[:,0], ka*no[:,0],ka*no[:,1], color='r', angles='uv',scale_units='xy',scale=0.01) # uv表示方向, xy位置参数,此时uv表示其增量
# plt.show()
# cv2.imshow('img', img_c3)
# cv2.waitKey(0)
# 求得每个区率曲率最大的点
x = po[:, 0]
y = po[:, 1]
arr_1 = []
arr_2 = []
arr_3 = []
x1 = x[0]
y1 = y[0]
arr_1.append([x1, y1])
for i in range(1, len(x)):
x2 = x[i]
y2 = y[i]
d = euclidean_Dis(x1, y1, x2, y2)
if d < 10:
arr_1.append([x2, y2])
else:
arr_2.append([x2, y2])
arr_2 = np.array(arr_2)
array_x = arr_2[:, 0]
array_y = arr_2[:, 1]
arr_4 = []
point_x1 = array_x[0]
point_y1 = array_y[0]
arr_4.append([point_x1, point_y1])
for j in range(1, len(array_x)):
point_x2 = array_x[j]
point_y2 = array_y[j]
d1 = euclidean_Dis(point_x1, point_y1, point_x2, point_y2)
if d1 < 10:
arr_4.append([point_x2, point_y2])
else:
arr_3.append([point_x2, point_y2])
# 获取三个区域的数组 心尖和二尖瓣
cls_1 = arr_1
cls_2 = arr_3
cls_3 = arr_4
# 找到每个区域中曲率最大的值
cls_1 = np.array(cls_1)
cls_2 = np.array(cls_2)
cls_3 = np.array(cls_3)
cls_1_arrp = []
cls_2_arrp = []
cls_3_arrp = []
cls_1_pos = []
cls_2_pos = []
cls_3_pos = []
for i in range(len(ka)):
if po[i] in cls_1:
cls_1_arrp.append(ka[i])
cls_1_pos.append(po[i])
if po[i] in cls_2:
cls_2_arrp.append(ka[i])
cls_2_pos.append(po[i])
if po[i] in cls_3:
cls_3_arrp.append(ka[i])
cls_3_pos.append(po[i])
cls_1_arrp = np.array(cls_1_arrp)
cls_2_arrp = np.array(cls_2_arrp)
cls_3_arrp = np.array(cls_3_arrp)
cls_1_maxp = cls_1_arrp.max()
cls_2_maxp = cls_2_arrp.max()
cls_3_maxp = cls_3_arrp.max()
for i in range(len(cls_1_arrp)):
if cls_1_arrp[i] == cls_1_maxp:
cls_1_max_pos = cls_1_pos[i]
for i in range(len(cls_2_arrp)):
if cls_2_arrp[i] == cls_2_maxp:
cls_2_max_pos = cls_2_pos[i]
for i in range(len(cls_3_arrp)):
if cls_3_arrp[i] == cls_3_maxp:
cls_3_max_pos = cls_3_pos[i]
final_pos = np.array([cls_1_max_pos, cls_2_max_pos, cls_3_max_pos])
for i in range(3):
final_x, final_y = final_pos[i][0], final_pos[i][1]
cv2.circle(img_c3, (final_y, final_x), 1, (0, 0, 255), -1)
cv2.imshow('img', img_c3)
cv2.waitKey(0)