0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

基于OpenCV來實現(xiàn)對圖像中目標對象檢測識別 以土地為例

新機器視覺 ? 來源:http://yishuihancheng.blog.csd ? 作者:沂水寒城 ? 2020-11-23 16:33 ? 次閱讀

OpenCV是一款非常強大的圖像處理工具,對于從事圖像處理領域相關工作的人來說這個可以說是必不可少的一項工具,用起來也很方面,下嗎是一段簡單的介紹:

OpenCV是一個基于BSD許可(開源)發(fā)行的跨平臺計算機視覺機器學習軟件庫,可以運行在Linux、Windows、Android和Mac OS操作系統(tǒng)上。它輕量級而且高效——由一系列 C 函數(shù)和少量 C++ 類構成,同時提供了Python、Ruby、MATLAB等語言的接口,實現(xiàn)了圖像處理和計算機視覺方面的很多通用算法。OpenCV用C++語言編寫,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要傾向于實時視覺應用,并在可用時利用MMX和SSE指令, 如今也提供對于C#、Ch、Ruby,GO的支持。

OpenCV官網是https://opencv.org/,首頁截圖如下所示:

下面給出來幾個學習OpenCV的鏈接:

https://docs.opencv.org/master/d9/df8/tutorial_root.html https://docs.opencv.org/ https://www.zhihu.com/question/26881367我們今天的內容主要是想基于OpenCV來實現(xiàn)對圖像中我們關注的一些目標對象進行檢測識別或者說是對其存在的區(qū)域位置進行挖掘,在開始這篇文章之前,我曾經看到了有人基于OpenCV實現(xiàn)了火焰或者是煙霧的檢測,其實不管是類似的物體的檢測也好不相關的物體識別檢測也好,很大程度是比較通用的做法都是基于像素來完成最終的計算的。 這里我們以生活中最為常見的土地來作為要識別檢測的目標對象進行實驗,先來看一張網上找到的圖片,如下所示:

接下來先看一下,最終的識別檢測效果:

從上面的結果來看,比較完全地檢測到了圖中出現(xiàn)的土地的區(qū)域,最終,我們采用外切矩形的方式完成了對其輪廓數(shù)據(jù)的確定。 接下來,我們進入正文,在實際去實踐之前,我們很有必要來了解一下幾種比較常用的顏色空間,簡單總結匯總如下:

RGB顏色空間: R:Red紅色 G:Green綠色 B:Blue藍色 HSV顏色空間: H:Hue色度 S:Saturation飽和度 V:Value亮度 HSI顏色空間: H:Hue色度 S:Saturation飽和度 I:Intensity強度本質上來講,不同的物體不同的對象自身的像素范圍是不同的,在實際操作的時候基于像素區(qū)間可以過濾得到你所關注的對象,通常這樣的操作會在HSV空間中進行,個人的理解是將原始的BGR或者是RGB的圖像轉化到HSV空間里面來確定目標對象的像素區(qū)間更為容易,我實際測試過,在RGB和BGR空間里面也是可以進行計算的,只不過不如HSV空間,這里就不再多討論了,可以嘗試別的方式,本文用的是HSV空間進行計算的。 最開始的時候去確定目標對象所處的像素空間是很笨拙的,主要是借助OpenCV和matplotlib實現(xiàn)的“人眼探索”,比較麻煩,后來在github社區(qū)里面找到了一個界面的實現(xiàn),覺得很不錯,就拿來用了,這里貼出來源碼實現(xiàn),如下所示:#!usr/bin/envpython #encoding:utf-8 from__future__importdivision ''' 功能:HSV空間圖片色素范圍查看器 ''' importcv2 importnumpyasnp defnothing(x): pass defcolorLooker(pic='1.png'): ''' HSV空間圖片色素范圍查看器 ''' #圖像加載 image=cv2.imread(pic) #窗口初始化 cv2.namedWindow('image',cv2.WINDOW_NORMAL) #創(chuàng)建拖動條 #Opencv中Hue取值范圍是0-179 cv2.createTrackbar('HMin','image',0,179,nothing) cv2.createTrackbar('SMin','image',0,255,nothing) cv2.createTrackbar('VMin','image',0,255,nothing) cv2.createTrackbar('HMax','image',0,179,nothing) cv2.createTrackbar('SMax','image',0,255,nothing) cv2.createTrackbar('VMax','image',0,255,nothing) #設置默認最大值 cv2.setTrackbarPos('HMax','image',179) cv2.setTrackbarPos('SMax','image',255) cv2.setTrackbarPos('VMax','image',255) #初始化設置 hMin=sMin=vMin=hMax=sMax=vMax=0 phMin=psMin=pvMin=phMax=psMax=pvMax=0 while(1): #實時獲取拖動條上的值 hMin=cv2.getTrackbarPos('HMin','image') sMin=cv2.getTrackbarPos('SMin','image') vMin=cv2.getTrackbarPos('VMin','image') hMax=cv2.getTrackbarPos('HMax','image') sMax=cv2.getTrackbarPos('SMax','image') vMax=cv2.getTrackbarPos('VMax','image') #設定HSV的最大和最小值 lower=np.array([hMin,sMin,vMin]) upper=np.array([hMax,sMax,vMax]) #BGR和HSV顏色空間轉化處理 hsv=cv2.cvtColor(image,cv2.COLOR_BGR2HSV) mask=cv2.inRange(hsv,lower,upper) result=cv2.bitwise_and(image,image,mask=mask) #拖動改變閾值的同時,實時輸出調整的信息 if((phMin!=hMin)|(psMin!=sMin)|(pvMin!=vMin)|(phMax!=hMax)|(psMax!=sMax)|(pvMax!=vMax)): print("(hMin=%d,sMin=%d,vMin=%d),(hMax=%d,sMax=%d,vMax=%d)"%(hMin,sMin,vMin,hMax,sMax,vMax)) phMin=hMin psMin=sMin pvMin=vMin phMax=hMax psMax=sMax pvMax=vMax #展示由色素帶閾值范圍處理過的結果圖片 cv2.imshow('image',result) ifcv2.waitKey(10)&0xFF==ord('q'): break cv2.destroyAllWindows() if__name__=='__main__': colorLooker(pic='1.png') 啟動后截圖如下所示:

借助界面中的拖動條可以很方便地進行調節(jié),看到實時處理后的結果圖片:

經過調節(jié)后最終的結果如下所示:

調整拖動條的同時,終端窗口輸出如下所示:

到這里,我們已經獲取到了所需要的各個維度的閾值數(shù)據(jù)了,就可以進行后面的處理了。 接下來我們基于上述閾值來進行區(qū)域挖掘計算,同樣使用上述的圖片,核心代碼實現(xiàn)如下所示:

img=Image.open('1.png') img=cv2.cvtColor(np.asarray(img),cv2.COLOR_RGB2BGR) frame=cv2.cvtColor(img,cv2.COLOR_BGR2HSV) blur=cv2.GaussianBlur(frame,(21,21),0) hsv=cv2.cvtColor(blur,cv2.COLOR_BGR2HSV) h,w,way=img.shape total=h*w print('h:',h,'w:',w,'area:',total) #設置閾值數(shù)據(jù) lower=[8,67,84] upper=[85,255,255] lower=np.array(lower,dtype="uint8") upper=np.array(upper,dtype="uint8") mask=cv2.inRange(hsv,lower,upper) output=cv2.bitwise_and(hsv,hsv,mask=mask) count=cv2.countNonZero(mask) print('count:',count) now_ratio=round(int(count)/total,3) print('now_ratio:',now_ratio)

之后為了得到實際的輪廓區(qū)域,我們可以使用cv2.findContours方法來實現(xiàn)目標對象的區(qū)域挖掘計算,核心代碼實現(xiàn)如下所示:gray=cv2.cvtColor(output,cv2.COLOR_BGR2GRAY) print('gray_shape:',gray.shape) ret,output=cv2.threshold(gray,127,255,cv2.THRESH_BINARY) ''' cv2.findContours:
在opencv中查找輪廓時,物體應該是白色而背景應該是黑色 contours,hierarchy=cv2.findContours(image,mode,method) image:輸入圖像 mode:輪廓的模式。cv2.RETR_EXTERNAL只檢測外輪廓;cv2.RETR_LIST檢測的輪廓不建立等級關系;cv2.RETR_CCOMP建立兩個等級的輪廓,上一層為外邊界,內層為內孔的邊界。如果內孔內還有連通物體,則這個物體的邊界也在頂層;cv2.RETR_TREE建立一個等級樹結構的輪廓。 method:輪廓的近似方法。cv2.CHAIN_APPROX_NOME存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1;cv2.CHAIN_APPROX_SIMPLE壓縮水平方向、垂直方向、對角線方向的元素,只保留該方向的終點坐標,例如一個矩形輪廓只需要4個點來保存輪廓信息;cv2.CHAIN_APPROX_TC89_L1,cv2.CV_CHAIN_APPROX_TC89_KCOS contours:返回的輪廓 hierarchy:每條輪廓對應的屬性 ''' contours,hierarchy=cv2.findContours(output,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) print('contours_num:',len(contours)) count_dict={} areas,lengths=0,0 foriinrange(len(contours)): one=contours[i] one_lk=one.tolist() iflen(one_lk)>=2: area=cv2.contourArea(one) length=cv2.arcLength(one,True) areas+=area lengths+=length left_list,right_list=[O[0][0]forOinone_lk],[O[0][1]forOinone_lk] minX,maxX,minY,maxY=min(left_list),max(left_list),min(right_list),max(right_list) A=abs(maxY-minY)*abs(maxX-minX) print('area:',area,'A:',A,'length:',length) count_dict[i]=[A,area,length,[minX,maxX,minY,maxY]] sorted_list=sorted(count_dict.items(),key=lambdae:e[1][0],reverse=True) print(sorted_list[:10]) result['value']=count_dict cv2.drawContours(img,contours,-1,(0,0,255),3)完成輪廓的挖掘計算后,我們借助于OpenCV實現(xiàn)可視化,結果如下所示:

可以看到:已經大體上實現(xiàn)了我們所要的功能,但是美中不足的是里面有很多小的矩形框,這個是我們外切矩形設計的問題,沒有考慮到過濾掉嵌套或者是包含的情況,所以這里就來處理一下:

ifsorted_list: filter_list=filterBox(sorted_list[:5]) forone_boxinfilter_list: print('one_box:',one_box) A,area,length,[minX,maxX,minY,maxY]=one_box cv2.rectangle(img,(minX,maxY),(maxX,minY),(0,255,0),3)此時的結果如下所示:

對應的計算結果輸出如下所示:

('h:',336L,'w:',500L,'area:',168000L) ('count:',126387) ('now_ratio:',0.752) ('output_shape:',(336L,500L,3L)) ('gray_shape:',(336L,500L)) ('contours_num:',64) ('area:',0.0,'A:',2,'length:',4.828427076339722) ('area:',0.0,'A:',0,'length:',4.0) ('area:',29.0,'A:',44,'length:',27.313708186149597) ('area:',42.5,'A:',72,'length:',34.72792184352875) ('area:',0.5,'A:',6,'length:',9.071067690849304) ('area:',0.0,'A:',10,'length:',11.656854152679443) ('area:',0.0,'A:',1,'length:',2.8284270763397217) ('area:',0.0,'A:',2,'length:',4.828427076339722) ('area:',1.5,'A:',2,'length:',5.414213538169861) ('area:',16.5,'A:',36,'length:',27.55634891986847) ('area:',5.0,'A:',36,'length:',37.79898953437805) ('area:',1.5,'A:',3,'length:',8.242640614509583) ('area:',0.0,'A:',0,'length:',2.0) ('area:',2.0,'A:',2,'length:',6.0) ('area:',360.0,'A:',1026,'length:',206.93607211112976) ('area:',44.0,'A:',143,'length:',59.94112479686737) ('area:',0.0,'A:',1,'length:',2.8284270763397217) ('area:',0.0,'A:',1,'length:',2.8284270763397217) ('area:',33.5,'A:',60,'length:',30.38477599620819) ('area:',76.5,'A:',228,'length:',63.35533845424652) ('area:',320.0,'A:',792,'length:',166.9949471950531) ('area:',16.0,'A:',35,'length:',21.313708305358887) ('area:',0.0,'A:',8,'length:',10.828427076339722) ('area:',21.0,'A:',78,'length:',37.79898953437805) ('area:',0.0,'A:',1,'length:',2.8284270763397217) ('area:',0.0,'A:',2,'length:',4.828427076339722) ('area:',0.0,'A:',2,'length:',4.828427076339722) ('area:',3.5,'A:',25,'length:',20.727921843528748) ('area:',1.5,'A:',12,'length:',13.071067690849304) ('area:',51.0,'A:',121,'length:',53.94112491607666) ('area:',0.0,'A:',1,'length:',2.8284270763397217) ('area:',32.5,'A:',50,'length:',27.899494767189026) ('area:',309.5,'A:',722,'length:',96.32590079307556) ('area:',34.0,'A:',42,'length:',22.485281229019165) ('area:',80970.5,'A:',132699,'length:',2718.5739262104034) [(63,[132699,80970.5,2718.5739262104034,[1,498,67,334]]),(24,[1026,360.0,206.93607211112976,[33,60,281,319]]),(39,[792,320.0,166.9949471950531,[61,94,252,276]]),(61,[722,309.5,96.32590079307556,[384,422,75,94]]),(34,[228,76.5,63.35533845424652,[1,13,267,286]]),(25,[143,44.0,59.94112479686737,[68,81,280,291]]),(55,[121,51.0,53.94112491607666,[189,200,219,230]]),(47,[78,21.0,37.79898953437805,[100,113,235,241]]),(4,[72,42.5,34.72792184352875,[209,221,328,334]]),(32,[60,33.5,30.38477599620819,[15,25,274,280]])] ('one_box:',[132699,80970.5,2718.5739262104034,[1,498,67,334]])為了更加直觀地對比分析,我們將上面計算各個步驟中的對象數(shù)據(jù)進行可視化,借助于matplotlib繪制在同一張圖上,結果如下所示:

左上角為原始圖片,右下角為最終處理得到的圖片,可以看到整個處理過程的變化。 到這里本文的內容就結束了,學習依舊在路上,歡迎交流,互相學習!

作者:沂水寒城,CSDN博客專家,個人研究方向:機器學習、深度學習、NLP、CV

Blog:http://yishuihancheng.blog.csdn.net

責任編輯:PSY

原文標題:垃圾分類的正確姿勢?用 OpenCV 人工智能圖像識別技術來進行

文章出處:【微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 圖像識別
    +關注

    關注

    9

    文章

    514

    瀏覽量

    38149
  • 檢測識別
    +關注

    關注

    0

    文章

    9

    瀏覽量

    7223
  • OpenCV
    +關注

    關注

    29

    文章

    622

    瀏覽量

    41089

原文標題:垃圾分類的正確姿勢?用 OpenCV 人工智能圖像識別技術來進行

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    圖像分割與目標檢測的區(qū)別是什么

    的區(qū)別。 定義 圖像分割是將圖像劃分為若干個區(qū)域或對象的過程,這些區(qū)域或對象具有相似的屬性,如顏色、紋理或形狀。圖像分割的目的是將
    的頭像 發(fā)表于 07-17 09:53 ?543次閱讀

    目標檢測圖像識別的區(qū)別在哪

    檢測(Object Detection)是指在圖像或視頻識別并定位感興趣的目標,通常包括目標
    的頭像 發(fā)表于 07-17 09:51 ?370次閱讀

    目標檢測識別技術有哪些

    視頻識別并定位感興趣的目標,通常包括目標的類別和位置信息。目標識別(Object Recognition)是指對
    的頭像 發(fā)表于 07-17 09:40 ?304次閱讀

    目標檢測識別技術的關系是什么

    任務是在圖像或視頻快速準確地定位出感興趣的目標,并給出目標的位置信息。目標檢測技術通常包括候選
    的頭像 發(fā)表于 07-17 09:38 ?276次閱讀

    目標檢測識別主要應用于哪些方面

    介紹目標檢測識別的應用領域,以及其在各個領域的具體應用情況。 安全監(jiān)控 安全監(jiān)控是目標檢測識別
    的頭像 發(fā)表于 07-17 09:34 ?448次閱讀

    圖像檢測圖像識別的原理、方法及應用場景

    目標物體的過程。它的目標是確定圖像是否存在特定的物體,并在圖像中找到這些物體的位置,通常以矩形框的形式表示。 1.2
    的頭像 發(fā)表于 07-16 11:19 ?1375次閱讀

    OpenCV圖像識別C++代碼

    的頭文件 在您的C++代碼,包含以下必要的頭文件: # include # include # include # include # include # include # include 讀取圖像
    的頭像 發(fā)表于 07-16 10:42 ?1087次閱讀

    opencv圖像識別有什么算法

    圖像識別算法: 邊緣檢測 :邊緣檢測圖像識別的基本步驟之一,用于識別
    的頭像 發(fā)表于 07-16 10:40 ?372次閱讀

    opencv的主要功能有哪些

    OpenCV提供了豐富的圖像處理功能,包括圖像的讀取、顯示、保存、轉換等。此外,OpenCV還支持圖像的濾波、邊緣
    的頭像 發(fā)表于 07-16 10:35 ?801次閱讀

    圖像檢測識別技術的關系

    檢測技術是指利用計算機視覺技術,對圖像的特定目標進行定位和識別的過程。它通常包括圖像預處理、特
    的頭像 發(fā)表于 07-03 14:43 ?343次閱讀

    圖像檢測圖像識別的區(qū)別是什么

    詳細的比較和分析。 定義和概念 圖像檢測(Image Detection)是指利用計算機視覺技術對圖像的特定目標進行定位和
    的頭像 發(fā)表于 07-03 14:41 ?481次閱讀

    OpenCV4.8 C++實現(xiàn)YOLOv8 OBB旋轉對象檢測

    YOLOv8框架在在支持分類、對象檢測、實例分割、姿態(tài)評估的基礎上更近一步,現(xiàn)已經支持旋轉對象檢測(OBB),基于DOTA數(shù)據(jù)集,支持航拍圖像
    的頭像 發(fā)表于 02-22 10:15 ?1174次閱讀
    <b class='flag-5'>OpenCV</b>4.8 C++<b class='flag-5'>實現(xiàn)</b>YOLOv8 OBB旋轉<b class='flag-5'>對象</b><b class='flag-5'>檢測</b>

    圖像識別技術原理 圖像識別技術的應用領域

    圖像識別技術是一種通過計算機對圖像進行分析和理解的技術。它借助計算機視覺、模式識別、人工智能等相關技術,通過對圖像進行特征提取和匹配,找出圖像
    的頭像 發(fā)表于 02-02 11:01 ?1778次閱讀

    openCV邊緣檢測原理是什么?

    openCV是通過什么原理實現(xiàn)邊緣檢測
    發(fā)表于 10-10 06:21

    【幸狐 Core3566 模組試用體驗】基于openCV的貓臉識別

    OpenCV,目標檢測使用的函數(shù)是cv2.CascadeClassifier.detectMultiScale(),它可以檢測
    發(fā)表于 09-24 23:50