├── README.md ├── app.py ├── image ├── data.jpg ├── data_.jpg └── data_crop.jpg ├── manage.py ├── mysite ├── settings.py ├── urls.py ├── view.py └── wsgi.py ├── pic ├── 1.png ├── 2.png ├── 3.png ├── 4.png ├── a.jpg ├── 世界名犬名字翻译 └── 哈弗大学狗子种类名称翻译 ├── utils.py ├── vgg15.py ├── vgg16.py ├── yolo ├── yolov3.cfg └── yolov3.txt └── yolo_opencv.py /README.md: -------------------------------------------------------------------------------- 1 | # 这是我在GitHub的第一个项目,很是激动. 2 | 小白一枚,HelloWorld. 3 | 4 | 功能:识别狗的种类(120种). 5 | 6 | 模型训练:数据集用的是斯坦福大学狗子数据集,基础模型是VGG16,正确率在70%左右. 7 | 8 | 应用方式:python Django Web 应用. 9 | 10 | 识别过程:two stage ,先YOLO物体检测出狗在图片中的位置(网上的模型),然后VGG16细致划分. 11 | # 使用 12 | 1、下载VGG16.npy,VGG16.npy放于项目根目录下,yolov3.weights放于yolo目录下。 13 | 14 | vgg16.npy(VGG16模型卷积核和全连接权重偏置) 15 | 16 | 链接:https://pan.baidu.com/s/1-kzh69q25E5mt_0CxHuHsA 17 | 18 | 提取码:m3yo 19 | 20 | vgg15.npy(自己训练的全连接权重和偏置) 21 | 22 | 链接:https://pan.baidu.com/s/1vJvUlZaEMtHJfPh89JMx-A 23 | 24 | 提取码:g0th 25 | 26 | yolov3.weights(YOLO参数) 27 | 28 | 链接:https://pan.baidu.com/s/1-huPnb3_FwUQlxbYHtHtXw 29 | 30 | 提取码:s8y1 31 | 32 | 2、安装相关代码包(我看了一下我的代码包如下所示)。 33 | 34 | tensorflow,opencv-python,scikit-image,django版本无所谓冲突概率很小(我没碰到). 35 | 36 | numpy版本很重要,涉及到VGG16模型数据的加载,最新的numpy不支持这样的加载方式. 37 | 38 | tensorflow 1.3.0 39 | 40 | scikit-image 0.15.0 41 | 42 | opencv-python 4.1.0.25 43 | 44 | numpy 1.16.2 45 | 46 | Django 2.2.1 47 | 48 | 2、控制台输入: 49 | python manage.py runserver 50 | 51 | 52 | 3、结果。 53 | 54 | 选择识别图片效果图: 55 | 56 | ![image](https://github.com/CupsWen/Dog-Identification/blob/master/pic/1.png) 57 | 58 | 加载图片效果图: 59 | ![image](https://github.com/CupsWen/Dog-Identification/blob/master/pic/2.png) 60 | 61 | 62 | YOLO物体检测效果: 63 | ![image](https://github.com/CupsWen/Dog-Identification/blob/master/pic/3.png) 64 | 65 | VGG16分类效果: 66 | ![image](https://github.com/CupsWen/Dog-Identification/blob/master/pic/4.png) 67 | 68 | 4、项目结构. 69 | ``` 70 | ├── image 中间图片存储文件 71 | │ ├── data.jpg 上传图片 72 | | ├── data_.jpg 图片YOLO检查结果缓存 73 | | ├── data_crop.jpg 根据YOLO检查结果剪切图片,用于VGG16识别其种类 74 | │── mysite Web项目文件 75 | │ ├── setting.py web配置文件 76 | │ ├── urls.py 路由配置 77 | │ ├── view.py 路由后的处理逻辑 78 | │ ├── wsgi.py 79 | ├── pic md显示图片 80 | │ ├── 斯坦福大学狗子种类名称翻译 81 | │   ├── 世界名犬名字翻译 82 | ├── template html存储文件 83 | │ ├── index.html 84 | │   ├── vgg.html 85 | │ ├── yolo.html 86 | │   ├── yolo_vgg.html 87 | ├── yolo yolo文件 88 | │ ├── yolov3.cfg 描述文件 89 | │ ├── yolov3.txt 分类class 90 | │ ├── yolov3.weights 模型参数 91 | ├── manage.py django入口文件 92 | ├── utils.py vgg16工具类 93 | ├── vgg15.py vgg16分类class 94 | ├── vgg15.npy 全连接存储文件 95 | ├── vgg16.py vgg16模型加载文件 96 | ├── vgg16.npy vgg16模型数据 97 | ├── yolo_opencv.py yolo使用示例文件 98 | ``` 99 | # 结论 100 | -------------------------------------------------------------------------------- /app.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # 导入相关函数包 3 | import os 4 | 5 | import numpy as np 6 | import tensorflow as tf 7 | import vgg16 as vgg16 8 | import utils as utils 9 | 10 | img_path = input('Input the path and image name:') 11 | img_ready = utils.load_image(img_path) 12 | labels = ['dhole', 'Doberman', 'Yorkshire_terrier','Weimaraner','Bernese_mountain_dog','Pembroke','German_short','English_foxhound','American_Staffordshire_terrier','miniature_pinscher','borzoi','redbone','briard','miniature_poodle','kelpie','schipperke','Bouvier_des_Flandres','Dandie_Dinmont','miniature_schnauzer','Tibetan_mastiff','affenpinscher','Irish_water_spaniel','Scotch_terrier','vizsla','Rottweiler','Blenheim_spaniel','standard_schnauzer','Kerry_blue_terrier','Cardigan','Chihuahua','German_shepherd','Eskimo_dog','whippet','African_hunting_dog','Sussex_spaniel','Shetland_sheepdog','Scottish_deerhound','beagle','bluetick','curly','Appenzeller','Airedale','toy_poodle','Rhodesian_ridgeback','Leonberg','English_springer','chow','boxer','standard_poodle','cairn','English_setter','Siberian_husky','keeshond','Sealyham_terrier','Maltese_dog','Welsh_springer_spaniel','malamute','wire','Great_Dane','Irish_wolfhound','kuvasz','groenendael','bull_mastiff','golden_retriever','Greater_Swiss_Mountain_dog','toy_terrier','Brabancon_griffon','Norwich_terrier','Samoyed','otterhound','giant_schnauzer','Norwegian_elkhound','Great_Pyrenees','papillon','flat','Italian_greyhound','clumber','Bedlington_terrier','Pomeranian','Mexican_hairless','black','Lakeland_terrier','Pekinese','basenji','komondor','silky_terrier','West_Highland_white_terrier','Chesapeake_Bay_retriever','French_bulldog','Newfoundland','pug','Boston_bull','Norfolk_terrier','Saint_Bernard','EntleBucher','Border_terrier','Brittany_spaniel','malinois','Border_collie','Gordon_setter','Australian_terrier','Labrador_retriever','basset','Tibetan_terrier','Staffordshire_bullterrier','Irish_setter','Japanese_spaniel','dingo','Irish_terrier','Saluki','Shih','collie','Old_English_sheepdog','Ibizan_hound','Afghan_hound','soft','Walker_hound','Lhasa','Walker_hound','Lhasa'] 13 | print(len(labels)) 14 | 15 | gpuConfig = tf.ConfigProto(allow_soft_placement=True) 16 | gpuConfig.gpu_options.allow_growth = True 17 | 18 | with tf.Session(config=gpuConfig) as sess: 19 | # 给输入图片占位 20 | images = tf.placeholder(tf.float32, [1, 224, 224, 3]) 21 | # 初始化vgg,读出保存的文件参数 22 | vgg = vgg16.Vgg16() 23 | # 调用前向传播函数,把待识别图片喂入神经网络 24 | vgg.forward(images) 25 | # 运行会话,预测分类结果 26 | probability = sess.run(vgg.prob, feed_dict={images:img_ready}) 27 | top5 = np.argsort(probability[0])[-1:-6:-1] 28 | print("top5:", top5) 29 | for n, i in enumerate(top5): 30 | print("n:", n) 31 | print("i:", i) 32 | print(i, ":", labels[i]) 33 | print("----", utils.percent(probability[0][i])) 34 | 35 | -------------------------------------------------------------------------------- /image/data.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/image/data.jpg -------------------------------------------------------------------------------- /image/data_.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/image/data_.jpg -------------------------------------------------------------------------------- /image/data_crop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/image/data_crop.jpg -------------------------------------------------------------------------------- /manage.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | if __name__ == '__main__': 6 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') 7 | try: 8 | from django.core.management import execute_from_command_line 9 | except ImportError as exc: 10 | raise ImportError( 11 | "Couldn't import Django. Are you sure it's installed and " 12 | "available on your PYTHONPATH environment variable? Did you " 13 | "forget to activate a virtual environment?" 14 | )from exc 15 | execute_from_command_line(sys.argv) 16 | -------------------------------------------------------------------------------- /mysite/settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | Django settings for mysite project. 3 | 4 | Generated by 'django-admin startproject' using Django 2.1.5. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/topics/settings/ 8 | 9 | For the full list of settings and their values, see 10 | https://docs.djangoproject.com/en/2.1/ref/settings/ 11 | """ 12 | import os 13 | BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 14 | 15 | 16 | # Quick-start development settings - unsuitable for production 17 | # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ 18 | 19 | # SECURITY WARNING: keep the secret key used in production secret! 20 | SECRET_KEY = '7-yy+2$@q4v924$5e=3&#_e10n)+6%3w#re=-8s4do9kse1ch5' 21 | 22 | # SECURITY WARNING: don't run with debug turned on in production! 23 | DEBUG = True 24 | 25 | ALLOWED_HOSTS = [] 26 | 27 | 28 | # Application definition 29 | 30 | INSTALLED_APPS = [ 31 | 'django.contrib.admin', 32 | 'django.contrib.auth', 33 | 'django.contrib.contenttypes', 34 | 'django.contrib.sessions', 35 | 'django.contrib.messages', 36 | 'django.contrib.staticfiles', 37 | ] 38 | 39 | MIDDLEWARE = [ 40 | 'django.middleware.security.SecurityMiddleware', 41 | 'django.contrib.sessions.middleware.SessionMiddleware', 42 | 'django.middleware.common.CommonMiddleware', 43 | # 'django.middleware.csrf.CsrfViewMiddleware', 44 | 'django.contrib.auth.middleware.AuthenticationMiddleware', 45 | 'django.contrib.messages.middleware.MessageMiddleware', 46 | 'django.middleware.clickjacking.XFrameOptionsMiddleware', 47 | ] 48 | 49 | ROOT_URLCONF = 'mysite.urls' 50 | 51 | TEMPLATES = [ 52 | { 53 | 'BACKEND': 'django.template.backends.django.DjangoTemplates', 54 | 'DIRS': [os.path.join(BASE_DIR, 'templates')], 55 | 'APP_DIRS': True, 56 | 'OPTIONS': { 57 | 'context_processors': [ 58 | 'django.template.context_processors.debug', 59 | 'django.template.context_processors.request', 60 | 'django.contrib.auth.context_processors.auth', 61 | 'django.contrib.messages.context_processors.messages', 62 | ], 63 | }, 64 | }, 65 | ] 66 | 67 | WSGI_APPLICATION = 'mysite.wsgi.application' 68 | 69 | 70 | # Database 71 | # https://docs.djangoproject.com/en/2.1/ref/settings/#databases 72 | 73 | DATABASES = { 74 | 'default': { 75 | 'ENGINE': 'django.db.backends.sqlite3', 76 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 77 | } 78 | } 79 | 80 | 81 | # Password validation 82 | # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators 83 | 84 | AUTH_PASSWORD_VALIDATORS = [ 85 | { 86 | 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', 87 | }, 88 | { 89 | 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', 90 | }, 91 | { 92 | 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', 93 | }, 94 | { 95 | 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', 96 | }, 97 | ] 98 | 99 | 100 | # Internationalization 101 | # https://docs.djangoproject.com/en/2.1/topics/i18n/ 102 | 103 | LANGUAGE_CODE = 'en-us' 104 | 105 | TIME_ZONE = 'UTC' 106 | 107 | USE_I18N = True 108 | 109 | USE_L10N = True 110 | 111 | USE_TZ = True 112 | 113 | 114 | # Static files (CSS, JavaScript, Images) 115 | # https://docs.djangoproject.com/en/2.1/howto/static-files/ 116 | 117 | STATIC_URL = '/static/' 118 | 119 | 120 | -------------------------------------------------------------------------------- /mysite/urls.py: -------------------------------------------------------------------------------- 1 | """mysite URL Configuration 2 | 3 | The `urlpatterns` list routes URLs to views. For more information please see: 4 | https://docs.djangoproject.com/en/2.1/topics/http/urls/ 5 | Examples: 6 | Function views 7 | 1. Add an import: from my_app import views 8 | 2. Add a URL to urlpatterns: path('', views.home, name='home') 9 | Class-based views 10 | 1. Add an import: from other_app.views import Home 11 | 2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') 12 | Including another URLconf 13 | 1. Import the include() function: from django.urls import include, path 14 | 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 15 | """ 16 | from django.conf.urls import url 17 | import mysite.view as view 18 | from django.views.static import serve 19 | 20 | urlpatterns = [ 21 | # url('app/index/', view.index), #进入添加页面 22 | url(r'^$', view.index), # 网站页面 23 | url(r'vgg16/', view.detect_image_vgg16), # 上传函数 24 | url(r'yolo/', view.detect_image_yolo), 25 | url(r'yolo_vgg/', view.detect_image_yolo_vgg), 26 | url(r'image/(?P.*)$', serve, {'document_root': '/home/cups/PycharmProjects/Demo/image'}), 27 | ] 28 | -------------------------------------------------------------------------------- /mysite/view.py: -------------------------------------------------------------------------------- 1 | import cv2 2 | import os 3 | 4 | from PIL import Image 5 | 6 | import utils as utils 7 | import numpy as np 8 | import tensorflow as tf 9 | import vgg16 as vgg16 10 | 11 | from django.http import HttpResponse 12 | from django.shortcuts import render, render_to_response 13 | 14 | 15 | def index(request): 16 | return render(request, "index.html") 17 | 18 | 19 | labels = ['Rhodesian_ridgeback 猎狮犬', 'Mexican_hairless 墨西哥无毛犬', 'pug 巴哥犬', 'briard 布雷猎犬', 'miniature_schnauzer 小型雪纳瑞犬', 20 | 'Sealyham_terrier 锡利哈姆梗', 'golden_retriever 金毛寻回犬', 'whippet 惠比特犬', 'Norwegian_elkhound 挪威猎鹿犬', 21 | 'Norwich_terrier 挪威梗', 'Lakeland_terrier 湖畔梗', 'miniature_poodle 迷你贵宾犬', 'English_foxhound 英国猎狐犬', 22 | 'miniature_pinscher 迷你杜宾犬', 'Great_Pyrenees 大白熊犬', 'English_springer 英国斯普林格犬', 'Shih-Tzu 西施犬', 23 | 'Siberian_husky 西伯利亚哈士奇', 'basset 短腿猎犬', 'Saint_Bernard 圣伯纳犬', 'malinois 马利诺斯犬', 'Chihuahua 吉娃娃', 24 | 'black-and-tan_coonhound 黑褐猎浣熊犬', 'Tibetan_terrier 西藏梗', 'giant_schnauzer 巨型雪纳瑞犬', 'Saluki 萨路基猎犬', 25 | 'Doberman 杜宾犬', 'Shetland_sheepdog 喜乐蒂牧羊犬', 'Airedale 秋田犬', 'collie 柯利犬', 26 | 'Chesapeake_Bay_retriever 切萨皮克海湾寻回犬', 'dhole 亚洲豺犬', 'Samoyed 萨摩耶犬', 'Weimaraner 威玛犬', 27 | 'Kerry_blue_terrier 凯利蓝梗', 'Brittany_spaniel 塔尼猎犬', 'boxer 拳师犬', 'Bernese_mountain_dog 伯恩山犬', 28 | 'affenpinscher 猴头梗', 'African_hunting_dog 美国猎犬', 'French_bulldog 法国斗牛犬', 'wire-haired_fox_terrier 刚毛猎狐梗', 29 | 'Irish_terrier 爱尔兰梗', 'Blenheim_spaniel 布莱尼姆长耳猎狗', 'German_short-haired_pointer 德国短毛猎犬', 30 | 'German_shepherd 德国牧羊犬', 'bloodhound 寻血猎犬', 'Rottweiler 罗威纳犬', 'keeshond 荷兰毛狮犬', 'papillon 蝴蝶犬', 31 | 'Afghan_hound 阿富汗猎犬', 'Irish_setter 爱尔兰雪橇犬', 'Irish_wolfhound 爱尔兰猎狼犬', 'clumber 矮脚西班牙猎犬', 32 | 'Sussex_spaniel 苏塞克斯猎犬', 'Appenzeller', 'English_setter 英格兰雪达犬', 'Old_English_sheepdog 古代英国牧羊犬', 33 | 'basenji 巴仙吉犬', 'Italian_greyhound 意大利灰狗', 'Pomeranian 博美犬', 'Border_collie 边境牧羊犬', 'EntleBucher', 34 | 'komondor 匈牙利牧羊犬', 'dingo 澳洲野犬', 'Welsh_springer_spaniel 威尔士跳猎犬', 'chow 松狮犬', 'Brabancon_griffon 布鲁塞尔格里枫犬', 35 | 'Australian_terrier 澳大利亚梗', 'otterhound 猎水獭犬', 'Cardigan', 'Boston_bull', 'Yorkshire_terrier 约克夏梗', 36 | 'groenendael 比利时牧羊犬', 'Scottish_deerhound 苏格兰猎鹿犬', 'Dandie_Dinmont 矮脚狄文㹴', 'Tibetan_mastiff 藏獒', 37 | 'Walker_hound 沃克猎犬', 'kelpie 澳大利亚卡尔比犬', 'Ibizan_hound 伊比赞猎犬', 'silky_terrier 丝毛梗', 'bull_mastiff 斗牛獒', 38 | 'Pekinese 狮子狗', 'Bedlington_terrier 贝灵顿梗', 'soft-coated_wheaten_terrier', 'kuvasz 库瓦兹犬', 39 | 'Greater_Swiss_Mountain_dog 大瑞士山地犬', 'Irish_water_spaniel 爱尔兰水猎犬', 'schipperke 西帕基犬', 'Pembroke 彭布罗克犬', 40 | 'Great_Dane 大丹犬', 'West_Highland_white_terrier 西高地白梗', 'Lhasa 拉萨犬', 'cocker_spaniel 美国可卡犬', 'beagle 比格猎犬', 41 | 'Labrador_retriever 拉布拉多寻回犬', 'borzoi 苏俄猎狼犬', 'cairn', 'Leonberg 莱昂贝格犬', 'bluetick 蓝色快狗', 'toy_poodle 玩具贵宾犬', 42 | 'Maltese_dog 马尔济斯犬', 'Japanese_spaniel 日本猎犬', 'Gordon_setter 戈登雪达犬', 'standard_poodle 标准贵宾犬', 43 | 'Border_terrier 博得猎狐犬', 'malamute 阿拉斯加玛拉慕蒂犬', 'redbone 惬意梗', 'Staffordshire_bullterrier 斯塔福郡斗牛梗', 44 | 'Newfoundland 纽芬兰犬', 'Bouvier_des_Flandres 波兰德斯布比野犬', 'standard_schnauzer 标准型雪纳瑞犬', 'toy_terrier 曼彻斯特玩具梗', 45 | 'Scotch_terrier 苏格兰小猎犬', 'flat-coated_retriever 弗莱特寻回犬', 'curly-coated_retriever 卷毛寻回犬', 'vizsla 维希拉猎犬', 46 | 'Norfolk_terrier 诺福克梗', 'Eskimo_dog 爱斯基摩犬', 'American_Staffordshire_terrier 美国斯塔福郡梗'] 47 | 48 | 49 | def detect_image_vgg16(request): 50 | if request.method == "POST": # 请求方法为POST时,进行处理 51 | 52 | myFile = request.FILES.get("myfile", None) # 获取上传的文件,如果没有文件,则默认为None 53 | if not myFile: 54 | return HttpResponse("no files for upload!") 55 | img_ready = utils.load_image(myFile) 56 | with tf.Session() as sess: 57 | # 给输入图片占位 58 | images = tf.placeholder(tf.float32, [1, 224, 224, 3]) 59 | # 初始化vgg,读出保存的文件参数 60 | vgg = vgg16.Vgg16() 61 | # 调用前向传播函数,把待识别图片喂入神经网络 62 | vgg.forward(images) 63 | # 运行会话,预测分类结果 64 | probability = sess.run(vgg.prob, feed_dict={images: img_ready}) 65 | top5 = np.argsort(probability[0])[-1:-6:-1] 66 | data = "" 67 | data += "top5:" 68 | data += str(top5) 69 | data += "
" 70 | for n, i in enumerate(top5): 71 | data += str(i) 72 | data += ":" 73 | data += labels[i] 74 | data += "----" 75 | data += str(utils.percent(probability[0][i])) 76 | data += "
" 77 | 78 | return HttpResponse("

VGG16物体分类结果展示

%s
" % data) 79 | 80 | 81 | 82 | class_path = "yolo/yolov3.txt" 83 | weights_path = "yolo/yolov3.weights" 84 | config_path = "yolo/yolov3.cfg" 85 | locations = [] 86 | def detect_image_yolo(request): 87 | if request.method == "POST": # 请求方法为POST时,进行处理 88 | myFile = request.FILES.get("myfile", None) # 获取上传的文件,如果没有文件,则默认为None 89 | if not myFile: 90 | return HttpResponse("no files for upload!") 91 | 92 | file = open(os.path.join(os.getcwd(), 'image/data.jpg'), 'wb+') 93 | for chunk in myFile.chunks(): # 分块写入文件 94 | file.write(chunk) 95 | file.close() 96 | 97 | image = cv2.imread("image/data.jpg") 98 | Width = image.shape[1] 99 | Height = image.shape[0] 100 | scale = 0.00392 101 | classes = None 102 | 103 | # 种类读取 104 | with open(class_path, 'r') as f: 105 | classes = [line.strip() for line in f.readlines()] 106 | 107 | COLORS = np.random.uniform(0, 255, size=(len(classes), 3)) 108 | 109 | net = cv2.dnn.readNet(weights_path, config_path) 110 | blob = cv2.dnn.blobFromImage(image, scale, (416, 416), (0, 0, 0), True, crop=False) 111 | net.setInput(blob) 112 | outs = net.forward(get_output_layers(net)) 113 | 114 | class_ids = [] 115 | confidences = [] 116 | boxes = [] 117 | conf_threshold = 0.5 118 | nms_threshold = 0.4 119 | 120 | for out in outs: 121 | for detection in out: 122 | scores = detection[5:] 123 | class_id = np.argmax(scores) 124 | confidence = scores[class_id] 125 | if confidence > 0.5: 126 | center_x = int(detection[0] * Width) 127 | center_y = int(detection[1] * Height) 128 | w = int(detection[2] * Width) 129 | h = int(detection[3] * Height) 130 | x = center_x - w / 2 131 | y = center_y - h / 2 132 | class_ids.append(class_id) 133 | confidences.append(float(confidence)) 134 | boxes.append([x, y, w, h]) 135 | 136 | indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold) 137 | 138 | # 显示识别效果 139 | locations.clear() 140 | for i in indices: 141 | i = i[0] 142 | box = boxes[i] 143 | x = box[0] 144 | y = box[1] 145 | w = box[2] 146 | h = box[3] 147 | if class_ids[i] == 16: 148 | locations.append([x, y, w, h]) 149 | draw_prediction(image, class_ids[i], confidences[i], round(x), round(y), round(x + w), round(y + h),classes,COLORS) 150 | cv2.imwrite("image/data_.jpg", image) 151 | print("dogs locations:", locations) 152 | return render(request, 'yolo.html') 153 | 154 | 155 | def detect_image_yolo_vgg(request): 156 | data = "" 157 | for i in locations: 158 | img = Image.open("image/data.jpg") 159 | img = img.crop([i[0], i[1], i[0]+i[2], i[1]+i[3]]) 160 | img.save("image/data_crop.jpg") 161 | img_ready = utils.load_image("image/data_crop.jpg") 162 | with tf.Session() as sess: 163 | # 给输入图片占位 164 | images = tf.placeholder(tf.float32, [1, 224, 224, 3]) 165 | # 初始化vgg,读出保存的文件参数 166 | vgg = vgg16.Vgg16() 167 | # 调用前向传播函数,把待识别图片喂入神经网络 168 | vgg.forward(images) 169 | # 运行会话,预测分类结果 170 | probability = sess.run(vgg.prob, feed_dict={images: img_ready}) 171 | top5 = np.argsort(probability[0])[-1:-2:-1] 172 | data += str(i) 173 | data += "--" 174 | data += labels[top5[0]] 175 | data += "
" 176 | return HttpResponse("

YOLO+VGG16物体检测结果展示


%s
" % data) 177 | 178 | # 获取某层输出 179 | def get_output_layers(net): 180 | layer_names = net.getLayerNames() 181 | output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] 182 | return output_layers 183 | 184 | # 画出识别结果 185 | def draw_prediction(img, class_id, confidence, x, y, x_plus_w, y_plus_h,classes,COLORS): 186 | label = str(classes[class_id]) 187 | color = COLORS[class_id] 188 | cv2.rectangle(img, (x, y), (x_plus_w, y_plus_h), color, 2) 189 | cv2.putText(img, label, (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) -------------------------------------------------------------------------------- /mysite/wsgi.py: -------------------------------------------------------------------------------- 1 | """ 2 | WSGI config for mysite project. 3 | 4 | It exposes the WSGI callable as a module-level variable named ``application``. 5 | 6 | For more information on this file, see 7 | https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ 8 | """ 9 | 10 | import os 11 | 12 | from django.core.wsgi import get_wsgi_application 13 | 14 | os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings') 15 | 16 | application = get_wsgi_application() 17 | -------------------------------------------------------------------------------- /pic/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/pic/1.png -------------------------------------------------------------------------------- /pic/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/pic/2.png -------------------------------------------------------------------------------- /pic/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/pic/3.png -------------------------------------------------------------------------------- /pic/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/pic/4.png -------------------------------------------------------------------------------- /pic/a.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CupsWen/Dog-Identification/876115b8aa7242393abfd99a9296b864a68971ff/pic/a.jpg -------------------------------------------------------------------------------- /pic/世界名犬名字翻译: -------------------------------------------------------------------------------- 1 | 1 Affenpinscher艾芬笃宾犬 2 | 2 Afghan Hound阿富汗猎犬 3 | 3 Airedale Terrier万能挭 4 | 4 Akita秋田犬 5 | 5 Alaskan Malamute阿拉斯加雪橇犬 6 | 6 American Eskimo Dog美国爱斯基摩犬 7 | 7 American Staffordshire Terrier美国史特富郡挭 8 | 8 American Water Spaniel美国水猎犬 9 | 9 Anatolian Shepherd安娜图牧羊犬 10 | 10 Australian Cattle Dog澳洲牧牛犬 11 | 11 Australian Shepherd澳洲牧羊犬 12 | 12 Australian Terrier澳洲挭 13 | 13 Basenji贝吉生犬 14 | 14 Basset Hound巴吉度猎犬 15 | 15 Beagle贝高犬 16 | 16 Bearded Collie古代长须牧羊犬 17 | 17 Bedlington Terrier贝林登挭 18 | 18 Belgian Malinois比利时玛利诺犬 19 | 19 Belgian Sheepdog比利时牧羊犬 20 | 20 Belgian Tervuren比利时坦比连犬 21 | 21 Bernese Mountain Dog伯恩山犬 22 | 22 Bichon Frise卷毛比雄犬 23 | 23 Black and Tan Coonhound黑褐猎浣熊犬 24 | 24 Bloodhound寻血猎犬 25 | 25 Border Collie边境牧羊犬 26 | 26 Border Terrier边境挭 27 | 27 Borzoi波索尔 28 | 28 Boston Terrier波士顿挭 29 | 29 Bouvier des Flandres法兰德斯畜牧犬 30 | 30 Boxer拳狮犬 31 | 31 Briard伯瑞犬 32 | 32 Brittany不列塔尼猎犬 33 | 33 Brussels Griffon比利时粗毛猎犬 34 | 34 Bull Terrier牛头挭 35 | 35 Bulldog老虎犬 36 | 36 Bullmastiff斗牛马士提夫犬 37 | 37 Cairn Terrier凯安挭 38 | 38 Canaan Dog卡南犬 39 | 39 Cavalier King Charles Spaniel查理士王小猎犬 40 | 40 Chesapeake Bay Retriever乞沙比克猎犬 41 | 41 Chihuahua吉娃娃 42 | 42 Chinese Crested中国冠毛犬 43 | 43 Chinese Shar-pei中国沙皮犬 44 | 44 Chow Chow松狮犬 45 | 45 Clumber Spaniel克伦伯犬 46 | 46 Cocker Spaniel可卡犬 47 | 47 Collie牧羊犬 48 | 48 Curly-Coated Retriever卷毛寻回犬 49 | 49 Dachshund腊肠犬 50 | 50 Dalmatian斑点犬 51 | 51 Dandie Dinmont Terrier短脚狄文挭 52 | 52 Doberman Pinscher都柏文犬 53 | 53 English Cocker Spaniel英国可卡犬 54 | 54 English Setter英国塞特犬 55 | 55 English Springer Spaniel英国可卡犬 56 | 56 English Toy Spaniel英国玩赏可卡犬 57 | 57 Field Spaniel田野猎犬 58 | 58 Finnish Spitz芬兰猎犬 59 | 59 Flat-Coated Retriever平毛寻回犬 60 | 60 Fox Terrier (Smooth)猎狐挭 61 | 61 Fox Terrier (Wire)刚毛猎狐挭 62 | 62 Foxhound (American)美国猎狐犬 63 | 63 Foxhound (English)英国猎狐犬 64 | 64 French Bulldog法国老虎犬 65 | 65 German Shepherd Dog德国牧羊犬 66 | 66 German Shorthaired Pointer德国短毛指示犬 67 | 67 German Wirehaired Pointer德国钢毛指示犬 68 | 68 Giant Schnauzer大型史柔查 69 | 69 Golden Retriever金毛寻回犬 70 | 70 Gordon Setter哥顿塞特犬 71 | 71 Great Dane大丹犬 72 | 72 Great Pyrenees大白熊犬 73 | 73 Greater Swiss Mountain Dog大瑞士山地犬 74 | 74 Greyhound格雷伊猎犬 75 | 75 Harrier哈利犬 76 | 76 Havanese哈威那 77 | 77 Ibizan Hound依比沙猎犬 78 | 78 Irish Setter爱尔兰塞特犬 79 | 79 Irish Terrier爱尔兰挭 80 | 80 Irish Water Spaniel爱尔兰水猎犬 81 | 81 Irish Wolfhound爱尔兰猎狼犬 82 | 82 Italian Greyhound意大利格雷伊猎犬 83 | 83 Jack Russell Terrier积奇罗素挭 84 | 84 Japanese Chin日本犬 85 | 85 Keeshond荷兰毛狮犬 86 | 86 Kerry Blue Terrier凯利蓝挭 87 | 87 Komondor可蒙犬 88 | 88 Kuvasz哥威斯犬 89 | 89 Labrador Retriever拉布拉多犬 90 | 90 Lakeland Terrier湖畔挭 91 | 91 Lhasa Apso拉萨犬 92 | 92 L?wchen罗秦犬 93 | 93 Maltese玛尔济斯 94 | 94 Manchester Terrier曼彻斯特挭 95 | 95 Mastiff马士提夫犬 96 | 96 Miniature Bull Terrier迷你牛头挭 97 | 97 Miniature Pinscher迷你笃宾犬 98 | 98 Miniature Schnauzer迷你史柔查 99 | 99 Newfoundland纽芬兰犬 100 | 100 Norfolk Terrier罗福挭 101 | 101 Norwegian Elkhound挪威猎麋犬 102 | 102 Norwich Terrier罗威士挭 103 | 103 Old English Sheepdog古代英国牧羊犬 104 | 104 Otterhound奥达猎犬 105 | 105 Papillon蝴蝶犬 106 | 106 Pekingese北京犬 107 | 107 Petit Basset Griffon Vendeen迷你贝吉格里芬凡丁犬 108 | 108 Pharaoh Hound法老王猎犬 109 | 109 Plott Hound普罗特猎犬 110 | 110 Polish Lowland Sheepdog波兰低地牧羊犬 111 | 111 Pointer指示犬 112 | 112 Pomeranian松鼠犬 113 | 113 Poodle贵妇犬 114 | 114 Portuguese Water Dog葡萄牙水犬 115 | 115 Pug八哥 116 | 116 Puli波利犬 117 | 117 Rhodesian Ridgeback 118 | 118 Rottweiler洛威拿 119 | 119 Saint Bernard圣伯纳犬 120 | 120 Saluki ?#124;非猎犬 121 | 121 Samoyed萨摩犬 122 | 122 Schipperke舒柏奇犬 123 | 123 Scottish Deerhound苏格兰猎鹿犬 124 | 124 Scottish Terrier苏格兰挭 125 | 125 Sealyham Terrier西里汉挭 126 | 126 Shetland Sheepdog喜乐蒂牧羊犬 127 | 127 Shiba Inu西巴犬 128 | 128 Shih Tzu西施 129 | 129 Siberian Husky西伯利亚雪橇犬 130 | 130 Silky Terrier丝毛挭 131 | 131 Skye Terrier斯开岛挭 132 | 132 Soft Coated Wheaten Terrier爱尔兰软毛挭 133 | 133 Spinone Italiano史毕诺犬 134 | 134 Staffordshire Bull Terrier斯塔福郡斗牛挭 135 | 135 Standard Schnauzer标准史柔查 136 | 136 Sussex Spaniel塞式猎犬 137 | 137 Tibetan Spaniel西藏猎犬 138 | 138 Tibetan Terrier西藏挭 139 | 139 Vizsla维兹拉犬 140 | 140 Weimaraner威玛猎犬 141 | 141 Welsh Corgi (Cardigan)威尔斯柯基犬(卡狄根) 142 | 142 Welsh Corgi (Pembroke)威尔斯柯基犬(宾波基) 143 | 143 Welsh Springer Spaniel威尔斯激飞猎犬 144 | 144 Welsh Terrier威尔斯挭 145 | 145 West Highland White Terrier西部高地白挭 146 | 146 Whippet惠比特犬 147 | 147 Wirehaired Pointing Griffon钢毛指示格里芬犬 148 | 148 Yorkshire Terrier约克夏 149 | -------------------------------------------------------------------------------- /pic/哈弗大学狗子种类名称翻译: -------------------------------------------------------------------------------- 1 | ['Rhodesian_ridgeback 猎狮犬', 'Mexican_hairless 墨西哥无毛犬', 'pug 巴哥犬', 'briard 布雷猎犬', 'miniature_schnauzer 小型雪纳瑞犬', 'Sealyham_terrier 锡利哈姆梗', 'golden_retriever 金毛寻回犬', 'whippet 惠比特犬', 'Norwegian_elkhound 挪威猎鹿犬', 'Norwich_terrier 挪威梗', 'Lakeland_terrier 湖畔梗', 'miniature_poodle 迷你贵宾犬', 'English_foxhound 英国猎狐犬', 'miniature_pinscher 迷你杜宾犬', 'Great_Pyrenees 大白熊犬', 'English_springer 英国斯普林格犬', 'Shih-Tzu 西施犬', 'Siberian_husky 西伯利亚哈士奇', 'basset 短腿猎犬', 'Saint_Bernard 圣伯纳犬', 'malinois 马利诺斯犬', 'Chihuahua 吉娃娃', 'black-and-tan_coonhound 黑褐猎浣熊犬', 'Tibetan_terrier 西藏梗', 'giant_schnauzer 巨型雪纳瑞犬', 'Saluki 萨路基猎犬', 'Doberman 杜宾犬', 'Shetland_sheepdog 喜乐蒂牧羊犬', 'Airedale 秋田犬', 'collie 柯利犬', 'Chesapeake_Bay_retriever 切萨皮克海湾寻回犬', 'dhole 亚洲豺犬', 'Samoyed 萨摩耶犬', 'Weimaraner 威玛犬', 'Kerry_blue_terrier 凯利蓝梗', 'Brittany_spaniel 塔尼猎犬', 'boxer 拳师犬', 'Bernese_mountain_dog 伯恩山犬', 'affenpinscher 猴头梗', 'African_hunting_dog 美国猎犬', 'French_bulldog 法国斗牛犬', 'wire-haired_fox_terrier 刚毛猎狐梗', 'Irish_terrier 爱尔兰梗', 'Blenheim_spaniel 布莱尼姆长耳猎狗', 'German_short-haired_pointer 德国短毛猎犬', 'German_shepherd 德国牧羊犬', 'bloodhound 寻血猎犬', 'Rottweiler 罗威纳犬', 'keeshond 荷兰毛狮犬', 'papillon 蝴蝶犬', 'Afghan_hound 阿富汗猎犬', 'Irish_setter 爱尔兰雪橇犬', 'Irish_wolfhound 爱尔兰猎狼犬', 'clumber 矮脚西班牙猎犬', 'Sussex_spaniel 苏塞克斯猎犬', 'Appenzeller', 'English_setter 英格兰雪达犬', 'Old_English_sheepdog 古代英国牧羊犬', 'basenji 巴仙吉犬', 'Italian_greyhound 意大利灰狗', 'Pomeranian 博美犬', 'Border_collie 边境牧羊犬', 'EntleBucher', 'komondor 匈牙利牧羊犬', 'dingo 澳洲野犬', 'Welsh_springer_spaniel 威尔士跳猎犬', 'chow 松狮犬', 'Brabancon_griffon 布鲁塞尔格里枫犬', 'Australian_terrier 澳大利亚梗', 'otterhound 猎水獭犬', 'Cardigan', 'Boston_bull', 'Yorkshire_terrier 约克夏梗', 'groenendael 比利时牧羊犬', 'Scottish_deerhound 苏格兰猎鹿犬', 'Dandie_Dinmont 矮脚狄文㹴', 'Tibetan_mastiff 藏獒', 'Walker_hound 沃克猎犬', 'kelpie 澳大利亚卡尔比犬', 'Ibizan_hound 伊比赞猎犬', 'silky_terrier 丝毛梗', 'bull_mastiff 斗牛獒', 'Pekinese 狮子狗', 'Bedlington_terrier 贝灵顿梗', 'soft-coated_wheaten_terrier', 'kuvasz 库瓦兹犬', 'Greater_Swiss_Mountain_dog 大瑞士山地犬', 'Irish_water_spaniel 爱尔兰水猎犬', 'schipperke 西帕基犬', 'Pembroke 彭布罗克犬', 'Great_Dane 大丹犬', 'West_Highland_white_terrier 西高地白梗', 'Lhasa 拉萨犬', 'cocker_spaniel 美国可卡犬', 'beagle 比格猎犬', 'Labrador_retriever 拉布拉多寻回犬', 'borzoi 苏俄猎狼犬', 'cairn', 'Leonberg 莱昂贝格犬', 'bluetick 蓝色快狗', 'toy_poodle 玩具贵宾犬', 'Maltese_dog 马尔济斯犬', 'Japanese_spaniel 日本猎犬', 'Gordon_setter 戈登雪达犬', 'standard_poodle 标准贵宾犬', 'Border_terrier 博得猎狐犬', 'malamute 阿拉斯加玛拉慕蒂犬', 'redbone 惬意梗', 'Staffordshire_bullterrier 斯塔福郡斗牛梗', 'Newfoundland 纽芬兰犬', 'Bouvier_des_Flandres 波兰德斯布比野犬', 'standard_schnauzer 标准型雪纳瑞犬', 'toy_terrier 曼彻斯特玩具梗', 'Scotch_terrier 苏格兰小猎犬', 'flat-coated_retriever 弗莱特寻回犬', 'curly-coated_retriever 卷毛寻回犬', 'vizsla 维希拉猎犬', 'Norfolk_terrier 诺福克梗', 'Eskimo_dog 爱斯基摩犬', 'American_Staffordshire_terrier 美国斯塔福郡梗'] 2 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | # coding:utf-8 2 | # 导入相关函数库 3 | from skimage import io, transform 4 | from pylab import mpl 5 | 6 | mpl.rcParams['font.sans-serif'] = ['SimHei'] # 正常显示中文标签 7 | mpl.rcParams['axes.unicode_minus'] = False # 正常显示正负号 8 | 9 | def load_image(path): 10 | ''' 11 | 对图像进行预处理,并 12 | 显示 Original Picture,Centre Picture",Resize Picture 13 | :param path: 待识别图片路径 14 | :return: 处理后的图像 15 | ''' 16 | img = io.imread(path) 17 | img = img / 255.0 18 | short_edge = min(img.shape[:2]) 19 | y = (img.shape[0] - short_edge) // 2 20 | x = (img.shape[1] - short_edge) // 2 21 | crop_img = img[y:y+short_edge, x:x+short_edge] 22 | re_img = transform.resize(crop_img, (224, 224)) 23 | img_ready = re_img.reshape((1, 224, 224, 3)) 24 | 25 | return img_ready 26 | 27 | def load_image_crop(path): 28 | ''' 29 | 对图像进行预处理,并 30 | 显示 Original Picture,Centre Picture",Resize Picture 31 | :param path: 待识别图片路径 32 | :return: 处理后的图像 33 | ''' 34 | img = io.imread(path) 35 | img = img / 255.0 36 | short_edge = min(img.shape[:2]) 37 | y = (img.shape[0] - short_edge) // 2 38 | x = (img.shape[1] - short_edge) // 2 39 | crop_img = img[y:y+short_edge, x:x+short_edge] 40 | re_img = transform.resize(crop_img, (224, 224)) 41 | img_ready = re_img.reshape((1, 224, 224, 3)) 42 | 43 | return img_ready 44 | 45 | def percent(value): 46 | ''' 47 | 获取百分数表示 48 | :param value:小数 49 | :return: 百分数表示 50 | ''' 51 | return '%.2f%%' % (value * 100) 52 | 53 | if __name__ == '__main__': 54 | f = open("test.txt", "r") 55 | contents = f.readlines() 56 | f.close() 57 | data = list() 58 | for content in contents: 59 | raw_data = content.split("/") 60 | if raw_data[0] not in data: 61 | data.append(raw_data[0]) 62 | print(raw_data[0]) 63 | print(data) 64 | 65 | -------------------------------------------------------------------------------- /vgg15.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #coding:utf-8 3 | labels = { 4 | 0: "dhole", 5 | 1: "Doberman", 6 | 2: "Yorkshire_terrier", 7 | 3: "Weimaraner", 8 | 4: "Bernese_mountain_dog", 9 | 5: "Pembroke", 10 | 6: "German_short", 11 | 7: "English_foxhound", 12 | 8: "American_Staffordshire_terrier", 13 | 9: "miniature_pinscher", 14 | 10: "borzoi", 15 | 11: "redbone", 16 | 12: "briard", 17 | 13: "miniature_poodle", 18 | 14: "kelpie", 19 | 15: "schipperke", 20 | 16: "Bouvier_des_Flandres", 21 | 17: "Dandie_Dinmont", 22 | 18: "miniature_schnauzer", 23 | 19: "Tibetan_mastiff", 24 | 20: "affenpinscher", 25 | 21: "Irish_water_spaniel", 26 | 22: "Scotch_terrier", 27 | 23: "vizsla", 28 | 24: "Rottweiler", 29 | 25: "Blenheim_spaniel", 30 | 26: "standard_schnauzer", 31 | 27: "Kerry_blue_terrier", 32 | 28: "Cardigan", 33 | 29: "Chihuahua", 34 | 30: "German_shepherd", 35 | 31: "Eskimo_dog", 36 | 32: "whippet", 37 | 33: "African_hunting_dog", 38 | 34: "Sussex_spaniel", 39 | 35: "Shetland_sheepdog", 40 | 36: "Scottish_deerhound", 41 | 37: "beagle", 42 | 38: "bluetick", 43 | 39: "curly", 44 | 40: "Appenzeller", 45 | 41: "Airedale", 46 | 42: "toy_poodle", 47 | 43: "Rhodesian_ridgeback", 48 | 44: "Leonberg", 49 | 45: "English_springer", 50 | 46: "chow", 51 | 47: "boxer", 52 | 48: "standard_poodle", 53 | 49: "cairn", 54 | 50: "English_setter", 55 | 51: "Siberian_husky", 56 | 52: "keeshond", 57 | 53: "Sealyham_terrier", 58 | 54: "Maltese_dog", 59 | 55: "Welsh_springer_spaniel", 60 | 56: "malamute", 61 | 57: "wire", 62 | 58: "Great_Dane", 63 | 59: "Irish_wolfhound", 64 | 60: "kuvasz", 65 | 61: "groenendael", 66 | 62: "bull_mastiff", 67 | 63: "golden_retriever", 68 | 64: "Greater_Swiss_Mountain_dog", 69 | 65: "toy_terrier", 70 | 66: "Brabancon_griffon", 71 | 67: "Norwich_terrier", 72 | 68: "Samoyed", 73 | 69: "otterhound", 74 | 70: "giant_schnauzer", 75 | 71: "Norwegian_elkhound", 76 | 72: "Great_Pyrenees", 77 | 73: "papillon", 78 | 74: "flat", 79 | 75: "Italian_greyhound", 80 | 76: "clumber", 81 | 77: "Bedlington_terrier", 82 | 78: "Pomeranian", 83 | 79: "Mexican_hairless", 84 | 80: "black", 85 | 81: "Lakeland_terrier", 86 | 82: "Pekinese", 87 | 83: "basenji", 88 | 84: "komondor", 89 | 85: "silky_terrier", 90 | 86: "West_Highland_white_terrier", 91 | 87: "Chesapeake_Bay_retriever", 92 | 88: "French_bulldog", 93 | 89: "Newfoundland", 94 | 90: "pug", 95 | 91: "Boston_bull", 96 | 92: "Norfolk_terrier", 97 | 93: "Saint_Bernard", 98 | 94: "EntleBucher", 99 | 95: "Border_terrier", 100 | 96: "Brittany_spaniel", 101 | 97: "malinois", 102 | 98: "Border_collie", 103 | 99: "Gordon_setter", 104 | 100: "Australian_terrier", 105 | 101: "Labrador_retriever", 106 | 102: "basset", 107 | 103: "Tibetan_terrier", 108 | 104: "Staffordshire_bullterrier", 109 | 105: "Irish_setter", 110 | 106: "Japanese_spaniel", 111 | 107: "dingo", 112 | 108: "Irish_terrier", 113 | 109: "Saluki", 114 | 110: "Shih", 115 | 111: "collie", 116 | 112: "Old_English_sheepdog", 117 | 113: "Ibizan_hound", 118 | 114: "Afghan_hound", 119 | 115: "soft", 120 | 116: "Walker_hound", 121 | 117: "Lhasa", 122 | 118: "cocker_spaniel"} -------------------------------------------------------------------------------- /vgg16.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # coding:utf-8 3 | 4 | import os 5 | import numpy as np 6 | import tensorflow as tf 7 | 8 | VGG_MEAN = [103.939, 116.779, 123.68] 9 | 10 | class Vgg16(): 11 | def __init__(self, vgg16_path=None, vgg15_path=None): 12 | if vgg16_path is None: 13 | vgg16_path = os.path.join(os.getcwd(), "vgg16.npy") 14 | self.data_dict = np.load(vgg16_path, encoding='latin1').item() 15 | #print self.data_dict 16 | if vgg15_path is None: 17 | vgg15_path = os.path.join(os.getcwd(), "vgg15.npy") 18 | self.data = np.load(vgg15_path, encoding='latin1').item() 19 | #print(self.data) 20 | 21 | def forward(self, images): 22 | 23 | rgb_scaled = images * 255.0 24 | red, green, blue = tf.split(rgb_scaled,3,3) 25 | bgr = tf.concat([ 26 | blue - VGG_MEAN[0], 27 | green - VGG_MEAN[1], 28 | red - VGG_MEAN[2]],3) 29 | 30 | self.conv1_1 = self.conv_layer(bgr, "conv1_1") 31 | self.conv1_2 = self.conv_layer(self.conv1_1, "conv1_2") 32 | self.pool1 = self.max_pool_2x2(self.conv1_2, "pool1") 33 | 34 | self.conv2_1 = self.conv_layer(self.pool1, "conv2_1") 35 | self.conv2_2 = self.conv_layer(self.conv2_1, "conv2_2") 36 | self.pool2 = self.max_pool_2x2(self.conv2_2, "pool2") 37 | 38 | self.conv3_1 = self.conv_layer(self.pool2, "conv3_1") 39 | self.conv3_2 = self.conv_layer(self.conv3_1, "conv3_2") 40 | self.conv3_3 = self.conv_layer(self.conv3_2, "conv3_3") 41 | self.pool3 = self.max_pool_2x2(self.conv3_3, "pool3") 42 | 43 | self.conv4_1 = self.conv_layer(self.pool3, "conv4_1") 44 | self.conv4_2 = self.conv_layer(self.conv4_1, "conv4_2") 45 | self.conv4_3 = self.conv_layer(self.conv4_2, "conv4_3") 46 | self.pool4 = self.max_pool_2x2(self.conv4_3, "pool4") 47 | 48 | 49 | self.conv5_1 = self.conv_layer(self.pool4, "conv5_1") 50 | self.conv5_2 = self.conv_layer(self.conv5_1, "conv5_2") 51 | 52 | self.conv5_3 = self.conv_layer(self.conv5_2, "conv5_3") 53 | self.pool5 = self.max_pool_2x2(self.conv5_3, "pool5") 54 | 55 | self.pool_shape = self.pool5.get_shape().as_list() 56 | self.nodes = self.pool_shape[1] * self.pool_shape[2] * self.pool_shape[3] 57 | self.cups = tf.reshape(self.pool5, [self.pool_shape[0], self.nodes]) 58 | 59 | self.w1 = tf.constant(self.data['w1'], name='w1') 60 | self.b1 = tf.constant(self.data['b1'], name='b1') 61 | self.y1 = tf.nn.relu(tf.matmul(self.cups, self.w1) + self.b1) 62 | 63 | self.w2 = tf.constant(self.data['w2'], name='w2') 64 | self.b2 = tf.constant(self.data['b2'], name='b2') 65 | self.y2 = tf.matmul(self.y1, self.w2) + self.b2 66 | self.prob = tf.nn.softmax(self.y2, name="prob") 67 | 68 | self.data = None 69 | 70 | def conv_layer(self, x, name): 71 | with tf.variable_scope(name): 72 | w = self.get_conv_filter(name) 73 | conv = tf.nn.conv2d(x, w, [1, 1, 1, 1], padding='SAME') 74 | conv_biases = self.get_bias(name) 75 | result = tf.nn.relu(tf.nn.bias_add(conv, conv_biases)) 76 | return result 77 | 78 | def get_conv_filter(self, name): 79 | return tf.constant(self.data_dict[name][0], name="filter") 80 | 81 | def get_bias(self, name): 82 | return tf.constant(self.data_dict[name][1], name="biases") 83 | 84 | def max_pool_2x2(self, x, name): 85 | return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name=name) 86 | 87 | def get_fc_weight(self, name): 88 | return tf.constant(self.data_dict[name][0], name="weights") 89 | 90 | -------------------------------------------------------------------------------- /yolo/yolov3.cfg: -------------------------------------------------------------------------------- 1 | [net] 2 | # Testing 3 | # batch=1 4 | # subdivisions=1 5 | # Training 6 | batch=64 7 | subdivisions=16 8 | width=608 9 | height=608 10 | channels=3 11 | momentum=0.9 12 | decay=0.0005 13 | angle=0 14 | saturation = 1.5 15 | exposure = 1.5 16 | hue=.1 17 | 18 | learning_rate=0.001 19 | burn_in=1000 20 | max_batches = 500200 21 | policy=steps 22 | steps=400000,450000 23 | scales=.1,.1 24 | 25 | [convolutional] 26 | batch_normalize=1 27 | filters=32 28 | size=3 29 | stride=1 30 | pad=1 31 | activation=leaky 32 | 33 | # Downsample 34 | 35 | [convolutional] 36 | batch_normalize=1 37 | filters=64 38 | size=3 39 | stride=2 40 | pad=1 41 | activation=leaky 42 | 43 | [convolutional] 44 | batch_normalize=1 45 | filters=32 46 | size=1 47 | stride=1 48 | pad=1 49 | activation=leaky 50 | 51 | [convolutional] 52 | batch_normalize=1 53 | filters=64 54 | size=3 55 | stride=1 56 | pad=1 57 | activation=leaky 58 | 59 | [shortcut] 60 | from=-3 61 | activation=linear 62 | 63 | # Downsample 64 | 65 | [convolutional] 66 | batch_normalize=1 67 | filters=128 68 | size=3 69 | stride=2 70 | pad=1 71 | activation=leaky 72 | 73 | [convolutional] 74 | batch_normalize=1 75 | filters=64 76 | size=1 77 | stride=1 78 | pad=1 79 | activation=leaky 80 | 81 | [convolutional] 82 | batch_normalize=1 83 | filters=128 84 | size=3 85 | stride=1 86 | pad=1 87 | activation=leaky 88 | 89 | [shortcut] 90 | from=-3 91 | activation=linear 92 | 93 | [convolutional] 94 | batch_normalize=1 95 | filters=64 96 | size=1 97 | stride=1 98 | pad=1 99 | activation=leaky 100 | 101 | [convolutional] 102 | batch_normalize=1 103 | filters=128 104 | size=3 105 | stride=1 106 | pad=1 107 | activation=leaky 108 | 109 | [shortcut] 110 | from=-3 111 | activation=linear 112 | 113 | # Downsample 114 | 115 | [convolutional] 116 | batch_normalize=1 117 | filters=256 118 | size=3 119 | stride=2 120 | pad=1 121 | activation=leaky 122 | 123 | [convolutional] 124 | batch_normalize=1 125 | filters=128 126 | size=1 127 | stride=1 128 | pad=1 129 | activation=leaky 130 | 131 | [convolutional] 132 | batch_normalize=1 133 | filters=256 134 | size=3 135 | stride=1 136 | pad=1 137 | activation=leaky 138 | 139 | [shortcut] 140 | from=-3 141 | activation=linear 142 | 143 | [convolutional] 144 | batch_normalize=1 145 | filters=128 146 | size=1 147 | stride=1 148 | pad=1 149 | activation=leaky 150 | 151 | [convolutional] 152 | batch_normalize=1 153 | filters=256 154 | size=3 155 | stride=1 156 | pad=1 157 | activation=leaky 158 | 159 | [shortcut] 160 | from=-3 161 | activation=linear 162 | 163 | [convolutional] 164 | batch_normalize=1 165 | filters=128 166 | size=1 167 | stride=1 168 | pad=1 169 | activation=leaky 170 | 171 | [convolutional] 172 | batch_normalize=1 173 | filters=256 174 | size=3 175 | stride=1 176 | pad=1 177 | activation=leaky 178 | 179 | [shortcut] 180 | from=-3 181 | activation=linear 182 | 183 | [convolutional] 184 | batch_normalize=1 185 | filters=128 186 | size=1 187 | stride=1 188 | pad=1 189 | activation=leaky 190 | 191 | [convolutional] 192 | batch_normalize=1 193 | filters=256 194 | size=3 195 | stride=1 196 | pad=1 197 | activation=leaky 198 | 199 | [shortcut] 200 | from=-3 201 | activation=linear 202 | 203 | 204 | [convolutional] 205 | batch_normalize=1 206 | filters=128 207 | size=1 208 | stride=1 209 | pad=1 210 | activation=leaky 211 | 212 | [convolutional] 213 | batch_normalize=1 214 | filters=256 215 | size=3 216 | stride=1 217 | pad=1 218 | activation=leaky 219 | 220 | [shortcut] 221 | from=-3 222 | activation=linear 223 | 224 | [convolutional] 225 | batch_normalize=1 226 | filters=128 227 | size=1 228 | stride=1 229 | pad=1 230 | activation=leaky 231 | 232 | [convolutional] 233 | batch_normalize=1 234 | filters=256 235 | size=3 236 | stride=1 237 | pad=1 238 | activation=leaky 239 | 240 | [shortcut] 241 | from=-3 242 | activation=linear 243 | 244 | [convolutional] 245 | batch_normalize=1 246 | filters=128 247 | size=1 248 | stride=1 249 | pad=1 250 | activation=leaky 251 | 252 | [convolutional] 253 | batch_normalize=1 254 | filters=256 255 | size=3 256 | stride=1 257 | pad=1 258 | activation=leaky 259 | 260 | [shortcut] 261 | from=-3 262 | activation=linear 263 | 264 | [convolutional] 265 | batch_normalize=1 266 | filters=128 267 | size=1 268 | stride=1 269 | pad=1 270 | activation=leaky 271 | 272 | [convolutional] 273 | batch_normalize=1 274 | filters=256 275 | size=3 276 | stride=1 277 | pad=1 278 | activation=leaky 279 | 280 | [shortcut] 281 | from=-3 282 | activation=linear 283 | 284 | # Downsample 285 | 286 | [convolutional] 287 | batch_normalize=1 288 | filters=512 289 | size=3 290 | stride=2 291 | pad=1 292 | activation=leaky 293 | 294 | [convolutional] 295 | batch_normalize=1 296 | filters=256 297 | size=1 298 | stride=1 299 | pad=1 300 | activation=leaky 301 | 302 | [convolutional] 303 | batch_normalize=1 304 | filters=512 305 | size=3 306 | stride=1 307 | pad=1 308 | activation=leaky 309 | 310 | [shortcut] 311 | from=-3 312 | activation=linear 313 | 314 | 315 | [convolutional] 316 | batch_normalize=1 317 | filters=256 318 | size=1 319 | stride=1 320 | pad=1 321 | activation=leaky 322 | 323 | [convolutional] 324 | batch_normalize=1 325 | filters=512 326 | size=3 327 | stride=1 328 | pad=1 329 | activation=leaky 330 | 331 | [shortcut] 332 | from=-3 333 | activation=linear 334 | 335 | 336 | [convolutional] 337 | batch_normalize=1 338 | filters=256 339 | size=1 340 | stride=1 341 | pad=1 342 | activation=leaky 343 | 344 | [convolutional] 345 | batch_normalize=1 346 | filters=512 347 | size=3 348 | stride=1 349 | pad=1 350 | activation=leaky 351 | 352 | [shortcut] 353 | from=-3 354 | activation=linear 355 | 356 | 357 | [convolutional] 358 | batch_normalize=1 359 | filters=256 360 | size=1 361 | stride=1 362 | pad=1 363 | activation=leaky 364 | 365 | [convolutional] 366 | batch_normalize=1 367 | filters=512 368 | size=3 369 | stride=1 370 | pad=1 371 | activation=leaky 372 | 373 | [shortcut] 374 | from=-3 375 | activation=linear 376 | 377 | [convolutional] 378 | batch_normalize=1 379 | filters=256 380 | size=1 381 | stride=1 382 | pad=1 383 | activation=leaky 384 | 385 | [convolutional] 386 | batch_normalize=1 387 | filters=512 388 | size=3 389 | stride=1 390 | pad=1 391 | activation=leaky 392 | 393 | [shortcut] 394 | from=-3 395 | activation=linear 396 | 397 | 398 | [convolutional] 399 | batch_normalize=1 400 | filters=256 401 | size=1 402 | stride=1 403 | pad=1 404 | activation=leaky 405 | 406 | [convolutional] 407 | batch_normalize=1 408 | filters=512 409 | size=3 410 | stride=1 411 | pad=1 412 | activation=leaky 413 | 414 | [shortcut] 415 | from=-3 416 | activation=linear 417 | 418 | 419 | [convolutional] 420 | batch_normalize=1 421 | filters=256 422 | size=1 423 | stride=1 424 | pad=1 425 | activation=leaky 426 | 427 | [convolutional] 428 | batch_normalize=1 429 | filters=512 430 | size=3 431 | stride=1 432 | pad=1 433 | activation=leaky 434 | 435 | [shortcut] 436 | from=-3 437 | activation=linear 438 | 439 | [convolutional] 440 | batch_normalize=1 441 | filters=256 442 | size=1 443 | stride=1 444 | pad=1 445 | activation=leaky 446 | 447 | [convolutional] 448 | batch_normalize=1 449 | filters=512 450 | size=3 451 | stride=1 452 | pad=1 453 | activation=leaky 454 | 455 | [shortcut] 456 | from=-3 457 | activation=linear 458 | 459 | # Downsample 460 | 461 | [convolutional] 462 | batch_normalize=1 463 | filters=1024 464 | size=3 465 | stride=2 466 | pad=1 467 | activation=leaky 468 | 469 | [convolutional] 470 | batch_normalize=1 471 | filters=512 472 | size=1 473 | stride=1 474 | pad=1 475 | activation=leaky 476 | 477 | [convolutional] 478 | batch_normalize=1 479 | filters=1024 480 | size=3 481 | stride=1 482 | pad=1 483 | activation=leaky 484 | 485 | [shortcut] 486 | from=-3 487 | activation=linear 488 | 489 | [convolutional] 490 | batch_normalize=1 491 | filters=512 492 | size=1 493 | stride=1 494 | pad=1 495 | activation=leaky 496 | 497 | [convolutional] 498 | batch_normalize=1 499 | filters=1024 500 | size=3 501 | stride=1 502 | pad=1 503 | activation=leaky 504 | 505 | [shortcut] 506 | from=-3 507 | activation=linear 508 | 509 | [convolutional] 510 | batch_normalize=1 511 | filters=512 512 | size=1 513 | stride=1 514 | pad=1 515 | activation=leaky 516 | 517 | [convolutional] 518 | batch_normalize=1 519 | filters=1024 520 | size=3 521 | stride=1 522 | pad=1 523 | activation=leaky 524 | 525 | [shortcut] 526 | from=-3 527 | activation=linear 528 | 529 | [convolutional] 530 | batch_normalize=1 531 | filters=512 532 | size=1 533 | stride=1 534 | pad=1 535 | activation=leaky 536 | 537 | [convolutional] 538 | batch_normalize=1 539 | filters=1024 540 | size=3 541 | stride=1 542 | pad=1 543 | activation=leaky 544 | 545 | [shortcut] 546 | from=-3 547 | activation=linear 548 | 549 | ###################### 550 | 551 | [convolutional] 552 | batch_normalize=1 553 | filters=512 554 | size=1 555 | stride=1 556 | pad=1 557 | activation=leaky 558 | 559 | [convolutional] 560 | batch_normalize=1 561 | size=3 562 | stride=1 563 | pad=1 564 | filters=1024 565 | activation=leaky 566 | 567 | [convolutional] 568 | batch_normalize=1 569 | filters=512 570 | size=1 571 | stride=1 572 | pad=1 573 | activation=leaky 574 | 575 | [convolutional] 576 | batch_normalize=1 577 | size=3 578 | stride=1 579 | pad=1 580 | filters=1024 581 | activation=leaky 582 | 583 | [convolutional] 584 | batch_normalize=1 585 | filters=512 586 | size=1 587 | stride=1 588 | pad=1 589 | activation=leaky 590 | 591 | [convolutional] 592 | batch_normalize=1 593 | size=3 594 | stride=1 595 | pad=1 596 | filters=1024 597 | activation=leaky 598 | 599 | [convolutional] 600 | size=1 601 | stride=1 602 | pad=1 603 | filters=255 604 | activation=linear 605 | 606 | 607 | [yolo] 608 | mask = 6,7,8 609 | anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 610 | classes=80 611 | num=9 612 | jitter=.3 613 | ignore_thresh = .7 614 | truth_thresh = 1 615 | random=1 616 | 617 | 618 | [route] 619 | layers = -4 620 | 621 | [convolutional] 622 | batch_normalize=1 623 | filters=256 624 | size=1 625 | stride=1 626 | pad=1 627 | activation=leaky 628 | 629 | [upsample] 630 | stride=2 631 | 632 | [route] 633 | layers = -1, 61 634 | 635 | 636 | 637 | [convolutional] 638 | batch_normalize=1 639 | filters=256 640 | size=1 641 | stride=1 642 | pad=1 643 | activation=leaky 644 | 645 | [convolutional] 646 | batch_normalize=1 647 | size=3 648 | stride=1 649 | pad=1 650 | filters=512 651 | activation=leaky 652 | 653 | [convolutional] 654 | batch_normalize=1 655 | filters=256 656 | size=1 657 | stride=1 658 | pad=1 659 | activation=leaky 660 | 661 | [convolutional] 662 | batch_normalize=1 663 | size=3 664 | stride=1 665 | pad=1 666 | filters=512 667 | activation=leaky 668 | 669 | [convolutional] 670 | batch_normalize=1 671 | filters=256 672 | size=1 673 | stride=1 674 | pad=1 675 | activation=leaky 676 | 677 | [convolutional] 678 | batch_normalize=1 679 | size=3 680 | stride=1 681 | pad=1 682 | filters=512 683 | activation=leaky 684 | 685 | [convolutional] 686 | size=1 687 | stride=1 688 | pad=1 689 | filters=255 690 | activation=linear 691 | 692 | 693 | [yolo] 694 | mask = 3,4,5 695 | anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 696 | classes=80 697 | num=9 698 | jitter=.3 699 | ignore_thresh = .7 700 | truth_thresh = 1 701 | random=1 702 | 703 | 704 | 705 | [route] 706 | layers = -4 707 | 708 | [convolutional] 709 | batch_normalize=1 710 | filters=128 711 | size=1 712 | stride=1 713 | pad=1 714 | activation=leaky 715 | 716 | [upsample] 717 | stride=2 718 | 719 | [route] 720 | layers = -1, 36 721 | 722 | 723 | 724 | [convolutional] 725 | batch_normalize=1 726 | filters=128 727 | size=1 728 | stride=1 729 | pad=1 730 | activation=leaky 731 | 732 | [convolutional] 733 | batch_normalize=1 734 | size=3 735 | stride=1 736 | pad=1 737 | filters=256 738 | activation=leaky 739 | 740 | [convolutional] 741 | batch_normalize=1 742 | filters=128 743 | size=1 744 | stride=1 745 | pad=1 746 | activation=leaky 747 | 748 | [convolutional] 749 | batch_normalize=1 750 | size=3 751 | stride=1 752 | pad=1 753 | filters=256 754 | activation=leaky 755 | 756 | [convolutional] 757 | batch_normalize=1 758 | filters=128 759 | size=1 760 | stride=1 761 | pad=1 762 | activation=leaky 763 | 764 | [convolutional] 765 | batch_normalize=1 766 | size=3 767 | stride=1 768 | pad=1 769 | filters=256 770 | activation=leaky 771 | 772 | [convolutional] 773 | size=1 774 | stride=1 775 | pad=1 776 | filters=255 777 | activation=linear 778 | 779 | 780 | [yolo] 781 | mask = 0,1,2 782 | anchors = 10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326 783 | classes=80 784 | num=9 785 | jitter=.3 786 | ignore_thresh = .7 787 | truth_thresh = 1 788 | random=1 789 | 790 | -------------------------------------------------------------------------------- /yolo/yolov3.txt: -------------------------------------------------------------------------------- 1 | person 2 | bicycle 3 | car 4 | motorcycle 5 | airplane 6 | bus 7 | train 8 | truck 9 | boat 10 | traffic light 11 | fire hydrant 12 | stop sign 13 | parking meter 14 | bench 15 | bird 16 | cat 17 | dog 18 | horse 19 | sheep 20 | cow 21 | elephant 22 | bear 23 | zebra 24 | giraffe 25 | backpack 26 | umbrella 27 | handbag 28 | tie 29 | suitcase 30 | frisbee 31 | skis 32 | snowboard 33 | sports ball 34 | kite 35 | baseball bat 36 | baseball glove 37 | skateboard 38 | surfboard 39 | tennis racket 40 | bottle 41 | wine glass 42 | cup 43 | fork 44 | knife 45 | spoon 46 | bowl 47 | banana 48 | apple 49 | sandwich 50 | orange 51 | broccoli 52 | carrot 53 | hot dog 54 | pizza 55 | donut 56 | cake 57 | chair 58 | couch 59 | potted plant 60 | bed 61 | dining table 62 | toilet 63 | tv 64 | laptop 65 | mouse 66 | remote 67 | keyboard 68 | cell phone 69 | microwave 70 | oven 71 | toaster 72 | sink 73 | refrigerator 74 | book 75 | clock 76 | vase 77 | scissors 78 | teddy bear 79 | hair drier 80 | toothbrush -------------------------------------------------------------------------------- /yolo_opencv.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | import cv2 4 | import argparse 5 | import numpy as np 6 | 7 | 8 | # 获取某层输出 9 | def get_output_layers(net): 10 | layer_names = net.getLayerNames() 11 | output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()] 12 | return output_layers 13 | 14 | 15 | # 画出识别结果 16 | def draw_prediction(img, class_id, confidence, x, y, x_plus_w, y_plus_h): 17 | label = str(classes[class_id]) 18 | color = COLORS[class_id] 19 | cv2.rectangle(img, (x,y), (x_plus_w,y_plus_h), color, 2) 20 | cv2.putText(img, label, (x-10,y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2) 21 | 22 | image_path = "n02090379_521.jpg" 23 | class_path = "yolov3.txt" 24 | weights_path = "yolov3.weights" 25 | config_path = "yolov3.cfg" 26 | 27 | if __name__ == '__main__': 28 | 29 | # 图像读入 30 | image = cv2.imread(image_path) 31 | Width = image.shape[1] 32 | Height = image.shape[0] 33 | scale = 0.00392 34 | classes = None 35 | 36 | # 种类读取 37 | with open(class_path, 'r') as f: 38 | classes = [line.strip() for line in f.readlines()] 39 | 40 | COLORS = np.random.uniform(0, 255, size=(len(classes), 3)) 41 | 42 | net = cv2.dnn.readNet(weights_path, config_path) 43 | blob = cv2.dnn.blobFromImage(image, scale, (416,416), (0,0,0), True, crop=False) 44 | net.setInput(blob) 45 | outs = net.forward(get_output_layers(net)) 46 | 47 | class_ids = [] 48 | confidences = [] 49 | boxes = [] 50 | conf_threshold = 0.5 51 | nms_threshold = 0.4 52 | 53 | 54 | for out in outs: 55 | for detection in out: 56 | scores = detection[5:] 57 | class_id = np.argmax(scores) 58 | confidence = scores[class_id] 59 | if confidence > 0.5: 60 | center_x = int(detection[0] * Width) 61 | center_y = int(detection[1] * Height) 62 | w = int(detection[2] * Width) 63 | h = int(detection[3] * Height) 64 | x = center_x - w / 2 65 | y = center_y - h / 2 66 | class_ids.append(class_id) 67 | confidences.append(float(confidence)) 68 | boxes.append([x, y, w, h]) 69 | 70 | 71 | indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold) 72 | 73 | 74 | # 显示识别效果 75 | for i in indices: 76 | i = i[0] 77 | box = boxes[i] 78 | x = box[0] 79 | y = box[1] 80 | w = box[2] 81 | h = box[3] 82 | draw_prediction(image, class_ids[i], confidences[i], round(x), round(y), round(x+w), round(y+h)) 83 | 84 | cv2.imshow("object detection", image) 85 | cv2.waitKey() 86 | 87 | cv2.imwrite("object-detection.jpg", image) 88 | cv2.destroyAllWindows() 89 | --------------------------------------------------------------------------------