我想基于给定数量类别的输入训练样本,对RGB图像进行像素分类。例如,我有4个类别,每个类别包含(r,g,b)像素,因此目标是将图像分割成四个部分。
我发现Python OpenCV2中有期望最大化算法,可以完成这项工作。但遗憾的是,我没有找到任何教程或材料来解释(因为我是初学者)如何使用该算法。
您能推荐任何可以作为起点的教程吗?
更新…下面代码的另一种方法:
**def getsamples(img): x, y, z = img.shape samples = np.empty([x * y, z]) index = 0 for i in range(x): for j in range(y): samples[index] = img[i, j] index += 1 return samplesdef EMSegmentation(img, no_of_clusters=2): output = img.copy() colors = np.array([[0, 11, 111], [22, 22, 22]]) samples = getsamples(img) #em = cv2.ml.EM_create() em = cv2.EM(no_of_clusters) #em.setClustersNumber(no_of_clusters) #em.trainEM(samples) em.train(samples) x, y, z = img.shape index = 0 for i in range(x): for j in range(y): result = em.predict(samples[index])[0][1] #print(result) output[i][j] = colors[result] index = index + 1 return outputimg = cv2.imread('00.jpg')smallImg = small = cv2.resize(img, (0,0), fx=0.5, fy=0.5) output = EMSegmentation(img)smallOutput = cv2.resize(output, (0,0), fx=0.5, fy=0.5) cv2.imshow('image', smallImg)cv2.imshow('EM', smallOutput)cv2.waitKey(0)cv2.destroyAllWindows()**
回答:
将C++转换为Python 来源
import cv2import numpy as npdef getsamples(img): x, y, z = img.shape samples = np.empty([x * y, z]) index = 0 for i in range(x): for j in range(y): samples[index] = img[i, j] index += 1 return samplesdef EMSegmentation(img, no_of_clusters=2): output = img.copy() colors = np.array([[0, 11, 111], [22, 22, 22]]) samples = getsamples(img) em = cv2.ml.EM_create() em.setClustersNumber(no_of_clusters) em.trainEM(samples) means = em.getMeans() covs = em.getCovs() # 已知错误:https://github.com/opencv/opencv/pull/4232 x, y, z = img.shape distance = [0] * no_of_clusters for i in range(x): for j in range(y): for k in range(no_of_clusters): diff = img[i, j] - means[k] distance[k] = abs(np.dot(np.dot(diff, covs[k]), diff.T)) output[i][j] = colors[distance.index(max(distance))] return outputimg = cv2.imread('dinosaur.jpg')output = EMSegmentation(img)cv2.imshow('image', img)cv2.imshow('EM', output)cv2.waitKey(0)cv2.destroyAllWindows()