基于Python實現(xiàn)一鍵找出磁盤里所有貓照
前言

最近在整理我磁盤上的照片,發(fā)現(xiàn)不少貓照,突然覺得若能把這些貓照都挑出來,觀察它們的成長軌跡也是一件不錯的事情。一張一張的找實在是太費勁了,能不能自動化地找出來呢?
目標檢測,是許多計算機視覺應(yīng)用的重中之重,比如說我們上次的實例分割:Python 20行代碼批量自動摳圖,人體關(guān)鍵點提取、人臉識別等。而我們這一次,是要識別貓照。由于時間不多,我們沒有時間收集訓(xùn)練集,那么有沒有已經(jīng)訓(xùn)練好的目標檢測模型呢?
這時候就要搬出paddlehub了,puddlehub有一個模型叫做YOLOv3,基于 Joseph Redmon和Ali Farhadi提出的單階段檢測器。該檢測器與達到同樣精度的傳統(tǒng)目標檢測方法相比,推斷速度能達到接近兩倍。
YOLOv3將輸入圖像分成S*S個格子,每個格子預(yù)測B個bounding box,每個bounding box預(yù)測內(nèi)容包括: Location(x, y, w, h)、Confidence Score和C個類別的概率,因此我們不僅能夠找出貓的照片,還能定位它的位置!甚至能自動數(shù)出一張照片里有多少只貓!
1.準備
開始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒有,可以訪問這篇文章:超詳細Python安裝指南 進行安裝。
(可選1) 如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda,它內(nèi)置了Python和pip.
(可選2) 此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點
為了實現(xiàn)識別貓的功能,我們需要安裝 paddlepaddle, 進入他們的官方網(wǎng)站就有詳細的指引

根據(jù)你自己的情況選擇這些選項,最后一個CUDA版本,由于本實驗不需要訓(xùn)練數(shù)據(jù),也不需要太大的計算量,所以直接選擇CPU版本即可。選擇完畢,下方會出現(xiàn)安裝指引,不得不說,Paddlepaddle 這些方面做的還是比較貼心的。

要注意,如果你的Python3環(huán)境變量里的程序名稱是Python,記得將python3 xxx 語句改為Python xxx 如下進行安裝:
python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
你還需要安裝paddlehub:
pip install -i https://mirror.baidu.com/pypi/simple paddlehub
2.編寫代碼
我們先試試單圖片識別,找到貓貓:

新建predict.py文件,存放貓照在當前文件夾的imgs文件夾下,命名為c1.jpg. 輸入以下代碼:
import?paddlehub?as?hub
# 加載模型
yolov3 = hub.Module(name="yolov3_darknet53_coco2017")
# 圖片位置
test_img_path =?"imgs/c1.jpg"
# 輸入圖片
input_dict = {"image": [test_img_path]}
# 輸出結(jié)果
results = yolov3.object_detection(data=input_dict)
for?result?in?results:
????print(result['path'])
????print(result['data'])在終端/CMD輸入以下命令運行文件:
python predict.py
# [{'left': 684.79376, 'right': 2024.4724, 'top': 961.53644, 'bottom': 2299.855, 'label': 'cat', 'confidence': 0.94765514}, {'left': 1461.0829, 'right': 3853.3633, 'top': 621.53064, 'bottom': 2769.5376, 'label': 'cat', 'confidence': 0.8093604}]可以看到,識別到了兩只貓,其中第一只貓頂部位置為961,右部位置為2024,左部位置為684,底部位置為2299。根據(jù)這個位置,編寫代碼,用于框出相應(yīng)位置的貓:
def?paint_rect(input_img: str, output_path: str,
???????????????labels: list, position: list):
????"""
????畫出矩形
????????:param input_img: 輸入圖片
????????:param output_path: 輸出圖片
????????:param labels: 標簽
????????:param positions: 坐標
????公眾號:Python實用寶典
????"""
????img = cv2.imread(input_img)
????for?position?in?positions:
????????print(position)
????????# 畫矩形框, 輸入?yún)?shù)分別為圖像、左上角坐標、右下角坐標、顏色數(shù)組、粗細
????????cv2.rectangle(
????????????img, (position['left'], position['top']),
????????????(position['right'], position['bottom']),
????????????(0,?255,?0), thickness=10
????????)
????if?'cat'?in?labels:
????????# 若是貓,則存到另一個地方
????????shutil.move(input_img, output_path + os.sep + input_img.split('/')[-1])
????????cv2.imwrite(output_path + os.sep +?'rect_%s'?% input_img.split('/')[-1], img)效果如下:

3.批量自動識別
這樣,我們就有思路進行自動識別了,首先獲得該文件夾下所有的圖片,其次,將這些圖片都放入分類器中進行分類,最后,再根據(jù)分類的標簽將其提取出來移動到其他地方。
獲得該文件夾下所有圖片:
def?get_all_path(dirpath, *suffix): ????""" ????獲得所有路徑 ????@param dirpath: 目錄 ????@param *suffix: 后綴 ????公眾號:Python實用寶典 ????""" ????path_array = [] ????for?r, ds, fs?in?os.walk(dirpath): ????????for?fn?in?fs: ????????????if?os.path.splitext(fn)[1]?in?suffix: ????????????????fname = os.path.join(r, fn) ????????????????path_array.append(fname) ????return?path_array # 獲得所有jpg和png圖片 image_paths = get_all_path(source_path,?'.jpg',?'.JPG',?'png',?'PNG')
放入分類器中分類:
# 加載模型
yolov3 = hub.Module(name="yolov3_darknet53_coco2017")
# 輸入圖片
input_dict = {"image": image_paths}
# 輸出結(jié)果
results = yolov3.object_detection(data=input_dict, labels=['cat'])根據(jù)標簽畫框并移動:
def?paint_rect(input_img: str, output_path: str,
???????????????labels: list, position: list):
????"""
????畫出矩形
????????:param input_img: 輸入圖片
????????:param output_path: 輸出圖片
????????:param labels: 標簽
????????:param positions: 坐標
????公眾號:Python實用寶典
????"""
????img = cv2.imread(input_img)
????for?position?in?positions:
????????# 畫矩形框, 輸入?yún)?shù)分別為圖像、左上角坐標、右下角坐標、顏色數(shù)組、粗細
????????cv2.rectangle(
????????????img, (position['left'], position['top']),
????????????(position['right'], position['bottom']),
????????????(0,?255,?0), thickness=10
????????)
????if?'cat'?in?labels:
????????# 若是貓,則存到另一個地方
????????shutil.move(input_img, output_path + os.sep + input_img.split('/')[-1])
????????cv2.imwrite(output_path + os.sep +?'rect_%s'?% input_img.split('/')[-1], img)
results = yolov3.object_detection(data=input_dict, labels=['cat'])
for?result?in?results:
????path = result['path']
????labels = []
????positions = []
????for?target?in?result['data']:
????????labels.append(target.get('label',?''))
????????positions.append({
????????????'left': target.get('left',?-1),
????????????'top': target.get('top',?-1),
????????????'right': target.get('right',?-1),
????????????'bottom': target.get('bottom',?-1)
????????})
????paint_rect(path, target_path, labels, positions)4.完整代碼
import paddlehub as hub
import cv2
import os
import shutil
def get_all_path(dirpath, *suffix):
"""
獲得所有路徑
@param dirpath: 目錄
@param *suffix: 后綴
"""
path_array = []
for r, ds, fs in os.walk(dirpath):
for fn in fs:
if os.path.splitext(fn)[1] in suffix:
fname = os.path.join(r, fn)
path_array.append(fname)
return path_array
def paint_rect(input_img: str, output_path: str,
labels: list, position: list):
"""
畫出矩形
:param input_img: 輸入圖片
:param output_path: 輸出圖片
:param labels: 標簽
:param positions: 坐標
"""
img = cv2.imread(input_img)
for position in positions:
# 畫矩形框, 輸入?yún)?shù)分別為圖像、左上角坐標、右下角坐標、顏色數(shù)組、粗細
cv2.rectangle(
img, (position['left'], position['top']),
(position['right'], position['bottom']),
(0, 255, 0), thickness=10
)
if 'cat' in labels:
# 若是貓,則存到另一個地方
shutil.move(input_img, output_path + os.sep + input_img.split('/')[-1])
cv2.imwrite(output_path + os.sep + 'rect_%s' % input_img.split('/')[-1], img)
if __name__ == '__main__':
source_path = './imgs/'
target_path = './target/'
# 獲得所有jpg和png圖片
image_paths = get_all_path(source_path, '.jpg', '.JPG', 'png', 'PNG')
# 加載模型
yolov3 = hub.Module(name="yolov3_darknet53_coco2017")
# 輸入圖片
input_dict = {"image": image_paths}
# 輸出結(jié)果
results = yolov3.object_detection(data=input_dict, labels=['cat'])
for result in results:
path = result['path']
labels = []
positions = []
print(path)
for target in result['data']:
labels.append(target.get('label', ''))
positions.append({
'left': target.get('left', -1),
'top': target.get('top', -1),
'right': target.get('right', -1),
'bottom': target.get('bottom', -1)
})
paint_rect(path, target_path, labels, positions)到此這篇關(guān)于基于Python實現(xiàn)一鍵找出磁盤里所有貓照的文章就介紹到這了,更多相關(guān)Python找出磁盤貓照內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決django的template中如果無法引用MEDIA_URL問題
這篇文章主要介紹了解決django的template中如果無法引用MEDIA_URL問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
Python中使用NumPy進行數(shù)據(jù)處理方式
這篇文章主要介紹了Python中使用NumPy進行數(shù)據(jù)處理方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-02-02
淺析關(guān)于Keras的安裝(pycharm)和初步理解
Keras 是一個用 Python 編寫的高級神經(jīng)網(wǎng)絡(luò) API,它能夠以 TensorFlow, CNTK, 或者 Theano 作為后端運行。這篇文章給大家介紹Keras的安裝(pycharm)和初步理解,感興趣的朋友一起看看吧2020-10-10

