测试图片:
import cv2
import numpy as np
import math
from copy import deepcopy
# 构建样本数据集 水果--1 背景--0
def Dataset():
# R G B
samples_data = [[180,123,94],[219,115,76],[217,115,75],
[216,114,74],[215,113,73],[156,93,62],
[174,113,84],[214,112,72],[214,112,72],
[214,112,72],[174,113,84],[176,115,86],
[184,125,95],[186,127,97],[180,123,94],
[194,205,209],[179,175,166],[191,202,206],
[191,202,206],[192,203,207],[176,172,163]]
class_lable = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0] #类别标签 15水果 6 背景
return samples_data,class_lable
# 根据样本估计均值向量
# 得到三维均值向量
# 均值向量存储形式 R G B
def Get_Junzhi(samples_data,class_lable):
L = len(samples_data)
m = 0 # 水果
n = 0 # 背景
r1 = 0
g1 = 0
b1 = 0
r0 = 0
g0 = 0
b0 = 0
mv = [0]
mean_vector1 = [mv]*3
mean_vector0 = [mv]*3
for i in range(L):
if class_lable[i] == 1:
m += 1
else:
n += 1
for i in range(L):
if i < m:
r1 += samples_data[i][0]
g1 += samples_data[i][1]
b1 += samples_data[i][2]
else:
r0 += samples_data[i][0]
g0 += samples_data[i][1]
b0 += samples_data[i][2]
mean_vector1 = [[int(r1/m)],[int(g1/m)],[int(b1/m)]] # 三维均值向量
mean_vector0 = [[int(r0/n)],[int(g0/n)],[int(b0/n)]]
#print(mean_vector1)
#print(mean_vector0)
return mean_vector1,mean_vector0
# 计算协方差矩阵
def Get_Cov(samples_data,mean_vector1,mean_vector0):
L= len(samples_data)
m = 15
n = 6
cov = [0]*3
Cov_1 = [cov]*3
Cov_0 = [cov]*3
cov_bb1 = 0
cov_gb1 = 0
cov_gg1 = 0
cov_rb1 = 0
cov_rg1 = 0
cov_rr1 = 0
cov_bb0 = 0
cov_gb0 = 0
cov_gg0 = 0
cov_rb0 = 0
cov_rg0 = 0
cov_rr0 = 0
for i in range(L):
if i < m:
cov_rr1 += (samples_data[i][0]-mean_vector1[0][0])*(samples_data[i][0]-mean_vector1[0][0])
cov_rg1 += (samples_data[i][0]-mean_vector1[0][0])*(samples_data[i][1]-mean_vector1[1][0])
cov_rb1 += (samples_data[i][0]-mean_vector1[0][0])*(samples_data[i][2]-mean_vector1[2][0])
cov_gg1 += (samples_data[i][1]-mean_vector1[1][0])*(samples_data[i][1]-mean_vector1[1][0])
cov_gb1 += (samples_data[i][1]-mean_vector1[1][0])*(samples_data[i][2]-mean_vector1[2][0])
cov_bb1 += (samples_data[i][2]-mean_vector1[2][0])*(samples_data[i][2]-mean_vector1[2][0])
else:
cov_rr0 += (samples_data[i][0] - mean_vector0[0][0]) * (samples_data[i][0] - mean_vector0[0][0])
cov_rg0 += (samples_data[i][0] - mean_vector0[0][0]) * (samples_data[i][1] - mean_vector0[1][0])
cov_rb0 += (samples_data[i][0] - mean_vector0[0][0]) * (samples_data[i][2] - mean_vector0[2][0])
cov_gg0 += (samples_data[i][1] - mean_vector0[1][0]) * (samples_data[i][1] - mean_vector0[1][0])
cov_gb0 += (samples_data[i][1] - mean_vector0[1][0]) * (samples_data[i][2] - mean_vector0[2][0])
cov_bb0 += (samples_data[i][2] - mean_vector0[2][0]) * (samples_data[i][2] - mean_vector0[2][0])
a = m-1
b = n-1
Cov_1 = [[cov_rr1/a,cov_rg1/a,cov_rb1/a],[cov_rg1/a,cov_gg1/a,cov_gb1/a],[cov_rb1/a,cov_gb1/a,cov_bb1/a]]
Cov_0 = [[cov_rr0/b,cov_rg0/b,cov_rb0/b],[cov_rg0/b,cov_gg0/b,cov_gb0/b],[cov_rb0/b,cov_gb0/b,cov_bb0/b]]
return Cov_1, Cov_0
# 计算矩阵的逆
# 计算矩阵行列式
# 代入对数似然函数中,求对数
def Get_Inverse(mean_vector1, mean_vector0, Cov_1, Cov_0, test_data):
Inv_1 = np.linalg.inv(Cov_1) # 逆矩阵
Inv_0 = np.linalg.inv(Cov_0)
rows_1 = np.linalg.det(Cov_1) #行列式
rows_0 = np.linalg.det(Cov_0)
L = len(test_data)
a1 = [[0], [0], [0]] # 存储 x - 均值向量的值
a0 = [[0], [0], [0]]
b1 = [0, 0, 0] # 转置
b0 = [0, 0, 0]
for i in range(L):
a1[i][0] = test_data[i][0] -mean_vector1[i][0]
a0[i][0] = test_data[i][0] - mean_vector0[i][0]
b1[i] = a1[i][0] # 求 a 的转置
b0[i] = a0[i][0]
#计算转置*逆矩阵*差
m1 = np.dot(b1,Inv_1)
M1 = np.dot(m1,a1)
m0 = np.dot(b0,Inv_0)
M0 = np.dot(m0,a0)
P1 = 0.5* (math.log(rows_1) + M1 + 3*math.log(2*math.pi))
P0 = 0.5* (math.log(rows_0) + M0 + 3*math.log(2*math.pi))
# print(P1)
# print(P0)
return P1, P0
# 判断类别
def Get_Classify(P1, P0):
if P1 >= P0:
print('该样本是背景')
else:
print('该样本是水果')
# 读取测试图片的RGB,把BGR->RGB
# 并把每个像元转为3行1列的向量
def Get_RGB(image):
w = image.shape[0]
h = image.shape[1]
data = []
ve = [[0] for i in range(3)]
new_data = [ve for i in range(w*h)]
for i in range(w):
for j in range(h):
for k in range(1): # B G 调换
a = image[i,j,k+0]
image[i,j,k+0] = image[i,j,k+2]
image[i,j,k+2] = a
# print(image)
for i in range(w):
for j in range(h):
new_data[i*h+j][0][0] = image[i][j][0]
new_data[i*h+j][1][0] = image[i][j][1]
new_data[i*h+j][2][0] = image[i][j][2]
V = deepcopy(ve)
data.append(V)
return data
# 把图片的RGB传进来对每一个像素做分类 水果赋值180,背景赋值[74,114,216]
def Get_Cla_Image(test_image,image):
sam, clas = Dataset()
mv1, mv0 = Get_Junzhi(sam, clas)
Cov_1, Cov_0 = Get_Cov(sam, mv1, mv0)
w = image.shape[0]
h = image.shape[1]
for i in range(w):
for j in range(h):
P1, P0 = Get_Inverse(mv1, mv0, Cov_1, Cov_0, test_image[i*h+j])
if P1 >= P0:
image[i][j] = 255
else:
image[i][j][0] = 74 # 74,114,216 这里图片是RGB形式
image[i][j][1] = 114 # 赋值时需要注意
image[i][j][2] = 216
return image
image = cv2.imread('testJuzi1.jpg') # 缩小后的图
test_image = Get_RGB(image)
Cla_image = Get_Cla_Image(test_image, image)
cv2.imshow('Bayes',Cla_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
'''
test_data = [[216],[114],[74]]
sam, clas = Dataset()
mv1, mv0 = Get_Junzhi(sam,clas)
print('水果样本均值向量为:',mv1)
print('背景样本均值向量为:',mv0)
Cov_1, Cov_0 = Get_Cov(sam,mv1,mv0)
print('水果的协方差矩阵为:',Cov_1)
print('背景的协方差矩阵为:',Cov_0)
P1, P0 = Get_Inverse(mv1, mv0, Cov_1, Cov_0, test_data)
'''
'''
print('水果协方差矩阵的逆矩阵为:','\n',Inv_1)
print('背景协方差矩阵的逆矩阵为:','\n',Inv_0)
print('水果协方差矩阵的行列式为:','\n',rows_1)
print('背景协方差矩阵的行列式为:','\n',rows_0)
Get_Classify(P1, P0)
'''