python opencv 中的最大似然像素分类
Maximum likelihood pixel classification in python opencv
我想根据给定数量类的输入训练样本对RGB图像进行像素分类。所以我有例如4 类 包含像素 (r,g,b) 因此目标是将图像分割成四个阶段。
我发现 python opencv2 具有可以完成这项工作的期望最大化算法。但不幸的是,我没有找到任何教程或 material 可以解释我(因为我是初学者)如何使用该算法。
能否请您提出任何类型的教程作为起点?
更新...以下代码的另一种方法:
**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 samples
def 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 output
img = 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 source
import cv2
import numpy as np
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 samples
def 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() # Known bug: 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 output
img = cv2.imread('dinosaur.jpg')
output = EMSegmentation(img)
cv2.imshow('image', img)
cv2.imshow('EM', output)
cv2.waitKey(0)
cv2.destroyAllWindows()
我想根据给定数量类的输入训练样本对RGB图像进行像素分类。所以我有例如4 类 包含像素 (r,g,b) 因此目标是将图像分割成四个阶段。
我发现 python opencv2 具有可以完成这项工作的期望最大化算法。但不幸的是,我没有找到任何教程或 material 可以解释我(因为我是初学者)如何使用该算法。
能否请您提出任何类型的教程作为起点?
更新...以下代码的另一种方法:
**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 samples
def 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 output
img = 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 source
import cv2
import numpy as np
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 samples
def 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() # Known bug: 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 output
img = cv2.imread('dinosaur.jpg')
output = EMSegmentation(img)
cv2.imshow('image', img)
cv2.imshow('EM', output)
cv2.waitKey(0)
cv2.destroyAllWindows()