基于Python實(shí)現(xiàn)一鍵找出磁盤(pán)里所有貓照
前言
最近在整理我磁盤(pán)上的照片,發(fā)現(xiàn)不少貓照,突然覺(jué)得若能把這些貓照都挑出來(lái),觀察它們的成長(zhǎng)軌跡也是一件不錯(cuò)的事情。一張一張的找實(shí)在是太費(fèi)勁了,能不能自動(dòng)化地找出來(lái)呢?
目標(biāo)檢測(cè),是許多計(jì)算機(jī)視覺(jué)應(yīng)用的重中之重,比如說(shuō)我們上次的實(shí)例分割:Python 20行代碼批量自動(dòng)摳圖,人體關(guān)鍵點(diǎn)提取、人臉識(shí)別等。而我們這一次,是要識(shí)別貓照。由于時(shí)間不多,我們沒(méi)有時(shí)間收集訓(xùn)練集,那么有沒(méi)有已經(jīng)訓(xùn)練好的目標(biāo)檢測(cè)模型呢?
這時(shí)候就要搬出paddlehub了,puddlehub有一個(gè)模型叫做YOLOv3,基于 Joseph Redmon和Ali Farhadi提出的單階段檢測(cè)器。該檢測(cè)器與達(dá)到同樣精度的傳統(tǒng)目標(biāo)檢測(cè)方法相比,推斷速度能達(dá)到接近兩倍。
YOLOv3將輸入圖像分成S*S個(gè)格子,每個(gè)格子預(yù)測(cè)B個(gè)bounding box,每個(gè)bounding box預(yù)測(cè)內(nèi)容包括: Location(x, y, w, h)、Confidence Score和C個(gè)類別的概率,因此我們不僅能夠找出貓的照片,還能定位它的位置!甚至能自動(dòng)數(shù)出一張照片里有多少只貓!
1.準(zhǔn)備
開(kāi)始之前,你要確保Python和pip已經(jīng)成功安裝在電腦上,如果沒(méi)有,可以訪問(wèn)這篇文章:超詳細(xì)Python安裝指南 進(jìn)行安裝。
(可選1) 如果你用Python的目的是數(shù)據(jù)分析,可以直接安裝Anaconda,它內(nèi)置了Python和pip.
(可選2) 此外,推薦大家用VSCode編輯器,它有許多的優(yōu)點(diǎn)
為了實(shí)現(xiàn)識(shí)別貓的功能,我們需要安裝 paddlepaddle, 進(jìn)入他們的官方網(wǎng)站就有詳細(xì)的指引
根據(jù)你自己的情況選擇這些選項(xiàng),最后一個(gè)CUDA版本,由于本實(shí)驗(yàn)不需要訓(xùn)練數(shù)據(jù),也不需要太大的計(jì)算量,所以直接選擇CPU版本即可。選擇完畢,下方會(huì)出現(xiàn)安裝指引,不得不說(shuō),Paddlepaddle 這些方面做的還是比較貼心的。
要注意,如果你的Python3環(huán)境變量里的程序名稱是Python,記得將python3 xxx 語(yǔ)句改為Python xxx 如下進(jìn)行安裝:
python -m pip install paddlepaddle -i https://mirror.baidu.com/pypi/simple
你還需要安裝paddlehub:
pip install -i https://mirror.baidu.com/pypi/simple paddlehub
2.編寫(xiě)代碼
我們先試試單圖片識(shí)別,找到貓貓:
新建predict.py文件,存放貓照在當(dāng)前文件夾的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輸入以下命令運(yùn)行文件:
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}]
可以看到,識(shí)別到了兩只貓,其中第一只貓頂部位置為961,右部位置為2024,左部位置為684,底部位置為2299。根據(jù)這個(gè)位置,編寫(xiě)代碼,用于框出相應(yīng)位置的貓:
def?paint_rect(input_img: str, output_path: str, ???????????????labels: list, position: list): ????""" ????畫(huà)出矩形 ????????:param input_img: 輸入圖片 ????????:param output_path: 輸出圖片 ????????:param labels: 標(biāo)簽 ????????:param positions: 坐標(biāo) ????公眾號(hào):Python實(shí)用寶典 ????""" ????img = cv2.imread(input_img) ????for?position?in?positions: ????????print(position) ????????# 畫(huà)矩形框, 輸入?yún)?shù)分別為圖像、左上角坐標(biāo)、右下角坐標(biāo)、顏色數(shù)組、粗細(xì) ????????cv2.rectangle( ????????????img, (position['left'], position['top']), ????????????(position['right'], position['bottom']), ????????????(0,?255,?0), thickness=10 ????????) ????if?'cat'?in?labels: ????????# 若是貓,則存到另一個(gè)地方 ????????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.批量自動(dòng)識(shí)別
這樣,我們就有思路進(jìn)行自動(dòng)識(shí)別了,首先獲得該文件夾下所有的圖片,其次,將這些圖片都放入分類器中進(jìn)行分類,最后,再根據(jù)分類的標(biāo)簽將其提取出來(lái)移動(dòng)到其他地方。
獲得該文件夾下所有圖片:
def?get_all_path(dirpath, *suffix): ????""" ????獲得所有路徑 ????@param dirpath: 目錄 ????@param *suffix: 后綴 ????公眾號(hào):Python實(shí)用寶典 ????""" ????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ù)標(biāo)簽畫(huà)框并移動(dòng):
def?paint_rect(input_img: str, output_path: str, ???????????????labels: list, position: list): ????""" ????畫(huà)出矩形 ????????:param input_img: 輸入圖片 ????????:param output_path: 輸出圖片 ????????:param labels: 標(biāo)簽 ????????:param positions: 坐標(biāo) ????公眾號(hào):Python實(shí)用寶典 ????""" ????img = cv2.imread(input_img) ????for?position?in?positions: ????????# 畫(huà)矩形框, 輸入?yún)?shù)分別為圖像、左上角坐標(biāo)、右下角坐標(biāo)、顏色數(shù)組、粗細(xì) ????????cv2.rectangle( ????????????img, (position['left'], position['top']), ????????????(position['right'], position['bottom']), ????????????(0,?255,?0), thickness=10 ????????) ????if?'cat'?in?labels: ????????# 若是貓,則存到另一個(gè)地方 ????????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): """ 畫(huà)出矩形 :param input_img: 輸入圖片 :param output_path: 輸出圖片 :param labels: 標(biāo)簽 :param positions: 坐標(biāo) """ img = cv2.imread(input_img) for position in positions: # 畫(huà)矩形框, 輸入?yún)?shù)分別為圖像、左上角坐標(biāo)、右下角坐標(biāo)、顏色數(shù)組、粗細(xì) cv2.rectangle( img, (position['left'], position['top']), (position['right'], position['bottom']), (0, 255, 0), thickness=10 ) if 'cat' in labels: # 若是貓,則存到另一個(gè)地方 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實(shí)現(xiàn)一鍵找出磁盤(pán)里所有貓照的文章就介紹到這了,更多相關(guān)Python找出磁盤(pán)貓照內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python對(duì)數(shù)組進(jìn)行反轉(zhuǎn)的方法
這篇文章主要介紹了python對(duì)數(shù)組進(jìn)行反轉(zhuǎn)的方法,涉及Python中reverse方法的使用技巧,需要的朋友可以參考下2015-05-05Python實(shí)現(xiàn)兩個(gè)list對(duì)應(yīng)元素相減操作示例
這篇文章主要介紹了Python實(shí)現(xiàn)兩個(gè)list對(duì)應(yīng)元素相減操作,結(jié)合具體實(shí)例形式分析了list對(duì)應(yīng)元素操作的簡(jiǎn)單實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-06-06比較兩個(gè)numpy數(shù)組并實(shí)現(xiàn)刪除共有的元素
這篇文章主要介紹了比較兩個(gè)numpy數(shù)組并實(shí)現(xiàn)刪除共有的元素,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02如何打包Python Web項(xiàng)目實(shí)現(xiàn)免安裝一鍵啟動(dòng)的方法
這篇文章主要介紹了如何打包Python Web項(xiàng)目,實(shí)現(xiàn)免安裝一鍵啟動(dòng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05Python檢查和同步本地時(shí)間(北京時(shí)間)的實(shí)現(xiàn)方法
這篇文章主要介紹了Python檢查和同步本地時(shí)間(北京時(shí)間)的實(shí)現(xiàn)方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12PyTorch中的參數(shù)類torch.nn.Parameter()詳解
這篇文章主要給大家介紹了關(guān)于PyTorch中torch.nn.Parameter()的相關(guān)資料,要內(nèi)容包括基礎(chǔ)應(yīng)用、實(shí)用技巧、原理機(jī)制等方面,文章通過(guò)實(shí)例介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02