opencv训练模型如何移植到嵌入式(用OpenCV训练一个高斯混合模型GMM)
opencv训练模型如何移植到嵌入式(用OpenCV训练一个高斯混合模型GMM)也演示了如何可视化高斯混合模型,也演示了调用opencv 来使用EM算法的过程,这里例子,不仅演示了高斯分布的公式实现,还演示了如果用高斯分布生成高斯分布的样本点,
这里给出一个例子:
1 随机生成混合高斯分布模型A,并用高斯分布生成样本点
2 利用样本点,用EM算法求出最能描述这些点的混合高斯分布模型B
3 比较模型A和模型B
这里例子,
不仅演示了高斯分布的公式实现,
还演示了如果用高斯分布生成高斯分布的样本点,
也演示了调用opencv 来使用EM算法的过程,
也演示了如何可视化高斯混合模型,
短小精悍,干货满满,经典收藏。
首先看下代码将高斯分布可视化的结果:
图1 5个高斯分布
图1 中,绿色圈为生成样本用的高斯分布。红色圈为用样本估计的高斯分布。这里我们混合高斯模型中,一共有5个高斯模型。
重新运行一次的结果:
图2 5个高斯分布
图3 9个高斯分布
图4 15个高斯分布
#!/usr/bin/env python
# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3
if PY3:
xrange = range
import numpy as np
import cv2 as cv
from numpy import random
def make_gaussians(cluster_n img_size):
points = []
ref_distrs = []
# 随机生成cluster_n个混合高斯模型
for _i in xrange(cluster_n):
#随机生成高斯模型的均值
mean = (0.1 0.8*random.rand(2)) * img_size
#随机生成高斯模型的方差
a = (random.rand(2 2)-0.5)*img_size*0.1
cov = np.dot(a.T a) img_size*0.05*np.eye(2)
n = 100 random.randint(900)
# 生成当前高斯分布对应的随机点,用于后续训练
pts = random.multivariate_normal(mean cov n)
points.append( pts )
# 记录高斯分布的参数,等下于我们求出的参数进行比较
ref_distrs.append( (mean cov) )
points = np.float32( np.vstack(points) )
return points ref_distrs
def draw_gaussain(img mean cov color):
# 高斯模型的中心点
x y = np.int32(mean)
# 用方差得到高斯模型的点的分布范围椭圆点s1 s2
w u _vt = cv.SVDecomp(cov)
ang = np.arctan2(u[1 0] u[0 0])*(180/np.pi)
s1 s2 = np.sqrt(w)*3.0
# 绘制椭圆代表高斯分布的分布范围
cv.ellipse(img (x y) (s1 s2) ang 0 360 color 1 cv.LINE_AA)
def main():
cluster_n = 5
img_size = 512
print('press any key to update distributions ESC - exit\n')
while True:
print('sampling distributions...')
# 初始化生成混合高斯分布模型
points ref_distrs = make_gaussians(cluster_n img_size)
#使用EM算法求解高斯模型参数:均值,方差等
print('EM (opencv) ...')
em = cv.ml.EM_create()
em.setClustersNumber(cluster_n)
em.setCovarianceMatrixType(cv.ml.EM_COV_MAT_GENERIC)
em.trainEM(points)
# 均值
means = em.getMeans()
# 方差
covs = em.getCovs() # Known bug: https://github.com/opencv/opencv/pull/4232
found_distrs = zip(means covs)
print('ready!\n')
img = np.zeros((img_size img_size 3) np.uint8)
for x y in np.int32(points):
cv.circle(img (x y) 1 (255 255 255) -1)
# 绘制产生数据的高斯分布
for m cov in ref_distrs:
draw_gaussain(img m cov (0 255 0))
# 绘制EM算法求出的高斯分布,并于原高斯分布进行比较
for m cov in found_distrs:
draw_gaussain(img m cov (0 0 255))
cv.imshow('gaussian mixture' img)
ch = cv.waitKey(0)
if ch == 27:
break
print('Done')
if __name__ == '__main__':
print(__doc__)
main()
cv.destroyAllWindows()