關於在一張圖片中查找目標物體的方法 —— EasyDL和opencv結合使用


1. 概括

  EasyDL是百度AI中一個自動化的深度學習模型訓練和服務平臺

  使用EasyDL訓練得到模型,在python下調用對應模型的api,可以實現對圖片上傳至雲端進行識別,並接收返回的識別結果,再使用opencv通過返回的結果在圖片上進行繪製,框出目標物體,還可以得到其中心座標值
  進一步,其提供了多種部署方式,後面還可以將模型部署到私有云或者本地,可以更方便的拓展使用


2. 使用EasyDL訓練模型

使用EasyDL的鏈接,使用之前需要先註冊或登錄百度賬號,使用百度網盤賬號登錄也可以,都需要實名才能使用

 點擊開始訓練,使用經典版,這裏以物體檢測爲例

 先進入我的模型,然後創建模型,填寫相關信息即可,下一步,然後就可以可到新的模型已經創建

 需要新創建一個數據集,選擇下面的選項之後上傳照片,要求圖片命名不要有中文名,並且圖片的場景最好和後面要識別的場景一樣,多個角度,多個光線,25+張照片就可以,不過最好有40+,上傳完成之後,點擊確認並返回

 可以看到數據集的狀態還在處理中,等待處理完成即可;然後點擊後面的標註,對需要訓練的圖片進行標註需要識別的目標物體;先添加標籤,不能使用中文名,然後將目標物體框起來,再點擊對應的便籤即可
 通過多個標籤可以做到識別多個目標的目的,然後按下面的保存;接着需要手動點上方圖片進行選擇下一張需要標註的圖片,以此方法對所有圖片進行標註即可,完成後回到我的模型頁面

 回到我的模型頁面,選擇下面的訓練,選擇需要訓練的模型,這裏以公有云部署爲例,添加數據集,開始訓練之後,可以在我的模型頁面看到訓練的狀態,還可以設置短信提醒,40張照片的訓練預計30分鐘左右

 訓練完成之後,可以對模型進行檢驗,然後進行申請上線,這個過程可能也有點久,快的話當天可以完成,最慢就是第二天,可能會有百度雲的客服打電話過來詢問(類似於推廣告吧),最好接一下,說明你是在學習,測試一下,準備做項目,如果她繼續問更深入信息,你就說不方便透露,如果有需要再和你們聯繫就好了


3.在python調用EasyDL的api

 審覈結束,然後在我的模型頁面,點擊服務詳情,就可以看到模型的url(後面會用到),然後點擊立即使用

 在EasyDL經典版控制檯創建應用,填寫相關信息即可,然後在應用詳情頁獲取AK和SK

 接着需要獲取access_token,使用到上文的AK和SK,及應用詳情裏的API Key和Secret Key,複製以下鏈接,將AK和SK修改成自己的(注意是沒有【】的),然後用瀏覽器打開該鏈接,即可得到access_token,獲取access_token這部分也可以在代碼中實現

https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=【百度雲應用的AK】&client_secret=【百度雲應用的SK】

 可查閱使用文檔 經典版物體檢測API調用文檔

 以下是官方提供的python示例,需要注意的是python3中使用的不是urllib2

# encoding:utf-8
import urllib2

'''
easydl物體檢測
'''

request_url = "【接口地址】"

params = "{\"image\":\"sfasq35sadvsvqwr5q...\"}"

access_token = '[調用鑑權接口獲取的token]'
request_url = request_url + "?access_token=" + access_token
request = urllib2.Request(url=request_url, data=params)
request.add_header('Content-Type', 'application/json')
response = urllib2.urlopen(request)
content = response.read()
if content:
    print content


 按照服務API的說明,針對V1版(YOLOV3)的服務,編寫調用代碼(Python3)。需要注意的是與其他圖像識別服務不同的是定製化圖像識別服務以json方式請求。

 下面是我的代碼,僅供參考,如有錯誤,還望指正!


import time
import base64
import urllib3,json
import cv2


test_img_path = "E:/study/python/test4.jpg"
save_img_path = "E:/study/python/resule.jpg"

#access_token = "24.ee098060f9d444677770e289b6d8780b.*****************" #自己的access_token
#module_url = 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/d********' #當審覈通過後,可以在我的模型頁面,進入服務詳情可以查看到

def img_show(name,img_path):
    img = cv2.imread(img_path)
    print('shape:',img.shape)
    img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST)
    cv2.imshow(name ,img)
    cv2.waitKey(0)

def draw_result_img(originfilename,results,resultfilename):
    from PIL import Image, ImageDraw,ImageFont
    image_origin = Image.open(originfilename)
    draw = ImageDraw.Draw(image_origin)
    setFont = ImageFont.truetype('C:/windows/fonts/simhei.ttf', 66)
    for result in results:
        location = result['location']
        top_x,top_y = location['left'],location['top']
        button_x,button_y = (location['left']+location['width']),(location['top']+location['height'])
        center_x,cenrer_y = int(top_x+(location['width']/2)),int(top_y+(location['height']/2))
        print('目標物體中心座標:',center_x,cenrer_y)
        draw.rectangle((top_x,top_y,button_x,button_y),outline = "red")
        draw.ellipse((center_x-10,cenrer_y-10, center_x+10,cenrer_y+10), fill = (255, 0, 0))
        draw.text((top_x,top_y), result['name']+', Score:'+str(round(result['score'],3)),"yellow",font=setFont)
    image_origin.save(resultfilename, "JPEG")
    img_show('result',save_img_path)

def get_test_img():
    img_show('test_img',test_img_path)
    with open(test_img_path, 'rb') as f:
        img = base64.b64encode(f.read())
        #img參數進行一下str轉換    
        params={'image':''+str(img,'utf-8')+''}
        #對參數params數據進行json處理
        encoded_data = json.dumps(params).encode('utf-8')
        return encoded_data

def get_result():
    encoded_data = get_test_img()
    url = "{}?access_token={}".format(module_url,access_token)
    begin = time.perf_counter()
    request = urllib3.PoolManager().request('POST', 
                          url,
                          body = encoded_data,
                          headers={'Content-Type':'application/json'})
    #對返回的byte字節進行處理。Python3輸出位串,而不是可讀的字符串,需要進行轉換
    content = str(request.data,'utf-8')
    end = time.perf_counter()
    if content:
        data = json.loads(content)
        utime = end - begin
        return data,utime
    else:
        return False


data,utime = get_result()
results = data['results']
print(results)
print('處理時長:'+'%.2f'%(utime)+'秒')
draw_result_img(test_img_path,results,save_img_path)



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章