图像二值化之后,可以用cv2.CHAIN_APPROX_NONE或者cv2.CHAIN_APPROX_SIMPLE两种函数,NONE得到的是所有图像轮廓点,而SIMPLE得到的是“重要的点”,这个可以搜索该函数有详细的算法介绍。我用的NONE得到所有的像素点,并将其以csv格式保存。
再对上面保存的csv文件读取,进行B样条曲线拟合。可以修改拟合点的数量。
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import csv
from matplotlib.patches import Circle
from scipy.spatial.distance import pdist
import pandas as pd
from time import process_time
from time import time
#读取图像轮廓曲线(None/Simple),并进行B样条曲线拟合,可以设置确定数量的点来拟合(100个或者合适的点数量来拟合图像轮廓)
# 以准确率最高为准,并在此基础上求图像轮廓曲线的曲率。根据曲率的大小设置合适的参考值,也可称阈值来求得分叉点,输出分叉位置坐标
#以下代码是通过读取contours函数保存的csv文件进行B样条曲线拟合,并保存拟合后的csv取像,再读取相应的csv文件来求曲率,并得到曲率数值
#保存为csv文件,最终的程序可以选择通过读取保存csv文件作为中间步骤,但在时间上可以减少该步骤,从而减少程序运行的时间。
class BS_curve(object):
def __init__(self, n, p, cp=None, knots=None):
self.n = n # n+1 control points >>> p0,p1,,,pn
self.p = p
if cp:
self.cp = cp
self.u = knots
self.m = knots.shape[0] - 1 # m+1 knots >>> u0,u1,,,nm
else:
self.cp = None
self.u = None
self.m = None
self.paras = None
def check(self):
if self.m == self.n + self.p + 1:
return 1
else:
return 0
def coeffs(self, uq):
# n+1 control points >>> p0,p1,,,pn
# m+1 knots >>> u0,u1,,,nm
# algorithm is from https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-coef.html
# N[] holds all intermediate and the final results
# in fact N is longer than control points,this is just to hold the intermediate value
# at last, we juest extract a part of N,that is N[0:n+1]
N = np.zeros(self.m + 1, dtype=np.float64)
# rule out special cases Important Properties of clamped B-spline curve
if uq == self.u[0]:
N[0] = 1.0
return N[0:self.n + 1]
elif uq == self.u[self.m]:
N[self.n] = 1.0
return N[0:self.n + 1]
# now u is between