下载图片

首先你得先下图片,下图片,下图片…… 这里推荐一个插件

image.png

比如我想要找紫藤的图片,就百度:紫藤
可以多加载几页,一起下载下来
**
image.png

我下载了 1000 张紫藤,1000 张玫瑰,分别放在 0 和 1 文件夹中

image.png

整理加工图片

下载完成之后需要人工筛选一下,里面会夹杂一些乱七八糟的图片,以及主体不是目标的图片,筛选两三遍,最后可能也就找几百张,像前面别人做好的数据集那样一下 60000 张可麻烦了,可以用一些方法让他们翻倍,比如改变一下图片的亮度、对比度、把图片左右反转一下等等

先来看一下对图片的处理,写几个函数到时候调用就可以,需要用到 PIL 的 ImageEnhance 模块,其中的 enhance 的参数可以理解为百分比,1.2 就是 120%,也就是调大了,0.8 就是 80%,也就是调小了

  1. import os
  2. from PIL import Image, ImageEnhance
  3. #左右翻转
  4. def turn_left_right(img):
  5. return img.transpose(Image.FLIP_LEFT_RIGHT)
  6. #改变图片亮度
  7. def brighten_darken(img, val):
  8. return ImageEnhance.Brightness(img).enhance(val)
  9. #改变图片饱和度
  10. def saturation_up_down(img, val):
  11. return ImageEnhance.Color(img).enhance(val)
  12. #改变图片对比度
  13. def contrast_up_down(img, val):
  14. return ImageEnhance.Contrast(img).enhance(val)
  15. #改变图片锐度
  16. def sharpness_up_down(img, val):
  17. return ImageEnhance.Sharpness(img).enhance(val)

上面写完了对图片进行调整的函数,再来写个函数把文件夹下的所有图片都进行调整

  1. def picture_enhance(dir):
  2. img_list = os.listdir(dir) #把要操作的目录传进来,使用os.listdir获得文件列表
  3. for i in range(len(img_list)):
  4. try:
  5. img = Image.open(dir + '\\' + img_list[i]) #挨个打开
  6. temp = str(i)
  7. #convert('RGB')是为了抛弃透明度之类的没用的信息
  8. turn_left_right(img).convert('RGB').save(dir + '\\turn_left_right' + temp + '.jpg')
  9. brighten_darken(img, 1.2).convert('RGB').save(dir + '\\brighten' + temp + '_1' + '.jpg')
  10. brighten_darken(img, 1.4).convert('RGB').save(dir + '\\brighten' + temp + '_2' + '.jpg')
  11. brighten_darken(img, 0.8).convert('RGB').save(dir + '\\darken' + temp + '_1' + '.jpg')
  12. brighten_darken(img, 0.6).convert('RGB').save(dir + '\\darken' + temp + '_2' + '.jpg')
  13. saturation_up_down(img, 1.2).convert('RGB').save(dir + '\\saturation_up' + temp + '_1' + '.jpg')
  14. saturation_up_down(img, 1.4).convert('RGB').save(dir + '\\saturation_up' + temp + '_2' + '.jpg')
  15. saturation_up_down(img, 0.8).convert('RGB').save(dir + '\\saturation_down' + temp + '_1' + '.jpg')
  16. saturation_up_down(img, 0.6).convert('RGB').save(dir + '\\saturation_down' + temp + '_2' + '.jpg')
  17. contrast_up_down(img, 1.2).convert('RGB').save(dir + '\\contrast_up' + temp + '_1' + '.jpg')
  18. contrast_up_down(img, 1.4).convert('RGB').save(dir + '\\contrast_up' + temp + '_2' + '.jpg')
  19. contrast_up_down(img, 0.8).convert('RGB').save(dir + '\\contrast_down' + temp + '_1' + '.jpg')
  20. contrast_up_down(img, 0.6).convert('RGB').save(dir + '\\contrast_down' + temp + '_2' + '.jpg')
  21. sharpness_up_down(img, 1.2).convert('RGB').save(dir + '\\sharpness_up' + temp + '_1' + '.jpg')
  22. sharpness_up_down(img, 1.4).convert('RGB').save(dir + '\\sharpness_up' + temp + '_2' + '.jpg')
  23. sharpness_up_down(img, 0.8).convert('RGB').save(dir + '\\sharpness_down' + temp + '_1' + '.jpg')
  24. sharpness_up_down(img, 0.6).convert('RGB').save(dir + '\\sharpness_down' + temp + '_2' + '.jpg')
  25. except:
  26. pass
  27. picture_enhance('D:\\anquan\\deeplearn\\my_flower\\0')
  28. picture_enhance('D:\\anquan\\deeplearn\\my_flower\\1')

经过这个函数,一张图片会再保存出来 17 张,上面这个步骤处理完成之后每种花就会得到 18000 张图片

给图片打标签

先编写个函数,在每个文件夹下面生成一个 list.txt,内容是图片的路径加标签,对于放紫藤图片的文件夹就是:图片地址 0 然后统一整理到一起

image.png

  1. def generate_list(dir, label):
  2. files = os.listdir(dir)
  3. listText = open(dir + '\\' + 'list.txt', 'w')
  4. for file in files:
  5. name_label = dir + '\\' + file + ' ' + str(int(label)) + '\n' #路径\\文件名 标签 name_label:就是我们项写入到list.txt里面的内容
  6. listText.write(name_label)
  7. listText.close()
  8. generate_list('D:\\anquan\\deeplearn\\my_flower\\0', 0)
  9. generate_list('D:\\anquan\\deeplearn\\my_flower\\1', 1)
  10. #统一整理到上层文件夹的list.txt
  11. file = open('D:\\anquan\\deeplearn\\my_flower\\list.txt', 'w')
  12. file0 = open('D:\\anquan\\deeplearn\\my_flower\\0\\list.txt', 'r')
  13. file1 = open('D:\\anquan\\deeplearn\\my_flower\\1\\list.txt', 'r')
  14. roses_list = []
  15. for i in file0.readlines():
  16. file.write(i)
  17. sunflowers_list = []
  18. for i in file1.readlines():
  19. file.write(i)
  20. file0.close()
  21. file1.close()
  22. file.close()

制作数据集

读取 list.txt 中的图片,作为数据,后面的作为标签,保存为 npz 数据集

  1. import os
  2. from PIL import Image, ImageEnhance
  3. import numpy as np
  4. #编写一个函数,读取list.txt并返回图片数据和标签
  5. def readData(txt_path):
  6. list_file = open(txt_path, 'r')
  7. content = list_file.readlines() #读取list.txt里面的所有内容,并存储到content
  8. image = []#数据
  9. label = []#标签
  10. for i in range(len(content)):
  11. try:
  12. line = content[i]
  13. img = Image.open(line.split()[0])
  14. #line.split()默认以空格作为分割,line.split()[0]表示图片,line.split()[1]表示标签
  15. img = img.convert('RGB').resize((64,64), Image.ANTIALIAS)
  16. #制作数据集为64*64的图片,Image.ANTIALIAS表示压缩过程中尽量保持图片质量
  17. img = np.array(img)
  18. image.append(img)
  19. line.split()[1] = np.array(int(line.split()[1]))
  20. label.append(line.split()[1])
  21. except:
  22. pass #emmmm 图片名不要带中文的括号呀
  23. image_np_array = np.array(image)
  24. label_np_array = np.array(label)
  25. return (image_np_array, label_np_array)
  26. (data_image, data_label) = readData('D:\\anquan\\deeplearn\\my_flower\\list.txt')
  27. np.savez('Wisteria_Roses_DataSet_64.npz', train_image = data_image, train_label = data_label)

最后生成的数据集 400 多 MB

image.png

处理数据

之前保存出来的数据集可以这样导入

  1. dataset = np.load('Wisteria_Roses_DataSet_64.npz')
  2. image = dataset['train_image']
  3. label = dataset['train_label']

首先我们要分出一些来作为训练数据跟测试数据,现在我们有 18000*2,可以每种分出15000 作为训练数据,剩下的 3000 作为测试数据

  1. train_image_0 = []
  2. train_label_0 = []
  3. train_image_1 = []
  4. train_label_1 = []
  5. test_image = []
  6. test_label = []
  7. for i in range(len(image)):
  8. if (label[i] == '0') & (len(train_label_0) < 15000): #标签为0的前15000作为训练数据
  9. train_image_0.append(image[i])
  10. train_label_0.append(label[i])
  11. continue
  12. if (label[i] == '1') & (len(train_label_1) < 15000): #标签为1的前15000作为训练数据
  13. train_image_1.append(image[i])
  14. train_label_1.append(label[i])
  15. continue
  16. test_image.append(image[i]) #剩余3000+3000 = 6000作为测试数据
  17. test_label.append(label[i])
  18. train_image_0 = np.array([train_image_0])
  19. train_image_0 = np.squeeze(train_image_0)
  20. train_label_0 = np.array([train_label_0])
  21. train_label_0 = np.squeeze(train_label_0)
  22. train_image_1 = np.array([train_image_1])
  23. train_image_1 = np.squeeze(train_image_1)
  24. train_label_1 = np.array([train_label_1])
  25. train_label_1 = np.squeeze(train_label_1)
  26. test_image = np.array([test_image])
  27. test_image = np.squeeze(test_image)
  28. test_label = np.array([test_label])
  29. test_label = np.squeeze(test_label)

image.png

数据归一化、一位有效编码

  1. train_image_normalize = train_image.astype(float) / 255
  2. train_label_onehotencoding = np_utils.to_categorical(train_label)
  3. valid_image_normalize = valid_image.astype(float) / 255
  4. valid_label_onehotencoding = np_utils.to_categorical(valid_label)
  5. test_image_normalize = test_image.astype(float) / 255
  6. test_label_onehotencoding = np_utils.to_categorical(test_label)

建立模型并训练

  1. model = Sequential()
  2. model.add(Conv2D(filters=32,kernel_size=(3,3), padding='same', input_shape=(64,64,3), activation='relu'))
  3. model.add(MaxPooling2D(pool_size=(2,2)))
  4. model.add(Conv2D(filters=16,kernel_size=(3,3), padding='same', activation='relu'))
  5. model.add(MaxPooling2D(pool_size=(2,2)))
  6. model.add(Dropout(0.5))
  7. model.add(Flatten())
  8. model.add(Dropout(0.25))
  9. model.add(Dense(units=2, kernel_initializer='normal', activation='softmax'))
  10. model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
  11. #shuffle=Ture 表示随机取训练样本,避免某一分类过多训练
  12. train_history = model.fit(train_image_normalize, train_label_onehotencoding, validation_data=(valid_image_normalize, valid_label_onehotencoding), shuffle=True,epochs=20, batch_size=200, verbose=2)
  13. #验证模型准确率
  14. scores = model.evaluate(test_image_normalize, test_label_onehotencoding)
  15. print(scores)

自己选点图片预测

  1. import numpy as np
  2. from PIL import Image
  3. from keras.models import load_model
  4. my_model = load_model('Wisteria_Roses.h5')
  5. img = Image.open('3.jpg')
  6. img = img.resize((64,64), Image.ANTIALIAS)
  7. number_data = img.getdata()
  8. number_data_array = np.array(number_data)
  9. number_data_array = number_data_array.reshape(1, 64, 64, 3).astype(float)
  10. number_data_array_normalize = number_data_array / 255
  11. prediction = my_model.predict(number_data_array_normalize)
  12. index = np.argmax(prediction)
  13. if index == 0:
  14. print('紫藤')
  15. elif index == 1:
  16. print('玫瑰')

image.png

这张图片里的紫色的花应该是葡萄风信子(支付宝识别的)

image.png