工作说明:
本程序用于存储一类有着不高于12张的图片数据集,共分为两张数据表 第一张数据表包括id名以及12张图片的二进制数据 第二张图片包括id(和上一张id对应),图片类型(指静脉等),图片数量,数据来源,数据来源id(用于快速检索),width,length,平均灰度,灰度标准差,信息熵 此方法主要用于将大量的图片存储到一个数据库中,并能够实现快速地检索
第一步:连接数据库,构建父表和子表
import pymssql
import os
import cv2
import numpy as np
conn = pymssql.connect(server='LAPTOP-UITU4HR1', user='00', password='00', database='database')
cursor = conn.cursor() # 确认并定位光标位置
# 存储图片的表 16个数据
# 包括图片标签,图片类型,类型id,图片数量,12张图片
cursor.execute("""
if object_id('database_photo','u') is not NULL
drop table database_photo
create table database_photo(
label int not NULL,type varchar(20),type_id int,number int,
p1 image,p2 image,p3 image,p4 image,
p5 image,p6 image,p7 image,p8 image,
p9 image,p10 image,p11 image,p12 image,
primary key(label)
)
""")
# 存储每张图片的信息 11个数据
# 包括id ,图片标签,图片类型id,图片序号,来源,来源id,分辨率,平均灰度,灰度标准差,信息熵
cursor.execute("""
if object_id('database_information','u') is not NULL
drop table database_information
create table database_information(
id int not NULL,label int,type_id int,number int,
source varchar(20),source_id int,width int,length int,
average_gray int,gray_standard int,comentropy int,
primary key(id)
)
""")
代码解释:该步骤一方面连接了数据库(对此有疑惑可参考博主上期文章),另一方面构建了主表和子表。这里值得注意的是构建的父表和子表中包含着整型,字符型等,不同类型的数据杂糅在一块应该是这类表构建时容易引发问题的重要方面。
第二步:获取图片地址,填充父表和子表需要的内容
def information_insert(source_path, photo_type, source):
INF = information() # 声明类
dirs = os.listdir(source_path)
i_number_photo = 1
i = 1
for dir in dirs:
dir_path = os.path.join(source_path, dir)
photo_name = os.listdir(dir_path)
img = [None for _ in range(16)] # 父表行信息,用空填充父表,保证父表列数
img_information = [None for _ in range(11)] # 子表行信息,用空填充子表,保证子表列数
# 存储img,img_information的初始数值
img[0], img[1], img[2], img[3] = i, photo_type, INF.type_id(photo_type), len(photo_name)
img_information[1], img_information[2], img_information[4], img_information[5] = \
i, INF.type_id(photo_type), source, INF.source_id(source)
for j in range(len(photo_name)):
# 用于图片的填充
img_path = os.path.join(dir_path, photo_name[j])
photo = cv2.imread(img_path,0)
photo_open = open(img_path, 'rb')
img[j + 4] = photo_open.read()
photo_open.close()
# 用于信息的填充
width, length = photo.shape # 分辨率,图片的长和宽
average_gray, gray_standard = cv2.meanStdDev(photo) # 平均灰度,灰度标准差
img_information[0],img_information[3],img_information[6],img_information[7],img_information[8],img_information[9],img_information[10]= \
i_number_photo,j+1,width,length,int(average_gray),int(gray_standard),int(INF.comentropy(photo))
# 将每张图片信息存入一行表中
cursor.executemany(
"insert into database_information values (%d,%d,%d,%d,%s,%d,%d,%d,%d,%d,%d)",
[(img_information[0], img_information[1], img_information[2], img_information[3], img_information[4],
img_information[5], img_information[6], img_information[7], img_information[8], img_information[9],
img_information[10])]
)
conn.commit()
i_number_photo = i_number_photo + 1
# 将一类图片存入一行表中
for k in range(len(img)):
print(type(img[k]))
cursor.executemany(
"insert into database_photo values (%d,%s,%d,%d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)",
[(img[0], img[1], img[2], img[3], img[4], img[5], img[6], img[7], img[8], img[9], img[10], img[11],
img[12], img[13], img[14], img[15])]
)
conn.commit()
i = i + 1
print('--------------已存入{}类图片-------------'.format(i))
代码解释:此处工作包括图片地址的提取,图片部分信息的直接赋予(此处博主演示时为简化代码每次插入的一个文件夹的图片的来源以及类型是保持一致的,当遇到实际问题时可增加函数来进行判定后再进行相关数据的插入),图片信息的存储。这一块要注意的是表列数与信息量要保持一致,并且数据类型与返回值代号保持一致
class information():
# 获取类别id
def type_id(self, type_name):
if type_name == 'finger_vein': # 指静脉
return 0
elif type_name == 'knuckle_pattern': # 指节纹
return 1
elif type_name == 'palm_prints': # 掌纹
return 2
# 获取来源id
def source_id(self, source):
if source == '浙江工业大学':
return 0
elif source == '山东大学':
return 1
elif source == '中国科技大学':
return 2
elif source == '香港理工大学':
return 3
else:
return 4
# 获取信息熵
def comentropy(self,img):
N = 1 # 设置邻域属性,目标点周围1个像素点设置为邻域,九宫格,如果为2就是25宫格...
S = img.shape
IJ = []
# 计算j
for row in range(S[0]):
for col in range(S[1]):
Left_x = np.max([0, col - N])
Right_x = np.min([S[1], col + N + 1])
up_y = np.max([0, row - N])
down_y = np.min([S[0], row + N + 1])
region = img[up_y:down_y, Left_x:Right_x] # 九宫格区域
j = (np.sum(region) - img[row][col]) / ((2 * N + 1) ** 2 - 1)
IJ.append([img[row][col], j])
# 计算F(i,j)
F = []
arr = [list(i) for i in set(tuple(j) for j in IJ)] # 去重,会改变顺序,不过此处不影响
for i in range(len(arr)):
F.append(IJ.count(arr[i]))
# 计算pij
P = np.array(F) / (img.shape[0] * img.shape[1]) # 也是img的W*H
# 计算熵
E = np.sum([p * np.log2(1 / p) for p in P])
return E
代码解释:该代码为数据信息填充的一个类,这些类是为了获取相关的信息数据
第三步:主程序
source_path = r"D:\lab_finger\photo_zhangwen\photo_ma" + '\\'
photo_type = 'palm_prints'
source = 'ma'
information_insert(source_path,photo_type,source)
conn.close()
代码解释:输入文件夹地址,图片类型以及来源,并应用函数,最后关闭连接即可。