物體偵測(Object Detection) + 影像標題(Image Captioning)

文章推薦指數: 80 %
投票人數:10人

圖. 影像標題(Image Captioning),圖片來源:cs231n_2017_lecture11 Detection and Segmentation. 前言. 影像辨識的發展,可以從ImageNet ILSVRC 挑戰賽(Large Scale ... 2018iT邦幫忙鐵人賽 DAY 12 4 AI&MachineLearning 以100張圖理解NeuralNetwork--觀念與實踐系列第 12篇 Day12:物體偵測(ObjectDetection)+影像標題(ImageCaptioning) 2018鐵人賽 neuralnetwork machinelearning ai IcodesoIam 2017-12-2209:37:4566921瀏覽 圖.影像標題(ImageCaptioning),圖片來源:cs231n_2017_lecture11DetectionandSegmentation 前言 影像辨識的發展,可以從ImageNetILSVRC挑戰賽(LargeScaleVisualRecognitionChallenge)題目一窺端倪,2011年題目為影像分類(Classification)、影像分類及定位(ClassificationwithLocalization),到了2017年題目為物體定位(ObjectLocalization)、物體偵測(ObjectDetection)、影片物體偵測(ObjectDetectionfromVideo),就可以了解整個技術的演進,我們看看下圖,電腦視覺的應用概分為下列幾類: 分類(Classification) 按語意切割(SemanticSegmentation):按事物類別區分像素分塊,不區分『實例』(Instance)。

定位(Classification+Localization):標註單一物體(SingleObject)所在的位置及大小。

物體偵測(ObjectDetection):標註多個物體(MultipleObject)所在的位置及大小。

實體切割(InstanceSegmentation):標註『實例』(Instance),同一類的物體可以區分各別的位置及大小,尤其物體之間有重疊。

圖.除了分類(Classification),其他電腦視覺的應用,圖片來源:cs231n_2017_lecture11DetectionandSegmentation 之前在『Day10:CNN應用--找出相似的照片』一篇介紹如何找到我們如何找到相似的物體,問題再延伸一點,我們還要知道物體所在的位置及大小,進而把它標註出來,以利使用者迅速找到關注的物體,例如從監視器找嫌疑犯,如果能在每一幀(Frame)標註嫌疑犯,那警察抓嫌疑犯就方便多了。

所以,我們就來看看怎麼實作。

相關技術 實作的基礎還是應用『Day09:CNN經典模型應用』介紹的方法,先找出符合的物體,之後再判斷哪一區域有符合的物體,且機率最高,即將該區域以方框標註,如下圖,CNN後分別接兩種全連階層,一個作分類(Classification),另一個標註符合的區域。

圖.定位演算法模型,圖片來源:CS231n第八課:目標檢測定位學習記錄-IT閱讀 至於,標註區域的方式有下列幾類演算法: 滑動視窗(SlidingWindow):這是一種窮舉法,設定各種尺寸的區域,從左上角開始滑動,找出所有區域,然後,看哪一個區域符合的機率最高。

這種方法最簡單,但是也相對耗時。

圖.滑動視窗(SlidingWindow)模型,圖片來源:CS231n第八課:目標檢測定位學習記錄-IT閱讀 RegionProposals:利用了圖像中的紋理、邊緣、顏色等信息,人為定義可能含有目標的RoI(RegionsofInterest)區域,只針對這些區域比較符合的機率,每秒可過濾上千個區域,相關演算法有R-CNN、FastR-CNN、FasterR-CNN...等。

圖.RegionProposals示意圖,圖片來源:CS231n第八課:目標檢測定位學習記錄-IT閱讀 迴歸方法:將圖片切成小方塊(Grid),再以小方塊中心點選擇幾種尺寸的區域,利用迴歸方法計算每個區域含有目標的機率。

這種方法較RegionProposals慢,但適合即時(RealTime)偵測,目前相關演算法有有YOLO(YouOnlyLookOnce)、SSD(SingleShotMultiBoxDetector)...等。

圖.迴歸方法說明,圖片來源:cs231n_2017_lecture11DetectionandSegmentation 我們就舉SSD演算法為例來測試看看效果如何。

實作 本程式來自ObjectDetection·MartinThoma,程式較長,不易說明,我將部分參數固定(HardCode),並加上註解,放在SSD資料夾,可在這裡找到,其中weights_SSD300.hdf5檔案過大,請自https://mega.nz/#F!7RowVLCL!q3cEVRK9jyOSB9el3SssIA下載,放在SSD資料夾中,再準備一組照片檔(*.jpg"),辨識內容限20類照片--飛機、單車、鳥、小船、瓶子、巴士、轎車、貓、椅子、牛、餐桌、狗、馬、機車、人、盆栽、羊、沙發、火車、顯示器等,放在程式所在目錄下的images子目錄,然後執行下列指令: pythonssd_test.py """ RunobjectdetectionwithVOCclasses. Thisisjustaminormodificationofcodefrom https://github.com/rykov8/ssd_keras """ fromkeras.applications.imagenet_utilsimportpreprocess_input fromkeras.preprocessingimportimage importmatplotlib.pyplotasplt importnumpyasnp fromscipy.miscimportimread importsys fromssdimportSSD300 fromssd_utilsimportBBoxUtility importos fromos.pathimportbasename defcreate_overlay(img,results,,plt_fname): plt.clf() #Parsetheoutputs. det_label=results[:,0] det_conf=results[:,1] det_xmin=results[:,2] det_ymin=results[:,3] det_xmax=results[:,4] det_ymax=results[:,5] #Getdetectionswithconfidencehigherthan0.6. top_indices=[ifori,confinenumerate(det_conf)ifconf>=0.6] top_conf=det_conf[top_indices] top_label_indices=det_label[top_indices].tolist() top_xmin=det_xmin[top_indices] top_ymin=det_ymin[top_indices] top_xmax=det_xmax[top_indices] top_ymax=det_ymax[top_indices] colors=plt.cm.hsv(np.linspace(0,1,21)).tolist() plt.imshow(img/255.) currentAxis=plt.gca() currentAxis.axis('off') foriinrange(top_conf.shape[0]): xmin=int(round(top_xmin[i]*img.shape[1])) ymin=int(round(top_ymin[i]*img.shape[0])) xmax=int(round(top_xmax[i]*img.shape[1])) ymax=int(round(top_ymax[i]*img.shape[0])) score=top_conf[i] label=int(top_label_indices[i]) label_name=voc_classes[label-1] display_txt='{:0.2f},{}'.format(score,label_name) coords=(xmin,ymin),xmax-xmin+1,ymax-ymin+1 color=colors[label] currentAxis.add_patch(plt.Rectangle(*coords, fill=False, edgecolor=color, linewidth=2)) currentAxis.text(xmin,ymin,display_txt, bbox={'facecolor':color,'alpha':0.5}) plt.savefig(plt_fname) print("save"+plt_fname) if__name__=="__main__": importglob imagesList=glob.glob("images/*.jpg") #Loadthemodel voc_classes=['Aeroplane','Bicycle','Bird','Boat','Bottle', 'Bus','Car','Cat','Chair','Cow','Diningtable', 'Dog','Horse','Motorbike','Person','Pottedplant', 'Sheep','Sofa','Train','Tvmonitor'] NUM_CLASSES=len(voc_classes)+1 input_shape=(300,300,3) model=SSD300(input_shape,num_classes=NUM_CLASSES) model.load_weights('weights_SSD300.hdf5',by_name=True) bbox_util=BBoxUtility(NUM_CLASSES) #Loadtheinputs inputs=[] images=[] forimg_pathinimagesList: print("process"+img_path) img=image.load_img(img_path,target_size=(300,300)) img=image.img_to_array(img) images.append(imread(img_path)) inputs.append(img.copy()) #前置處理 print("前置處理...") inputs=preprocess_input(np.array(inputs)) #預測 print("預測...") preds=model.predict(inputs,batch_size=1,verbose=1) #取得預測結果 results=bbox_util.detection_out(preds) print("results[0]=") print(results[0][0][1]) #createfolderifnotexist output_directory="results" ifnotos.path.exists(output_directory): os.makedirs(output_directory) #procesimages fori,imginenumerate(images): #產生有框的outputfiles create_overlay(img,results[i],voc_classes, output_directory+"/{}.png".format(basename(os.path.splitext(imagesList[i])[0]))) #Garbagecollection,topreventfromTensorFlowerror importgc gc.collect() 程式說明 程式不像前兩篇,這次的程式很快就可以執行完,程式流程說明如下: 首先會搜尋images資料夾下的jpg檔案。

呼叫SSD300函數,載入模型及訓練好的參數檔。

呼叫detection_out函數,取得預測結果,放在results變數,內容包括的類別序號及對應的機率,還有標註方框的位置及大小。

呼叫create_overlay函數,將標註方框及類別名稱畫在原圖上,另存新檔,放在results資料夾,附檔名為png。

SSD模型定義在ssd.py中,該模型結構非常複雜,可以在呼叫SSD300函數後,加下列指令將結構圖存檔: fromkeras.utils.vis_utilsimportplot_model plot_model(model,to_file='model_plot.png',show_shapes=True,show_layer_names=True) 針對執行結果有以下幾點說明: 影像標題(ImageCaptioning):結果不只會有方框,也會標註類別名稱,如果不在20類的物體會顯示錯誤的類別名稱,如大象及熊讚。

只限20類是因為我們直接載入訓練好的模型(Pre-trainedModel)--weights_SSD300.hdf5,它的訓練資料只含20類物體,實際應用時,可以針對目標,放入更適合的類別資料,重新訓練,就可以得到我們想要的結果了。

訓練資料來源為PASCALVisualObjectClasses。

理論基礎請參考『SSD:SingleShotMultiBoxDetector』。

本例是將結果存檔,如果要將結果直接顯示出來,可搭配使用OpenCV工具箱。

結語 有關影像的辨識就介紹到這裡,其實,筆者還很想花時間作一些實驗,但迫於鐵人賽不等人,只好等賽程結束,再好好重整旗鼓了,下一次開始我們就要開始『自然語言處理』之旅,它涉及的知識範圍更廣,筆者會花更多的篇幅,與大家一起努力。

留言4 追蹤 檢舉 上一篇 Day11:風格轉換(StyleTransfer)--人人都可以是畢卡索 下一篇 Day13:『自然語言處理』(NLP)概念介紹 系列文 以100張圖理解NeuralNetwork--觀念與實踐 共31篇 目錄 RSS系列文 訂閱系列文 401人訂閱 27 Day27:音樂資訊檢索(MusicInformationRetrieval,MIR) 28 Day28:小學生談『生成對抗網路』(GenerativeAdversarialNetwork,GAN) 29 Day29:機器學習的資料處理生命週期 30 Day30:完結篇--MachineLearning工作前景與技能 31 DayN+1:進一步理解『梯度下降』(GradientDescent) 完整目錄 4則留言 舊至新 新至舊 最高Like數 2 ronaldxsun iT邦新手5級‧ 2018-01-1714:44:42 版主你好 請問若不想利用現成以訓練好的資料庫 想要自行訓練一筆資料 請問有什麼參考方法可以提供嗎? 回應 3 檢舉 IcodesoIam iT邦高手1級‧ 2018-01-1715:18:34 檢舉 如果不是要辨識voc的20類物品,要重新訓練其他物品,可以不要載入權重,即將下行拿掉: model.load_weights('weights_SSD300.hdf5',by_name=True) 再將訓練資料集放入模型中,重新訓練即可。

如果不是要辨識voc的20類物品,要重新訓練其他物品,可以不要載入權重,即將下行拿掉: model.load_weights('weights_SSD300.hdf5',by_name=True) 再將訓練資料集放入模型中,重新訓練即可。

修改 ronaldxsun iT邦新手5級‧ 2018-01-1812:05:37 檢舉 了解~ 不好意思,因為對於SSD的架構還不是太了解。

"再將訓練資料集放入模型中,重新訓練即可。

" 意思是再撰寫一份train.py的檔案output成.hdf5就可以了嗎? 因為看專案裡面好像沒有提供訓練的code。

麻煩版主 了解~ 不好意思,因為對於SSD的架構還不是太了解。

"再將訓練資料集放入模型中,重新訓練即可。

" 意思是再撰寫一份train.py的檔案output成.hdf5就可以了嗎? 因為看專案裡面好像沒有提供訓練的code。

麻煩版主 修改 IcodesoIam iT邦高手1級‧ 2018-01-1816:50:04 檢舉 請參考下列這一篇: https://ithelp.ithome.com.tw/articles/10191404 將原先的 model.load_weights('weights_SSD300.hdf5',by_name=True) 改為進行訓練,x/y為自行準備的訓練資料 train_history=model.fit(x=x_Train_norm,y=y_TrainOneHot,validation_split=0.2,epochs=10,batch_size=800,verbose=2) 請參考下列這一篇: https://ithelp.ithome.com.tw/articles/10191404 將原先的 model.load_weights('weights_SSD300.hdf5',by_name=True) 改為進行訓練,x/y為自行準備的訓練資料 train_history=model.fit(x=x_Train_norm,y=y_TrainOneHot,validation_split=0.2,epochs=10,batch_size=800,verbose=2) 修改 登入發表回應 0 peterhsu iT邦新手5級‧ 2018-01-1920:16:00 邦友你好 謝謝你做關於此tensorflow的文章, 我也對對於如何製作自己的trainmodel感到疑惑, 也有參考樓上的留言但是還是不太了解。

因為其中的model.load_weights('weights_SSD300.hdf5',by_name=True) 是指讀取weights_SSD300.hdf5 其中day2的mnist訓練方法也適用於SSD300嗎? 如何製作一個適合SSD300的trainningmodel.hdf5不太了解該怎麼進行.. 謝謝您 回應 2 檢舉 IcodesoIam iT邦高手1級‧ 2018-01-1922:06:25 檢舉 Keras的程序是固定的 建立模型:本例如下,SSD300定義在ssd.py model=SSD300(input_shape,num_classes=NUM_CLASSES) 訓練模型:model.fit,本例直接載入事先訓練的參數(model.load_weights),未進行訓練,故要自行訓練,則需改為fit 評估模型:model.evaluate 預測:model.predict day2展示自行訓練的完整程序,所以,本例要自行訓練,可參考day2。

要儲存訓練結果,請參考day4,或執行下列指令: fromkeras.modelsimportload_model model.save('model.h5')#createsaHDF5file'model.h5' Keras的程序是固定的 1.建立模型:本例如下,SSD300定義在ssd.py model=SSD300(input_shape,num_classes=NUM_CLASSES) 2.訓練模型:model.fit,本例直接載入事先訓練的參數(model.load_weights),未進行訓練,故要自行訓練,則需改為fit 3.評估模型:model.evaluate 4.預測:model.predict day2展示自行訓練的完整程序,所以,本例要自行訓練,可參考day2。

要儲存訓練結果,請參考day4,或執行下列指令: fromkeras.modelsimportload_model model.save('model.h5')#createsaHDF5file'model.h5' 修改 peterhsu iT邦新手5級‧ 2018-01-2319:15:52 檢舉 您好 謝謝你的回答,請問若只需要訓練兩類(指非A即B) 那我model.fit裡面變數該怎麼撰寫呢? 因為不太了解內部變數的意義。

不好意思麻煩你 您好 謝謝你的回答,請問若只需要訓練兩類(指非A即B) 那我model.fit裡面變數該怎麼撰寫呢? 因為不太了解內部變數的意義。

不好意思麻煩你 修改 登入發表回應 0 whard iT邦新手5級‧ 2019-01-0201:49:53 版主您好, 感謝您這篇文章的教學,我也照著您的Day2及Day4兩篇文章使用Cifar-10這個數據集完成了訓練並且存成了hdf5檔, 但是使用model.load_weights匯入hdf5檔後,預測出來的框完全是錯誤的(很多都是標空白處), 想請問這樣的情況是因為訓練圖片大小的問題嗎(3232)?是否一定要用300300得圖檔來訓練呢?? 還是預測程式這邊有參數設定錯誤了???還麻煩版主您解答了。

回應 1 檢舉 IcodesoIam iT邦高手1級‧ 2019-01-0218:49:53 檢舉 應該是圖片大小的問題,必須是300x300以上,程式會自動resize,解析度過低無法解析。

Cifar-10解析度只有32x32。

應該是圖片大小的問題,必須是300x300以上,程式會自動resize,解析度過低無法解析。

Cifar-10解析度只有32x32。

修改 登入發表回應 0 johnsonnnn iT邦新手5級‧ 2019-11-2614:56:53 你好 用ssd訓練時圖片不是會resize 那我們輸入的標記框不需要修改大小嗎? 回應 3 檢舉 IcodesoIam iT邦高手1級‧ 2019-11-2619:56:47 檢舉 ssd_test.py第90行 img=image.load_img(img_path,target_size=(300,300)) 會自動resize ssd_test.py第90行 img=image.load_img(img_path,target_size=(300,300)) 會自動resize 修改 johnsonnnn iT邦新手5級‧ 2019-11-2622:27:58 檢舉 謝謝你的回答 謝謝你的回答 修改 johnsonnnn iT邦新手5級‧ 2019-11-3019:22:14 檢舉 還有想請問訓練時的priors應該如何設置 還有想請問訓練時的priors應該如何設置 修改 登入發表回應 我要留言 立即登入留言 iT邦幫忙鐵人賽 參賽組數 1087組 團體組數 52組 累計文章數 20471篇 完賽人數 572人 鐵人賽最新文章 大盤到底能不能攻上一萬八?? gotodie?那個goto到底能不能用啊? 2021/12/12更新 予焦啦!一夢終須醒...... 盤點清查與檢測掃描-資通安全健診 [13th][Day23]httpresponseheader(下) [13th][Day22]httpresponseheader(上) [13th][Day21]golangcontext 股票怎麼選?掌握這原則,你也能找到強勢股 Gitpush 前往鐵人賽 技術推廣專區 [Day2]抓取每日收盤價 [Day1]基本工具安裝 利用python取得永豐銀行API的Nonce [Day03]tinyML開發板介紹 永豐金融API測試員 [Day01]在享受tinyML這道美食之前 [Day3]使用ta-lib製作指標 [Day4]函數打包與買進持有報酬率試算 計算API所需要的參數:HashID 計算API所需要的參數:IV 前往鐵人賽 熱門問題 我有一個客戶中了mljx病毒勒索950美金我免費轉讓有人要接嗎? 加班提醒視窗 家中的網路配置 C#超級新手請教一個非常笨的問題 Google相簿背後的系統設計? 切割vlan網段方式 臉書訊息讀取狀態 【已解決】如何安裝舊版本的VS2019 請問目前php8版本的問題 DNS好像怪怪的 IT邦幫忙 站方公告 【2021iThome鐵人賽】登登登!究竟獎落誰家,2021iThome鐵人賽得獎名單正式揭曉 熱門tag 看更多 13th鐵人賽 12th鐵人賽 11th鐵人賽 鐵人賽 2019鐵人賽 2018鐵人賽 javascript 2017鐵人賽 windows php python windowsserver linux c# 程式設計 資訊安全 css vue.js sql 分享 熱門回答 家中的網路配置 切割vlan網段方式 Google相簿背後的系統設計? 請問目前php8版本的問題 請問大神centos5.5DNSSERVER的DNS檔案在哪個路徑 請問初學laravel要做什麼專案 LinuxCent7OS(文字介面) C#超級新手請教一個非常笨的問題 關於網頁顯示問題 加班提醒視窗 熱門文章 gotodie?那個goto到底能不能用啊? 予焦啦!一夢終須醒...... 2021/12/12更新 第九隻狗勾 第八隻狗勾 軟體工程師從新手到高手的流程 大盤到底能不能攻上一萬八?? 【從零開始的C語言筆記】第二十九篇-讀檔&寫檔(1) CI/CD-Drone五分鐘成為終極工具人 群輝ds920+nas網路儲存設備簡易開箱,滿足家庭影音需求 一週點數排行 更多點數排行 海綿寶寶(antijava) ㊣浩瀚星空㊣(yoching) 居然解出來了(partyyaya) ccenjor(ccenjor) japhenchen(japhenchen) mathewkl(mathewkl) 小山丘(a243318490) horace_work(horace_work) juck30808(juck30808) raytracy(raytracy) × At 輸入對方的帳號或暱稱 Loading 找不到結果。

標記 {{result.label}} {{result.account}} 關閉



請為這篇文章評分?